27 Sep 2019

How to manually trigger an Azure Policy Evaluation Cycle

Azure Policy is a comprehensive tool to control and govern your azure environments. Whether you want to audit or prevent things from happening in your azure subscriptions, there are plenty of built-in policies you can customize according to your needs. Now I often get the question when and where policies get evaluated once created.

Once a policy or policy initiative has been assigned to a scope (Management Group, Subscription or Resource Group), it usually takes up to 30 minutes to take effect. The policy then evaluates compliance state against all underlying resources (for policies with audit effect). Same applies for changes to existing policy assignments.

While policy effect “deny” prevents affected deployments at submission time on ARM level, recurring policy evaluation against compliance state occurs then every 24 hours.

If you want to initiate a manual instant policy evaluation cycle, you can leverage the ARM REST APIs. Here’s an example to trigger an evaluation cycle on subscription level.

$subscriptionId = "your subscription id goes here"
$uri = "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.PolicyInsights/policyStates/latest/triggerEvaluation?api-version=2018-07-01-preview"
$azContext = Get-AzContext
$azProfile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile
$profileClient = New-Object -TypeName Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient -ArgumentList ($azProfile)
$token = $profileClient.AcquireAccessToken($azContext.Tenant.Id)
$authHeader = @{
    'Content-Type'='application/json'
    'Authorization'='Bearer ' + $token.AccessToken
}
Invoke-RestMethod -Method Post -Uri $uri -UseBasicParsing -Headers $authHeader

And a similar example to trigger the eval cycle on a specific resource group.

$subscriptionId = "your subscription id goes here>"
$resourceGroupName = "your resource group goes here>"
$uri = "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.PolicyInsights/policyStates/latest/triggerEvaluation?api-version=2018-07-01-preview"
$azContext = Get-AzContext
$azProfile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile
$profileClient = New-Object -TypeName Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient -ArgumentList ($azProfile)
$token = $profileClient.AcquireAccessToken($azContext.Tenant.Id)
$authHeader = @{
    'Content-Type'='application/json'
    'Authorization'='Bearer ' + $token.AccessToken
}
Invoke-RestMethod -Method Post -Uri $uri -UseBasicParsing -Headers $authHeader

A happy governance day!