Azure ARM: VM Domain Join to Active Directory Domain with "JoinDomain" Extension
It is a pretty common scenario to provision a Virtual Machine (VM) in Azure and join it to an existing Active Directory (AD) Domain, either extended from on-premises via hybrid connections, or natively deployed in the cloud installing Domain Controllers (DCs) into Azure VMs. Using legacy Azure Service Management API (ASM), a nice PowerShell cmdlet called “Add-AzureProvisioningConfig” is available, with “ -JoinDomain” switch to automatically join the VM to an AD domain as in example below:
Add-AzureProvisioningConfig
https://msdn.microsoft.com/en-us/library/azure/dn495299.aspx
Unfortunately, there is no more evidence of domain join functionality in the newest Azure Resource Manager (ARM) API, then how to gain back that nice feature previously available in Azure ASM? There are essentially two ways, both based on a new type of ARM “Extension” called “JsonADDomainExtension”:
- Using Azure ARM Templates (“declarative mode”).
- Using Azure ARM PowerShell Cmdlet (“imperative mode”).
The first approach is very simple; you can find a template sample for automatic VM joining to an AD domain at the link below in GitHub:
201-vm-domain-join
https://github.com/Azure/azure-quickstart-templates/blob/master/201-vm-domain-join/azuredeploy.json
As you can see, this new extension type can take all the necessary parameters to join a VM to an existing AD domain, and then finally reboot the VM once the join operation is complete. If you try to search using Bing about this extension, you will not find (at least at the time of writing this post) any public reference nor documentation. Now, what happen if you don’t or want to use an ARM template and instead you have/want to use “imperative” PowerShell? What I have done below is reverse-engineering the template mentioned above and test a very simple script. First of all, you need to prepare two JSON strings as in the example below:
The first one contains all the necessary parameters/options for the domain join operation, please note that there is no documentation on the possible values for “Options”, value (3) is recommended in the GitHub template mentioned above. The second one contains protected info that the extension mechanism will encrypt transparently to guarantee security of passwords. After that, simply execute the PowerShell cmdlet below:
Execution of “Set-AzureRmVMExtension” cmdlet will require some time; you can check the status using the “Get-AzureRmVMExtension” cmdlet as in the example below (output sample included):
From the Azure Portal, you can see almost the same level of details going into the “Extension” tab of your Virtual Machine:
That’s all I wanted to share with you, hope you will find this content useful and interesting, feel free to post your comments and feedbacks here. Remember that you can also follow me on Twitter ( @igorpag). Best Regards.
Comments
Anonymous
January 24, 2016
Awesome! thank youAnonymous
January 28, 2016
Very Useful. Thanks.Anonymous
February 07, 2016
Hi, thank you for your excellent description of this subject. I am having trouble joining using the ARM template on certain VHD files I have made. Some work, some don't. Is there a setting on the image that needs to be set right for this to work?Anonymous
February 07, 2016
The comment has been removedAnonymous
March 22, 2016
Worked like a charm. I ran the VM extensions after I created the VM, where Add-AzureProvisioningConfig is run prior to creating the VM.Anonymous
June 27, 2016
Hi,We are deployig VMs using JSON which is working fine. In the existing JSON, I have added the extension to add the VM to the Domain, while deploying the VM, I am getting an error for adding it to the Domain, it say not getting the "'The template variable 'apiVersion' is not found". Please suggest.Anonymous
September 06, 2016
Hi Igor,Nice article, thanks. Although when I try to use 201 domain join template, it fails with a joindomain extension conflict error, have you run into this issue at all.?- Anonymous
September 07, 2016
Conflict error on using the ARM template? Sorry no, never heard about that.Regards.
- Anonymous
Anonymous
September 14, 2016
I am getting below error using Github template code { "apiVersion": "2015-06-15", "type": "Microsoft.Compute/virtualMachines/extensions", "name": "[concat(parameters('vmName'),'/joindomain')]", "location": "[resourceGroup().location]", "dependsOn": [ "[concat('Microsoft.Compute/virtualMachines/', parameters('vmName'))]" ], "properties": { "publisher": "Microsoft.Compute", "type": "JsonADDomainExtension", "typeHandlerVersion": "1.3", "autoUpgradeMinorVersion": true, "settings": { "Name": "[parameters('domainToJoin')]", "OUPath": "[parameters('ouPath')]", "User": "[concat(parameters('domainToJoin'), '', parameters('domainUsername'))]", "Restart": "true", "Options": "[parameters('domainJoinOptions')]" }, "protectedsettings": { "Password": "[parameters('domainPassword')]"New-AzureRmResourceGroupDeployment : 11:20:11 AM - Handler 'Microsoft.Compute.JsonADDomainExtension' has reported failure for VM Extension 'joindomain' with terminal error code '1009' and error message: 'Enable failed 11:20:11 - [ERROR] for plugin (name: Microsoft.Compute.JsonADDomainExtension, version 1.3) with exception Command C:\Packages\Plugins\Microsoft.Compute.JsonADDomainExtension\1.3\enable.cmd of Microsoft.Compute.JsonADDomainExtension has 11:20:11 - [ERROR] not exited on time! Killing it...'- Anonymous
December 21, 2016
Hello I just found the reason for my error on the ARM template deployment, You may want to look your specific case under: %windir%\debug\netsetup.logIn my case it was failing because of incorrect referenced username in the template.wrong definittion on the template I had:"User": "parameters('domainUsername'))"It has missing the enclosing [ ], and the log says:12/20/2016 22:45:20:804 HostName: testVM12/20/2016 22:45:20:804 NetbiosName: testVM12/20/2016 22:45:20:804 Domain: example.com12/20/2016 22:45:20:804 MachineAccountOU: OU=Servers,DC=example,DC=com12/20/2016 22:45:20:804 Account: parameters('domainUsername')) ******** notice the parameter was not passed correctly12/20/2016 22:45:20:804 Options: 0x3 Regards
- Anonymous
Anonymous
September 16, 2016
Sorry for this question as it is a reflection on my lack of powershell knowledge and not a problem with your script. I actually used it perfectly and LOVE it! I want to add it to my own script and am trying to use variables for the domain join info. for example: rather than having the domain name hard coded in, I have if statements to determine the domain to use. here is an example:IF ($SubName -eq "ProdSubcription") {$DomainName = 'Companyname.com' }IF ($DomainName -eq "Companyname.com") { $DomainUser = 'Administrator' }So then i want to have the script you wrote look like this:$String1 "Name": "$DomainName" "User" : "DomainUser"Problem is when it runs it doesn't see the variable, rather thinks the domain is called $DomainName.... any ideas?- Anonymous
December 09, 2016
@Mike Bergin, If you're replacing information in the script example in this post, you need to change the quotes from single to double. So it would start $string1 = "{ ... Single quotes are literal strings, double quotes allow for variable replacement. HTH
- Anonymous
Anonymous
November 15, 2016
Hey Igor,Great script. It works.Anonymous
December 23, 2016
It works , but getting this error "Handler 'Microsoft.Compute.JsonADDomainExtension' has reported failure for VM Extension 'joindomain' with terminal error code '1009' and error message: 'Enable failed for pluginmpute.JsonADDomainExtension' has reported failure for VM Extension 'joindomain' with terminal error code '1009' and error message: 'Enable failed for plugin (name: Microsoft.Compute.JsonADDomainExtension, version 1.3) with exception Command C:\Packages\Plugins\Microsoft.Compute.JsonADDomainExtension\1.3\enable.cmd of Microsoft.Compute.JsonADDomainExtension has not exited on time! Killing it...'"is there any settings for timeout ?- Anonymous
April 13, 2017
Dyanesh December 23, 2016 at 5:56 pm It works , but getting this error“Handler ‘Microsoft.Compute.JsonADDomainExtension’ has reported failure for VM Extension ‘joindomain’ with terminal error code ‘1009’ and error message: ‘Enable failed for pluginmpute.JsonADDomainExtension’ has reported failure for VM Extension ‘joindomain’ with terminal error code ‘1009’ and error message: ‘Enable failed for plugin (name: Microsoft.Compute.JsonADDomainExtension, version 1.3) with exception Command C:\Packages\Plugins\Microsoft.Compute.JsonADDomainExtension\1.3\enable.cmd of Microsoft.Compute.JsonADDomainExtension has not exited on time! Killing it…'”is there any settings for timeout ? - Anonymous
April 13, 2017
Hi,with terminal error code ‘1009’ and error message: ‘Enable failed for plugin (name: Microsoft.Compute.JsonADDomainExtension, version 1.3) with exception Command C:\Packages\Plugins\Microsoft.Compute.JsonADDomainExtension\1.3\enable.cmd of Microsoft.Compute.JsonADDomainExtension has not exited on time! Killing it…regards:durga
- Anonymous
Anonymous
February 22, 2017
I have to ask. Does this now support joining Azure Active Directory?Anonymous
April 13, 2017
Great option But when using this with managed disk as an image VM's I got the following error. If I use a storage account it worked.New-AzureRmVM : Long running operation failed with status 'Failed'.ErrorCode: PropertyChangeNotAllowedErrorMessage: Changing property 'sourceUri' is not allowed.Anonymous
August 22, 2017
Siga as instruções e veja dinheiro entrar!