Domain Join : ARM Extension versus Azure Automation DSC


So you’ve already deployed Windows based systems in Azure. Very good! You’ve probably joined those systems into a domain, as you’ve always done this by going through the GUI. Did you know you can join a machine without logging into the machine? No? Then today’s post will be very interesting for you!

If you knew this was possible, then I’ll show you that there are various methods of doing so. And that each approach will have clear advantages and even disadvantages. So let’s get ready to domainjoin those systems!


ARM Extension
When working with Azure Resource Manager (ARM), you have the option to leverage the “ADDomainExtension” in order to get your VM to join the domain. There are various options to do so, where Igor has made a nice blog post in the beginning of the year to outline these.

In a recent endeavor, I used the following code for this ;

Function Initialize-DomainJoin ($domainJoinResourceGroup, $domainJoinpLocation, $domainJoinVmName, $domainJoinDomainName, $domainJoinAdminName $domainAdminPassKey)
Write-Information -MessageData "[XYLOS] Joining $domainJoinVmName to domain $domainJoinDomainName"
$domainJoinPassword = Get-AzureKeyvault-Secret $keyVault $domainAdminPassKey
Set-AzureRMVMExtension `
-VMName $domainJoinVmName `
–ResourceGroupName $domainJoinResourceGroup `
-Location $domainJoinpLocation `
-Name "JoinAD" `
-ExtensionType "JsonADDomainExtension" `
-Publisher "Microsoft.Compute" `
-TypeHandlerVersion "1.3" `
-Settings @{ "Name" = $domainJoinDomainName; "OUPath" = ""; "User" = $domainJoinAdminName; "Restart" = "true"; "Options" = 3} `
-ProtectedSettings @{"Password" = $domainJoinPassword} `
-ErrorAction SilentlyContinue

When doing this approach, what did I notice? It mostly just does what it needs to do. Though once an abnormal event surfaces, then it’s harder to debug. I noticed that the timeout for errors was about 90 minutes, so that made my automated deployments take a huge time. In addition, finding the error message for debug purposes is sometimes also vague…


Azure Automation & Desired State Configuration

Another approach to getting a VM into a domain is to leverage (Desired State Configuration) DSC via Azure Automation. This is a tad more complex, though it adds the value that a configuration (like a domain join) can be enforced (or reported on compliancy).

A sample configuration ;

Configuration XylosAdfsDscConfFederationServices
	Import-DscResource -ModuleName 'PSDesiredStateConfiguration'
    Import-DscResource -ModuleName 'xDSCDomainjoin'
    $dscDomainAdmin = Get-AutomationPSCredential -Name 'dscDomainAdmin'
	$dscDomainName = Get-AutomationVariable -Name 'dscDomainName'

    node $AllNodes.NodeName
        xDSCDomainjoin JoinDomain
            Domain = $dscDomainName 
            Credential = $dscDomainAdmin

and it’s companion config data ;

$ConfigData = @{
    AllNodes = @(
            NodeName = "Cattle"
            PSDscAllowPlainTextPassword = $True
			PSDscAllowDomainUser = $True

Important to note here is that I used the “xDSCDomainjoin” resource and not the most commonly used one, being xComputerManagement. Why did I go for this one? Because the xComputerManagement expects you to provide the computer name. This is quite hard to integrate with Azure Automation, as the configuration file is compiled on a separate / build system. So the config file will be rendered quite “generic” so that reuse is possible. On the other had, the xDSCDomainJoin doesn’t expect this parameter and thus perfect for the job!

Now what does that look like in Azure Automation?


Cool huh! 😉


When to choose which?

Now for the one million dollar question… When to choose which?

  • Extension : If you want it quick & dirty, where you know/expect/allow that the system configuration can deviate from your intended deployment.
  • DSC : If you want to have control over the configuration. You can set DSC to enforce or report back on the applied configuration. In addition, if you want to automate a great bunch of servers, please allow yourself a break and go for DSC!



  • There are various options on joining a server into a domain when using ARM.
  • Use the xDSCDomainJoin resource when going for Azure Automation. This is due to the fact that this resource does not require providing a computer name.


As a closing note

If you aren’t aware of it by now, know that DSC is the thing you need on your swiss army knife as a system engineer involved with windows based systems. If you haven’t already, read up on it and learn to master it. Once you’ll see the power it brings to the table, you’ll wonder how you ever managed without it!

3 thoughts on “Domain Join : ARM Extension versus Azure Automation DSC

  1. Great article!

    Do you know of a way to domain-join with DSC without Azure Automation?

    1. Azure automation is pull based. You can also do a push based. Which is what the extension does.

      Or use your own pull server…

  2. Great article.
    We got stuck at one point, could you please help us?
    We are having Azure based AD environment where we would make use of Azure end point manager to push the .msi files. We are running on cloud , so we can not use Group policy management console.
    Can you please give solution to do mass deployment for the above environment.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.