Automate Domain Controller Deployment in Microsoft Azure

Back in summer 2014, I walked you through writing a PowerShell script to deploy domain controllers in Microsoft Azure. In today’s Ask the Admin, I want to revisit the script to address issues including:

  • Problems connecting to the virtual machine (VM) using PowerShell Remoting due to differences in the name of the WinRM endpoint across Azure regions
  • Removing the need to run the script with local administrator privileges
  • Adding the ability to specify a Server Core installation and downgrade the size of the VM accordingly
  • Replacing hardcoded values with defined variables
  • Improving script readability with better formatting

About the Script

Although this version of the script is significantly improved over the original, it’s still a work in progress, and there is undoubtedly room for further optimization. Please take a look at Provision Domain Controllers in Azure using PowerShell on the Petri IT Knowledgebase to get an understanding of how the script works and the prerequisites.

Automating DC deployment in Azure using PowerShell (Image Credit: Russell Smith)
Automating DC deployment in Azure using PowerShell (Image Credit: Russell Smith)

The script uses PowerShell Remoting to connect to the Azure VM so that it can install the Active Directory Domain Services (AD DS) bits, initialize and format the NTDS volume, promote the server to a domain controller, and remove GUI features if a Server Core installation is specified.

The ultimate goal of this script is to replace PowerShell Remoting with Desired State Configuration (DSC), because DSC doesn’t require a connection to be maintained with the remote VM during configuration. The script also works to provide a solution for maintaining the server’s configuration after initial installation. Due to the extra complexity of setting up DSC and the experimental nature of DSC resources available from Microsoft, along with the fact that xAdDomain and xAdDomainController resources have only recently been able to set the AD DatabasePath, LogPath, and SysvolPath values, I’ve decided to stick with PowerShell Remoting for the time being.

New Variables

The custom variables section of the script now contains extra variables to remove hardcoded values, including $domainName, $admin, $siteName, $vmSize, and $osName, all of which should be self-explanatory. I’ve also added $serverCore, which should be set to $true or $false, so that the GUI features can be removed from the default Azure Windows Server image and the VM downgraded to Extra Small at the end of deployment.

PowerShell Remoting Certificate

One frustration with the old script is that if you forget to run it with elevated privileges, then the script fails when trying to add the certificate for PowerShell Remoting to the Local Machine certificate store. Therefore I decided to change the code to use the current user’s certificate store instead:

Certificate warning dialog (Image Credit: Russell Smith)
Certificate warning dialog (Image Credit: Russell Smith)

This isn’t ideal, as Windows prompts you to confirm that it’s okay to add a certificate to the Trusted Root Certification Authorities container, but it’s better than the script throwing an error.

Get the URI for PowerShell Remoting

The previous script enumerated the WinRM port for PowerShell Remoting using the name of the endpoint, which unfortunately isn’t consistent across Azure regions, sometimes causing the script to fail. I recently discovered the Get-AzureWinRMUri cmdlet, which solves this problem by using the cloud service and VM names instead. The –UseSSL parameter has also been removed from the New-PSSession cmdlet, as the $uri string specifies HTTPS.

Configure Server Core and Extra Small VM Size

I’ve added simple IF statement to remove GUI features from the installation and downgrade to an Extra Small (Basic_A0) VM. Using Server Core in an extra small VM can help keep costs down.

Disconnect from the Remote Session

And finally a minor detail, code to disconnect from the remote PowerShell session has been added:

The Complete Script

As always, you should modify the variables appropriately to suit your own requirements and environment. The script could also be modified to install member servers or meet any other needs you might have.

Related Topics:

  • Active Directory

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

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