Learn What IT Pros Need to Know About Windows 11 - August 24th at 1 PM ET! Learn What IT Pros Need to Know About Windows 11 - August 24th at 1 PM ET!
Microsoft Azure

Deploy an Azure VM to an Existing Domain using an ARM Template


In today’s Ask the Admin, I’ll show you how to deploy a Windows Server 2012 R2 VM in Azure and join it to an existing Active Directory (AD) domain.

This tutorial uses Azure Resource Manager (ARM) to deploy a virtual machine and join it to a domain. If you need a primer on ARM and how to work with templates, or want to deploy a new AD domain in Azure, take a look at “Provision a domain using a Microsoft Azure Resource Manager template” on the Petri IT Knowledgebase.

Get the template URI

As in the previous article, I’m going to use a readymade template, 201-vm-domain-join, from the quick-start gallery on GitHub. First we need to get the template URI:

Sponsored Content

Read the Best Personal and Business Tech without Ads

Staying updated on what is happening in the technology sector is important to your career and your personal life but ads can make reading news, distracting. With Thurrott Premium, you can enjoy the best coverage in tech without the annoying ads.

  • Open the 201-vm-domain-join template in a browser.
  • Click azuredeploy.json in the list of files.
  • Click Raw above the template code on the right.
Azure JSON ARM template (Image Credit: Russell Smith)
Azure JSON ARM template (Image Credit: Russell Smith)
  • Once the browser is displaying the raw template code, copy the URL from the browser address bar. This is the URI for the template required by the New-AzureRmResourceGroupDeployment cmdlet.

Deploy a VM using an ARM template

Before you can start working with the PowerShell ARM cmdlets, you’ll need to make sure that you’ve got Microsoft Azure PowerShell 1.0 or later installed on your system. For more information, see “Install Azure PowerShell 1.0 Preview” on Petri.

  • Open Windows PowerShell ISE.

The 201-vm-domain-join template creates a new VM in the same Resource Group (RG) as the domain controllers. Some additional variables are also required, including the name of the virtual network (VNET), subnet, AD domain administrator username and password, and a local administrator username and password for the new VM. To keep it simple, I’ll specify the same VNET and subnet that host my domain controller in Azure.

Template parameters in the Azure Resource Manager Template Visualizer (Image Credit: Russell Smith)
Template parameters in the Azure Resource Manager Template Visualizer (Image Credit: Russell Smith)

The code below logs in to Azure ARM and selects the first available subscription associated with the given Microsoft Account. The account credentials must be entered manually when prompted. The Resource Group name is then set ($rgName), and Azure region ($location). I’ve included some error checking to throw an error if the RG doesn’t exist and if the DNS name specified for the new VM is already in use.


$subs = Get-AzureRmSubscription 
Select-AzureRmSubscription -TenantId $subs[0].TenantId -SubscriptionId $subs[0].SubscriptionId

$rgName ='contosodcs'
$location = 'North Europe'
$domainPassword = 'passW0rd!'
$vmPassword = 'passW0rd!'
$vmName = 'srv1'

# Check availability of DNS name

If ((Test-AzureRmDnsAvailability -DomainQualifiedName $vmName -Location $location) -eq $false) {
        Write-Host 'The DNS label prefix for the VM is already in use' -foregroundcolor yellow -backgroundcolor red
        throw 'An error occurred'

# Create New Resource Group
# Checks to see if RG exists
# -ErrorAction Stop added to Get-AzureRmResourceGroup cmdlet to treat errors as terminating

try {
    Get-AzureRmResourceGroup -Name $rgName -Location $location -ErrorAction Stop
} catch {
    Write-Host "Resource Group doesn't exist" -foregroundcolor yellow -backgroundcolor red
    throw 'An error occurred'

Once the prerequisites have been met, all that’s left to do is assign values to the rest of the variables required by the template. To determine the parameters required, open the template in a browser using the link in the steps above, click Visualize to open the Azure Resource Manager Template Visualizer, and then click Edit Parameter Definitions in the menu on the left. In the Parameter Editor, you’ll see a list of parameters and their default values.

In the code below, I’ve defined the parameters in a hash table, and then splat them to the New-AzureRmResourceGroupDeployment cmdlet, which deploys the resources defined in the template to the specified Resource Group. Values for some of the parameters, such as existingVNETName and existingSubnetName, are taken from the existing domain deployment.

$newVMParams = @{
    'ResourceGroupName' = $rgName
    'TemplateURI' = 'https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/201-vm-domain-join/azuredeploy.json'
    'existingVNETName' = 'adVNET'
    'existingSubnetName' = 'adSubnet'
    'dnsLabelPrefix' = $vmName
    'vmSize' = 'Standard_A2'
    'domainToJoin' = 'ad.contoso.com'
    'domainUsername' = 'adadmin'
    'domainPassword' = convertto-securestring $domainPassword -asplaintext -force
    'ouPath' = ''
    'domainJoinOptions' = 3
    'vmAdminUsername' = 'azureuser'
    'vmAdminPassword' = convertto-securestring $vmPassword -asplaintext -force
New-AzureRmResourceGroupDeployment @newVMParams

The New-AzureRmResourceGroupDeployment can take a long time to deploy the resources defined in the template, so while it may appear to have hanged, if there’s a problem with the deployment, you’ll receive an error message fairly quickly. No output usually indicates the deployment is running successfully. You can check to see if the VM is being deploying by checking its status in the Azure management portal.

The New-AzureRmResourceGroupDeployment PowerShell cmdlet output (Image Credit: Russell Smith)
The New-AzureRmResourceGroupDeployment PowerShell cmdlet output (Image Credit: Russell Smith)

For convenience once the deployment is complete, I output the URL to connect to the VM via Remote Desktop.

# Display the RDP connection string

$rdpVM = Get-AzureRmVM -ResourceGroupName $rgName -Name $vmName

$rdpString = $vmName + '.' + $rdpVM.Location + '.cloudapp.azure.com'
Write-Host 'Connect to the VM using the URL below:' -foregroundcolor yellow -backgroundcolor red 
Write-Host $rdpString

In this Ask the Admin, I showed you how to deploy a VM and join in to an existing Active Directory domain running in Azure, using an ARM template from the quick-start gallery.


Related Topics:


Don't have a login but want to join the conversation? Sign up for a Petri Account

Comments (0)

Leave a Reply

IT consultant, Contributing Editor @PetriFeed, and trainer @Pluralsight. All about Microsoft, Office 365, Azure, and Windows Server.

Register for Advanced Microsoft 365 Day!

GET-IT: Advanced Microsoft 365 1-Day Virtual Conference - Live August 24th!

Join us on Tuesday, August 24th and hear from Microsoft MVPs and industry experts about how to take advantage of Microsoft 365 at a technical level and dive deep into the features and functionality that will make your environment more secure and compliant.


Sponsored By