4 Ways to Configure Azure VMs using PowerShell

In today’s Ask the Admin, I’m going to take another look at the sometimes perplexing world of Microsoft technologies, and specifically the different ways of automating virtual machine (VM) configuration using PowerShell. I’ll outline four different configuration methods, all relying on the Microsoft Azure PowerShell cmdlets for the initial VM deployment, and then different ways of executing PowerShell code once the VM has been provisioned.

Azure DSC Extension

Desired State Configuration allows system administrators to manage server configuration via declarative files that determine which components should be installed and how they must be set up. Although the number of DSC resources available in Windows Server 2012 R2 are limited, more are available in the DSC Resource Kit, and you can write your own, too. For more information on PowerShell Desired State Configuration, see the first part of a seven-part series Deploying a Desired State Configuration Web Host Using PowerShell on the Petri IT Knowledgebase.

Microsoft released a VM extension for PowerShell Desired State Configuration (DSC) last year and has been improving it since then. The Azure DSC Extension allows administrators to pass DSC configuration files to VMs during initial deployment, without the need to install a VM in the cloud running a DSC pull or push server. The extension also supports passing custom DSC resources to VMs as zip files, along with your configuration files.

The Azure DSC Extension is a great idea in principle, but has several drawbacks. Like any other Azure extension, VMs must reboot at least once before the extension is installed, and while this happens automatically, it adds extra time to the deployment process. At some point you’ll likely want to pass secure credentials to the VM, for example when promoting a server to a domain controller. The Azure DSC Extension supports PSCredential, but often fails to pass the credentials.

And that leads me nicely to the third issue: troubleshooting is difficult because the information in the logs is limited and somewhat cryptic, so when something goes wrong, you can end up spending hours trying to resolve the issues.

DSC Cloud Pull Server

While more complicated to set up, a VM in the cloud running a DSC pull server overcomes the problems presented by the Azure DSC Extension, but requires that a VM be left running 24/7, which in turn incurs a cost. For more information on configuring a DSC pull server, see Deploying a Desired State Configuration Web Host Using PowerShell on the Petri IT Knowledgebase.

PowerShell Remoting

I use PowerShell Remoting to deploy and configure Azure VMs because it’s fast, doesn’t require any infrastructure, and the learning curve is minimal. It does, however, need a certificate to be installed on the device where the script is executed, but downloading and installing the certificate for each VM can be automated. PowerShell Remoting also requires that a connection be maintained to the VM while the script executes. You can find a good example of using PowerShell Remoting to configure Azure VMs described in Automate Domain Controller Deployment in Microsoft Azure on Petri.

PowerShell using Custom Script Extension

The Azure Custom Script Extension allows administrators to run PowerShell scripts on VMs immediately after deployment, and scripts can be stored either on an on premise device, or in Azure cloud storage. The key advantage of using the Custom Script Extension over PowerShell Remoting is that the script is passed to the VM and executed locally, and doesn’t rely on a connection being maintained between the machine where the script is launched, and the remote VM. For more information on using the Custom Script Extension, see Aidan Finn’s article Easier Azure VM Deployment with the Custom Script Extension on Petri.