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

Maximize Value from Microsoft Defender

In this ebook, you’ll learn why Red Canary’s platform and expertise bring you the highest possible value from your Microsoft Defender for Endpoint investment, deployment, or migration.

  • 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' = ''
    'existingVNETName' = 'adVNET'
    'existingSubnetName' = 'adSubnet'
    'dnsLabelPrefix' = $vmName
    'vmSize' = 'Standard_A2'
    'domainToJoin' = ''
    '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 + ''
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.
External Sharing and Guest User Access in Microsoft 365 and Teams

This eBook will dive into policy considerations you need to make when creating and managing guest user access to your Teams network, as well as the different layers of guest access and the common challenges that accompany a more complicated Microsoft 365 infrastructure.

You will learn:

  • Who should be allowed to be invited as a guest?
  • What type of guests should be able to access files in SharePoint and OneDrive?
  • How should guests be offboarded?
  • How should you determine who has access to sensitive information in your environment?

Sponsored by:

Live Webinar: Active Directory Security: What Needs Immediate Priority!Live on Tuesday, October 12th at 1 PM ET

Attacks on Active Directory are at an all-time high. Companies that are not taking heed are being punished, both monetarily and with loss of production.

In this webinar, you will learn:

  • How to prioritize vulnerability management
  • What attackers are leveraging to breach organizations
  • Where Active Directory security needs immediate attention
  • Overall strategy to secure your environment and keep it secured

Sponsored by: