Remediate Azure Policy with PowerShell

Azure Policy is there to help us with properly governed and secure infrastructure. However, Azure Policy requires management as well.

Lately, I have built a new set of policies to ensure diagnostic logs are forwarded to Azure Monitor Logs. Multiple policies and a policy initiative were deployed to multiple subscriptions and multiple customers. All this was made possible since we manage through Azure Lighthouse.

Automatic remediation of Azure Policy

The challenge faced after deploying the policy was how to remediate them. Since policies with effect ‘deployIfNotExists’ only apply to new or modified resources, I faced the job with clicking in the portal or figure out a way to do this with PowerShell.
I actually started with the portal, as I thought it would be a quick job. After doing one or two subscriptions I realized how much time I would use.

Azure policy compliance state

Given the fact that the imitative it self contained around 50 individual policies, and at the time 19 subscriptions. I figured spending some time in PowerShell was well worth it. There is also a pretty good chance I will find my self in the same situation pretty soon.

Create remediation task with PowerShell

To create a remediation task for a policy set you can use this script. It will connect to your subscription and get all non-compliant policies. Then start a policy remediation task for the individual policies.


Policies with effect “deployIfNotExist” only work for resources that are updated or created after the policy was applied. To remediate existing resources you will have to create the remediation tasks manually through the portal, or by using PowerShell (and REST API)

By the way, fellow Azure MVP Tao Yang has created everything you need in order to enable these policies your self. Please see GitHub for complete ARM templates. And please help him maintain everything by contributing.

  • nimabi

    Thank you very much for sharing, I learned a lot from your article. Very cool. Thanks. nimabi

  • gateio

    I may need your help. I tried many ways but couldn’t solve it, but after reading your article, I think you have a way to help me. I’m looking forward for your reply. Thanks.

  • Nathan

    Apologies, point 1 should read 1000, not 100

  • Nathan

    I believe 2 things are important to note here:
    1. Get-AzPolicyState only returns 100 entries
    2. In order to get a better query result you should run the “Where-Object” statement in the “-filter” flag as outlined

  • Mart

    While this example looks quite straightforward, its worth adding that in order for it to work:

    This assumes that policies that are non-compliant are already assigned to their relevent scopes, and those assignments have rights to remediate them.
    also, the interface has changed slightly, the final line in the loop should read

    Start-AzPolicyRemediation -Name $remediationName -PolicyAssignmentId $policy.PolicyAssignmentId -PolicyDefinitionReferenceId $policy.PolicyDefinitionId

    because $policy.PolicyDefinitionReferenceId has been renamed $policy.PolicyDefinitionId in the latest Az Commandlets, since this article was written.

    Hope that helps.

    1. Martin Ehrnst

      Thanks. Two years in Azure includes alot of changes 😉

Engage by commenting