In part 1 of the Azure Guest Configuration Policy series I walked through the process of creating a custom guest policy using a DSC configuration. In this post, I’ll walk through the output of the guest policy publishing process and how to assign the new initiative to a target scope in an Azure subscription.
Each time you run the Publish-GuestConfigurationPolicy cmdlet, a new initiative and two policy definitions are created.

An Azure Policy initiative is a way to group policy definitions, which in this case are the “Deploy” and “Audit” definitions. To help explain what these definitions do, let’s take a look at an excerpt from the “Understand Azure Policy’s Guest Configuration” Microsoft documentation:
“Each audit run by Guest Configuration requires two policy definitions, a DeployIfNotExists definition and an AuditIfNotExists definition. The DeployIfNotExists definition is used to prepare the machine with the Guest Configuration agent and other components to support the validation tools.”
I won’t go any further into the weeds on concepts in this post, but if you are new to Guest Configuration policy, or Azure Policy in general, I recommend reading the Guest Configuration documentation to get familiar with the concepts and configuration options.
Back to assigning the new Guest Configuration policy…
To apply, or assign the new custom policy to a group of VMs, you need to assign the initiative to a scope. A newly published policy is not assigned by default, which means it is not actively auditing resources. Each new policy needs to be assigned to the appropriate scope where the policy should be applied for auditing.
In this example, the policy definition was published to a subscription. We need to assign the policy to either the entire subscription, or a sub-scope like a resource group. To assign the policy, click the initiative (in this example ‘[Initiative] Windows Server 2016 Baseline’. Once on the ‘Initiative Definition’ blade, we can see the policy definitions that make up the new initiative.

If you click the ‘Deploy’ definition, you can see the definition json which consists of the logic used to determine where to deploy this policy. In this case, the ‘policyRule’ section has been edited from the default to only include Windows Server 2016 VMs.

As you can see in the json logic, if all of the highlighted logic in the policy rule returns true, the DeployIfNotExists policy definition runs on the targeted VM(s). At this point, to quote from the Microsoft documentation, “Once the DeployIfNotExists assignment is Compliant, the AuditIfNotExists policy assignment uses the local validation tools to determine if the configuration assignment is Compliant or Non-compliant”.
Now that we’ve reviewed the underlying json and the use case for each default definition, it’s time to assign the initiative. It’s important to assign the initiative and not an individual definition. Both the ‘Deploy’ and ‘Audit’ definitions are required.
To assign the initiative, simply choose the ‘Assign’ option at the top left of the ‘Initiative’ blade:

Once you select the ‘Assign’ option, under ‘Scope’ there are options to set the scope and any exclusions that may be necessary. In this example, I am targeting a specific resource group in my subscription:

Once the scope has been configured, select ‘Review + create’ and then ‘Create’ to assign the initiative.
Now that the initiative has been assigned, it should be visible in the ‘Assignments’ blade.

In order to understand whether or not the initiative and it’s underlying policy definitions are functioning properly, select the ‘Compliance’ blade and search for the newly assigned initiative.
Note: It will take some time for the policy initiative to show compliance. When a policy is assigned, the compliance state will show as ‘Not started’ until the underlying configuration and evaluation has completed.

Once the policy shows a ‘Compliant’ or ‘Non-compliant’ compliance state, click the policy to view the compliance for the definitions.

In this case the ‘Deploy’ policy definition is compliant, meaning the configuration was successful on all targeted VMs. The ‘Audit’ policy definition is non-compliant, and therefore a bit more interesting to examine. When we select the ‘Audit’ policy definition, a view of all non-compliant resources is populated along with the compliance various properties for each resource.

Notice the ‘Details’ link under the ‘Non-compliance reason’ column. Clicking the ‘Details’ link brings up ‘Compliance details’, which includes a link (#2 in image 8 above) that opens a detailed view of which specific configuration resources are failing compliance. Image 9 below shows the detailed compliance view.

We’ve now got a custom Azure policy that can be applied at the management group or subscription level to audit hardening compliance across all required VMs in the estate!
In the next post in this series, we’ll create a more complex custom Guest Configuration Policy using a custom DSC resource to audit anti-malware compliance dynamically across OS versions.