- Create a certificate-signed RDP shortcut via Group Policy - Fri, Aug 9 2019
- Monitor web server uptime with a PowerShell script - Tue, Aug 6 2019
- How to build a PowerShell inventory script for Windows Servers - Fri, Aug 2 2019
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.
Prerequisites
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