In this article, I will explain how to send an PowerShell DSC configuration up to Azure, how start the DSC compilation job and apply the configuration to an Azure virtual machine. Azure Automation DSC gives an admin the tooling to properly manage DSC. However, working with Azure Automation DSC is a little different than managing and applying DSC configurations on-premises.

Desired State Configuration (DSC) is a useful component of PowerShell that allows system administrators, developers and anyone needing to quickly provision and configure infrastructure with code. Although only just introduced with PowerShell v4, DSC has already started catching on with forward-thinking companies looking for a better way to manage their environments.

However, one fact that those in the DSC space is that Microsoft never built great tooling around it. Microsoft has stated many times that DSC is a platform for other tools to leverage. It is not a tool itself but they did offer an option with Azure Automation DSC.


To get started, you'll first need an Azure virtual machine already onboarded. You will also need the Azure Automation DSC PowerShell cmdlets available in the AzureRm PowerShell module. Those cmdlets can be installed by running Install-Module -Name AzurRm. Once you have the module installed, the virtual machine created and onboarded with DSC; you're now able to write DSC configurations locally and push them up to Azure Automation DSC with PowerShell.

Getting started

The first task with any Azure task using PowerShell is to authenticate to your subscription. The easiest way to do this is to use the Add-AzureRmAccount command. Once authenticated, we'll then ensure our Azure virtual machine is started. Notice below that my VM's name is LABDC and the resource group it's located in is simply Group.

$null = Get-AzureRmVM -Name LABDC -ResourceGroupName Group | Start-AzureRmVM

Sending the DSC configuration to Azure

Next, we'll need to send the DSC configuration we'd like to apply to the VM up to Azure Automation DSC. We can do this using the Import-AzureRmAutomationDscConfiguration command. Below I'm using the Azure Automation account I have previously created, specifying the path to the DSC configuration script and also publishing the script to the node that I have built the configuration for.

$params = @{
    AutomationAccountName = 'adamautomation'
    ResourceGroupName = 'Group'
    SourcePath = 'C:\NewTestEnvironment.ps1'
    Published = $true
    Force = $true

$null = Import-AzureRmAutomationDscConfiguration

Starting the DSC compilation job

Once the DSC configuration is on the Azure Automation DSC pull server, I then need to build an MOF file for our node. This is done in the background using the Start-AzureRmAutomationDscCompilationJob command.

$compParams = @{
    AutomationAccountName = 'adamautomation'
    ResourceGroupName = 'Group'
    ConfigurationName = 'NewTestEnvironment'
$CompilationJob = Start-AzureRmAutomationDscCompilationJob @compParams

## Wait for the DSC compile
while($CompilationJob.EndTime -eq $null -and $CompilationJob.Exception -eq $null)
    $CompilationJob = $CompilationJob | Get-AzureRmAutomationDscCompilationJob
    Start-Sleep -Seconds 3

Notice that I have another step in this process below the compilation job above. Because the compilation job takes a little bit and the Start-AzureRmAutomationDscCompilationJob immediately returns to the console even if not finished, I've chosen to incorporate my own Wait functionality by checking the compilation job's status every three seconds until finished. By doing this, I can ensure that no further action is taken until the compilation job is complete.

Assigning the DSC Configuration to the node

Once the MOF has been created on the pull server, we now need to assign the DSC configuration to the node. We do this using the Set-AzureRmAutomationDscNode command. This sets up the link between our Azure virtual machine and the DSC configuration we'd like to apply to it.

$nodeId = (Get-AzureRmAutomationDscNode -AutomationAccountName 'adamautomation' -ResourceGroupName 'Group' -Name $azrVmName).Id
$nodeParams = @{
    NodeConfigurationName = "NewTestEnvironment.TESTLABDC"
    ResourceGroupName = 'Group'
    Id = $nodeId
    AutomationAccountName = 'adamautomation'
    Force = $true
$node = Set-AzureRmAutomationDscNode @nodeParams

Invoking the new DSC Configuration

At this point, we could wait until the Azure VM pulls the new DSC configuration itself but I'm impatient so let's go ahead and force it to pull the new configuration right away. Because the VM is public, I'll need to get the public IP address to connect via PowerShell remoting. Since it's also in a workgroup, I have to configure my local system to trust the VM's public IP address. Once this is done, I can connect via PowerShell remoting and update the DSC configuration.

Subscribe to 4sysops newsletter!

## Find the public IP of the VM
$vm = Get-AzureRmVm -Name 'TESTLABDC' -ResourceGroupName 'Group'
$ipAddress = (Get-AzureRmPublicIpAddress -ResourceGroupName 'Group' -Name "TESTLABDC-ip").IpAddress

## Since the VM isn't in the same domain, need to trust it to connect via PS Remoting
Set-Item -Path wsman:\localhost\Client\TrustedHosts -Value $ipAddress -Force

## Create the credential with the local administrator username and password of the VM
$adminUsername = $vm.osProfile.AdminUsername
$adminPwd = ConvertTo-SecureString 'localadminpasswordhere' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ($adminUsername, $adminPwd)

## Force the DSC update to run with Update-DscConfiguration
Invoke-Command -ComputerName $ipAddress -ScriptBlock { Update-DscConfiguration -Wait -Verbose } -Credential $cred
Invoking DSC Configuration

Invoking DSC Configuration


Leave a reply

Your email address will not be published. Required fields are marked *


© 4sysops 2006 - 2023


Please ask IT administration questions in the forums. Any other messages are welcome.


Log in with your credentials


Forgot your details?

Create Account