To find non-compliant resources in Azure Policy, read each subscription's latest policy states with Get-AzPolicyState, filtered to ComplianceState eq 'NonCompliant'. A resource created or changed through Azure Resource Manager shows its new state about 15 minutes later; other changes wait for the evaluation Azure runs once every 24 hours.
| Method | Best fit |
|---|---|
| PowerShell | A CSV of every policy each resource breaks, across your enabled subscriptions. |
| Admin centre | A look at 1 assignment's non-compliant resources, with the activity log a click away. |
| Altivane | Recommended for regular governance reviews, with each policy by its display name and a count for each. |
Before you start
Use an account with the Reader role on the subscriptions you want to check: Reader, like Contributor, has every read operation of Azure Policy. Microsoft lists no separate licence for reading compliance. If the portal shows a state of Not registered, the Microsoft. resource provider isn't registered on the subscription, or the account can't read compliance data.
Know what the states cover. Get-AzPolicyState returns the latest state of each resource from the last day by default. Azure Policy doesn't evaluate resources of the Microsoft. provider, apart from subscriptions and resource groups. A non-compliant state only says what a policy found: what happens next depends on the policy's effect, such as audit or deny. The example reads and exports; it starts no scan or remediation and changes nothing. The script's finally block disconnects the account and clears its saved Azure contexts.
Option 1
Find non-compliant resources with PowerShell
Install the modules once. The script reads the non-compliant states of each enabled subscription and saves 1 row for each policy a resource breaks.
Install-Module -Name Az.Accounts, Az.PolicyInsights -Repository PSGallery -Scope CurrentUser$ErrorActionPreference = 'Stop'
Connect-AzAccount -ErrorAction Stop
try {
$subscriptions = @(Get-AzSubscription | Where-Object State -eq 'Enabled')
if ($subscriptions.Count -eq 0) {
Write-Output 'No enabled subscriptions are available to this account.'
return
}
$filter = "ComplianceState eq 'NonCompliant'"
$rows = [System.Collections.Generic.List[object]]::new()
foreach ($sub in $subscriptions) {
foreach ($state in Get-AzPolicyState -SubscriptionId $sub.Id -Filter $filter) {
$rows.Add([pscustomobject]@{
Subscription = $sub.Name
ResourceGroup = $state.ResourceGroup
ResourceType = $state.ResourceType
ResourceId = $state.ResourceId
Policy = $state.PolicyDefinitionName
Effect = $state.PolicyDefinitionAction
Assignment = $state.PolicyAssignmentName
Initiative = $state.PolicySetDefinitionName
Evaluated = $state.Timestamp
})
}
}
if ($rows.Count -eq 0) {
Write-Output 'No non-compliant resources were found.'
} else {
$rows | Sort-Object Subscription, ResourceGroup, ResourceId, Policy |
Export-Csv -Path './policy-non-compliance.csv' -NoTypeInformation -Encoding utf8
Write-Output "$($rows.Count) non-compliant states saved to policy-non-compliance.csv."
}
} finally {
Disconnect-AzAccount | Out-Null
}The CSV holds the subscription, resource group, resource type and ID, the policy, its effect, the assignment, the initiative it came through and when it was evaluated. A resource that breaks 3 policies has 3 rows. PolicyDefinitionName is the definition's name, which for a built-in policy is a GUID; the portal and Altivane show its display name. To narrow the list, add to the filter, for example and PolicyDefinitionAction eq 'audit'.
Option 2
Review non-compliant resources in the Azure portal
- Sign in to the Azure portal with an account that can read the subscriptions.
- Search for Policy, open it and choose Compliance.
- Use the filters at the top to choose the scope and show the assignments that aren't compliant. Each row gives its non-compliant resources and policies.
- Select an assignment, then choose the Resource compliance tab and filter it to non-compliant resources.
- To see what happened to a resource, right-click its row and choose Show activity logs.
This suits working through 1 assignment at a time. To export the results, Microsoft points to Azure Resource Graph queries; for a file across every assignment and subscription, use PowerShell or Altivane.
Option 3 ยท Recommended for regular governance reviews
Find non-compliant resources with Altivane
- Open Altivane and choose the tenant.
- Run the Azure Policy Non-Compliance report.
- Open the Excel workbook and find Resources that are not compliant: each policy a resource breaks, with the policy's display name, its effect, the assignment, the initiative and when it was checked.
- Read Non-compliance by policy for how many resources break each policy, the most first.
The report covers every subscription where you gave Altivane the Reader role. A policy whose definition can't be read is named by its ID. The Azure Governance scorecard report counts resources not compliant with Azure Policy for the tenant's Word report.
Contact usCommon questions
I fixed the resource. Why is it still non-compliant?
The state changes when Azure evaluates it again: about 15 minutes after a change made through Azure Resource Manager, otherwise at the next daily cycle. Microsoft also offers an on-demand scan with Start-AzPolicyComplianceScan, which can take a long time to finish.
What does Not registered mean?
The Microsoft. resource provider isn't registered on the subscription, or the signed-in account can't read compliance data. Check the provider's registration and the account's role.
Can a policy require tags on resources?
Yes, Azure Policy has built-in definitions that require or add tags. To find what is untagged today, see how to find resources without tags in Azure.
Microsoft references
Technical references checked on 6 November 2026. The example scripts have been reviewed and syntax checked; they have not been run against a live tenant.