This article is contributed. See the original author and article here.

I did a post a while ago on installing software onto virtual machines using policy state change events as the trigger. Now with the general availability of Azure Automanage Machine Configuration (formerly Azure Policy Guest Configuration) it’s time for a bit of an update to that post. In this guide I’ll again be installing PowerShell 7 – however I’ll use Machine Configuration and Azure Policy to handle the installation. Let’s get started….


Development Environment

To make sure I have all the tools to complete this process I need to install some pre-requisite software. This is so I can generate the package which the virtual machine will download to tell it how to install the software.

On my local machine I have installed:

  • PowerShell 7.3.0

  • The GuestConfiguration module – version 4.2.0

  • The PSDscResources module – version

  • An Azure Storage Account with a container which will host my configuration. The virtual machine needs to be able to contact this Storage Account so make sure it has connectivity.

The next steps show the process I use to create the configuration right through to running the remediation. I’ve uploaded the script to GitHub so you can follow it through and see what I have done.


Create the Configuration and MOF File

First step is to write a DSC configuration to install the software. I’m using the built in MSIPackage resource because it allows me to specify a URL which the software can be downloaded from. Note that DSC in Machine Configuration works a little bit differently – you can’t have credentials or reboots so be aware of those limitations. My configuration looks like below.


To generate the MOF file I just run the configuration by calling it: –


A MOF file is generated – the same as a normal DSC configuration and you can have a look to see what it contains.


Create the Configuration Package Artifacts

Now I use the GuestConfiguration module to create an artifact. This command packages together my MOF file, plus all the required modules into a zip file.


I just use the generated MOF file as an input and it will create the zip file for me. Notice that the type is ‘AuditAndSet’. This is telling the configuration that it can make changes to the virtual machine. The other option is ‘Audit’ which just checks the setting and reports the compliance state.


Upload the Package to a Storage Account

I must put the zip file into a storage account – I also need to generate a SAS URL which is going to be embedded into the policy. This is so the Machine Configuration agent knows where to get the package from.



Azure Policy Creation

All that is left to do is create the Azure Policy object which will check compliance for me – and allow me to commence remediation. The GuestConfiguration module has a command to generate this for me as demonstrated below.


A couple of things to note about some of the parameters in the image above:-

  • PolicyID is a unique ID I generated using the New-Guid cmdlet – if you make changes or updates to the policy ensure this remains the same.

  • Platform – ‘Windows’ in this case – if you want to do installs on Linux you need to write class-based DSC resources to do this (will cover in a future post).

  • Mode is ‘ApplyAndAutoCorrect’ – this will configure the machine and correct drift as well.

  • Tag – allows me to have some control over how the installation is targeted. This policy will only apply to machines which have a tag called “InstallPowerShell” with the value set to true.

The last line of the code above takes the generated policy and uploads it to Azure – by default it uploads it to the subscription but you can use any method you want to create the definition.


Assign the Policy

Before we assign the machine configuration policy we need to ensure that the prerequisite policy is installed – this is the same as in the previous blog.


The machines need to have a Managed Identity enabled so they can authenticate to the GuestConfiguration resource provider.

Assign the newly created policy to a scope of your choosing – we are now ready to test.


Testing the Deployment

I have my policy assigned to a resource group – the effect is going to be DeployIfNotExists however this works a little bit differently to a normal DINE policy. To show you how this works – I’ve assigned my policy to an empty resource group as below.


As expected I can see 100% compliance because there is nothing in that resource group.


Now I’m going to build a virtual machine in that resource group and wait for policy to take effect on it. The prerequisite policies set above will go through and enable a system assigned Managed Identity and install the policy agent for me.


My compliance is still showing 100% after this is done and this is the first trick we can use to control how this is deployed. Remember I specified a tag in my policy assignment – in order to make this policy apply to that virtual machine I need to add the tag to the server.


When I do that a sequence of events start – because the resource has been updated eventually the DeployIfNotExists policy will evaluate. However, unlike a normal DINE policy what Machine Configuration does is uses the metadata in the policy definition to create a Guest Assignment resource. The most important field on this object is the “assignmentType” and it is set to null by default. This means that the virtual machine will start evaluating the assignment but will only work in an audit mode.


Here is what the policy metadata looks like: –


And if I look at the Guest Assignment object in Azure (using the Resource Graph so we can view the properties) you can see that the assignmentType is null.


At this point the virtual machine will have received the assignment and downloaded the package from the storage account – and evaluated its compliance. It reports this back to the Guest Assignment object which Azure Policy is monitoring, and we can now see the non-compliant resource in the policy view.


And here is the compliance reason: –


The second “gate” we have to control the deployment is to run the proper DeployIfNotExists effect on the deployment and I can do this using a remediation task.


This will cause the deployment to happen as stated in the policy file – and you can see the major difference is that it will set that assignmentType value to “ApplyAndAutoCorrect”.


After that remediation task is run – I can check the Guest Assignment object in the Resource Graph and notice the difference.


The virtual machine will now download the new assignment details and see that the assignmentType has changed – the next time it runs it will now perform the correction if required. Once the software is installed the server will send a report back to the Guest Assignment service – and this will update the Guest Assignment object to compliant. Azure Policy will then check that object and report back the overall compliance.


Here is what the Guest Assignment resource looks like: –


And finally, the policy will also be compliant.


There are definitely a lot of moving parts involved with Machine Configuration and some limitations at this stage – however it is the way of the future so jump in and check it out.



The sample scripts are not supported under any Microsoft standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages.


Brought to you by Dr. Ware, Microsoft Office 365 Silver Partner, Charleston SC.