Raw New Markdown
Generating updated version of doc...
Rendered New Markdown
Generating updated version of doc...
---
title: Get policy compliance data
description: Azure Policy evaluations and effects determine compliance. Learn how to get the compliance details of your Azure resources.
ms.date: 02/10/2025
ms.topic: how-to
ms.custom: devx-track-azurepowershell, devx-track-azurecli
---
# Get compliance data of Azure resources
One of the largest benefits of Azure Policy is the insight and controls it provides over resources in a subscription or [management group](../../management-groups/overview.md) of subscriptions. This control can prevent resources from being created in the wrong location, enforce common and consistent tag usage, or audit existing resources for appropriate configurations and settings. In all cases, Azure Policy generates data that enables you to understand the compliance state of your environment.
Before reviewing compliance data, it's important to [understand compliance states](../concepts/compliance-states.md) in Azure Policy.
There are several ways to access the compliance information generated by your policy and initiative assignments:
- [Azure portal](#portal).
- [Command line](#command-line).
- [Azure Monitor logs](#azure-monitor-logs).
- [Azure Resource Graph](#azure-resource-graph) queries.
Before looking at the methods to report on compliance, let's look at when compliance information is updated and the frequency and events that trigger an evaluation cycle.
## Evaluation triggers
The results of a completed evaluation cycle are available in the `Microsoft.PolicyInsights` Resource Provider through `PolicyStates` and `PolicyEvents` operations. For more information about the operations of the Azure Policy Insights REST API, see [Azure Policy Insights](/rest/api/policy/).
Evaluations of assigned policies and initiatives happen as the result of various events:
- A policy or initiative is newly assigned to a scope. It takes about five minutes for the assignment to be applied to the defined scope, then the evaluation cycle begins for applicable resources against the newly assigned policy or initiative. Depending on the effects used, resources are marked as compliant, non-compliant, exempt, or unknown. A large policy or initiative evaluated against a large scope of resources can take time, so there's no predefined expectation of when the evaluation cycle completes. After it completes, updated compliance results are available in the portal and Software Development Kits (SDKs).
- A policy or initiative already assigned to a scope is updated. The evaluation cycle and timing for this scenario is the same as for a new assignment to a scope.
- A resource is deployed to or updated within a scope with an assignment via Azure Resource Manager, REST API, or a supported SDK. In this scenario, the effect event (append, audit, deny, deploy) and compliant status information for the individual resource becomes available in the portal and SDKs around 15 minutes later. This event doesn't cause an evaluation of other resources.
- A subscription (resource type `Microsoft.Resources/subscriptions`) is created or moved within a [management group hierarchy](../../management-groups/overview.md) with an assigned policy definition targeting the subscription resource type. Evaluation of the subscription supported effects (audit, auditIfNotExist, deployIfNotExists, modify), logging, and any remediation actions takes around 30 minutes.
- A [policy exemption](../concepts/exemption-structure.md) is created, updated, or deleted. In this scenario, the corresponding assignment is evaluated for the defined exemption scope.
- Standard compliance evaluation cycle. Once every 24 hours, assignments are automatically reevaluated. A large policy or initiative of many resources can take time, so there's no predefined expectation of when the evaluation cycle completes. Once it completes, updated compliance results are available in the portal and SDKs.
- The [machine configuration](../../machine-configuration/overview.md) resource provider is updated with compliance details by a managed resource.
- On-demand scan.
> [!NOTE]
> By design, Azure Policy exempts from policy evaluation all resources under the `Microsoft.Resources` resource provider except for subscriptions and resource groups, which can be evaluated.
### On-demand evaluation scan
An evaluation scan for a subscription or a resource group can be started with REST, Azure CLI, Azure PowerShell, Azure Policy extension for Visual Studio Code, or [Azure Policy Compliance Scan GitHub Action](https://github.com/marketplace/actions/azure-policy-compliance-scan). The on-demand scans are an asynchronous process that takes a long time to run because resources are evaluated against all assigned policies.
> [!NOTE]
> Not all Azure resource providers support on-demand evaluation scans. For example, [Azure Virtual Network Manager (AVNM)](../../../virtual-network-manager/overview.md) currently doesn't support either manual triggers or the standard policy compliance evaluation cycle (daily scans).
#### On-demand evaluation scan using REST
As an asynchronous process, the REST endpoint to start the scan doesn't wait until the scan is complete to respond. Instead, it provides a URI to query the status of the requested evaluation.
In each REST API URI, there are variables that are used that you need to replace with your own values:
- `{resourceGroupName}`: Replace with the name of your resource group.
- `{subscriptionId}`: Replace with your subscription ID.
The scan supports evaluation of resources in a subscription or in a resource group. Start a scan by scope with a REST API POST command using the following URI structures:
Use the following command to evaluate a subscription. You can run the command from your browser at [Policy States - Trigger Subscription Evaluation](/rest/api/policy/policy-states/trigger-subscription-evaluation) using the **Try it** option.
```http
POST https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.PolicyInsights/policyStates/latest/triggerEvaluation?api-version=2019-10-01
```
Use the following command to evaluate a resource group. You can run the command from your browser at [Policy States - Trigger Resource Group Evaluation](/rest/api/policy/policy-states/trigger-resource-group-evaluation) using the **Try it** option.
```http
POST https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.PolicyInsights/policyStates/latest/triggerEvaluation?api-version=2019-10-01
```
The subscription and resource group REST API calls return a **202 Accepted** status. Included in the response header is a `location` property with the following format:
```http
https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.PolicyInsights/asyncOperationResults/{ResourceContainerGUID}?api-version=2019-10-01
```
`{ResourceContainerGUID}` is statically generated for the scope requested. If a scope is already running an on-demand scan, a new scan isn't started. Instead, the new request is provided the same `{ResourceContainerGUID}` `location` URI for status. A REST API GET command to the `location` URI returns a **202 Accepted** while the evaluation is ongoing. When the evaluation scan is complete, it returns a **200 OK** status. The body of a completed scan is a JSON response with the status: `succeeded`.
#### On-demand evaluation scan using Azure CLI
The compliance scan is started with the [az policy state trigger-scan](/cli/azure/policy/state#az-policy-state-trigger-scan) command.
By default, `az policy state trigger-scan` starts an evaluation for all resources in the current subscription. To start an evaluation on a specific resource group, use the `resource-group` parameter. The following example starts a compliance scan in the current subscription for a resource group. Replace `resourceGroupName` with your resource group's name:
```azurecli-interactive
az policy state trigger-scan --resource-group "resourceGroupName"
```
You can choose not to wait for the asynchronous process to complete before continuing with the `no-wait` parameter.
#### On-demand evaluation scan using Azure PowerShell
The compliance scan is started with the [Start-AzPolicyComplianceScan](/powershell/module/az.policyinsights/start-azpolicycompliancescan) cmdlet.
By default, `Start-AzPolicyComplianceScan` starts an evaluation for all resources in the current subscription. To start an evaluation on a specific resource group, use the `ResourceGroupName` parameter. The following example starts a compliance scan in the current subscription for a resource group. Replace `resourceGroupName` with your resource group's name:
```azurepowershell-interactive
Start-AzPolicyComplianceScan -ResourceGroupName 'resourceGroupName'
```
You can have PowerShell wait for the asynchronous call to complete before providing the results output or have it run in the background as a [job](/powershell/module/microsoft.powershell.core/about/about_jobs). To use a PowerShell job to run the compliance scan in the background, use the `AsJob` parameter and set the value to an object, such as `$job` in this example:
```azurepowershell-interactive
$job = Start-AzPolicyComplianceScan -AsJob
```
You can check on the status of the job by checking on the `$job` object. The job is of the type `Microsoft.Azure.Commands.Common.AzureLongRunningJob`. Use `Get-Member` on the `$job` object to see available properties and methods.
While the compliance scan is running, checking the `$job` object outputs results such as these:
```azurepowershell-interactive
$job
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
2 Long Running O... AzureLongRunni... Running True localhost Start-AzPolicyCompliance...
```
When the compliance scan completes, the `State` property changes to _Completed_.
#### On-demand evaluation scan using Visual Studio Code
The Azure Policy extension for Visual Studio Code is capable of running an evaluation scan for a specific resource. This scan is a synchronous process, unlike the Azure PowerShell and REST methods. For details and steps, see [On-demand evaluation with the VS Code extension](./extension-for-vscode.md#on-demand-evaluation-scan).
#### On-demand evaluation scan using GitHub Actions
Use the [Azure Policy Compliance Scan action](https://github.com/marketplace/actions/azure-policy-compliance-scan) to trigger an on-demand evaluation scan from your [GitHub workflow](https://docs.github.com/actions/writing-workflows/about-workflows) on one or multiple resources, resource groups, or subscriptions, and gate the workflow based on the compliance state of resources. You can also configure the workflow to run at a scheduled time so that you get the latest compliance status at a convenient time. Optionally, GitHub Actions can generate a report on the compliance state of scanned resources for further analysis or for archiving.
The following example runs a compliance scan for a subscription. In `scopes` use your subscription ID.
```yaml
on:
schedule:
- cron: '0 8 * * *' # runs every morning 8am
jobs:
assess-policy-compliance:
runs-on: ubuntu-latest
steps:
- name: Login to Azure
uses: azure/login@v2
with:
creds: ${{secrets.AZURE_CREDENTIALS}}
- name: Check for resource compliance
uses: azure/policy-compliance-scan@v0
with:
scopes: |
/subscriptions/aaaa6a6a-bb7b-cc8c-dd9d-eeeeee0e0e0e
```
For more information and workflow samples, see the [GitHub Actions for Azure Policy Compliance Scan repo](https://github.com/Azure/policy-compliance-scan).
## Portal
The Azure portal showcases a graphical experience of visualizing and understanding the state of compliance in your environment. On the **Policy** page, the **Overview** option provides details for available scopes on the compliance of both policies and initiatives. Along with the compliance state and count per assignment, it contains a chart showing compliance over the last seven days. The **Compliance** page contains much of this same information (except the chart), but provides more filtering and sorting options.
:::image type="content" source="../media/getting-compliance-data/compliance-page-small.png" lightbox="../media/getting-compliance-data/compliance-page.png" alt-text="Screenshot of Compliance page, filtering options, and details." border="false":::
Since a policy or initiative can be assigned to different scopes, the table includes the scope for each assignment and the type of definition that was assigned. The number of non-compliant resources and non-compliant policies for each assignment are also provided. Selecting on a policy or initiative in the table provides a deeper look at the compliance for that particular assignment.
:::image type="content" source="../media/getting-compliance-data/compliance-details-small.png" lightbox="../media/getting-compliance-data/compliance-details.png" alt-text="Screenshot of Compliance Details page, including counts and resource compliant details." border="false":::
The list of resources on the **Resource compliance** tab shows the evaluation status of existing resources for the current assignment. The tab defaults to all compliance states, but can be filtered.
For [Resource Provider mode](../concepts/definition-structure-basics.md#resource-provider-modes) resources, on the **Resource compliance** tab, selecting the resource opens the component compliance details. This page also offers tabs to see the policies that are assigned to this resource and change history.
:::image type="content" source="../media/getting-compliance-data/compliance-components.png" alt-text="Screenshot of Component Compliance tab and compliance details for a Resource Provider mode assignment." border="false":::
Back on the resource compliance page, right-click on the row of the event you would like to gather more details on and select **Show activity logs**. The activity log page opens and is prefiltered to the search showing details for the assignment and the events. The activity log provides more context and information about those events.
:::image type="content" source="../media/getting-compliance-data/compliance-activitylog-small.png" lightbox="../media/getting-compliance-data/compliance-activitylog.png" alt-text="Screenshot of the Activity Log for Azure Policy activities and evaluations." border="false":::
> [!NOTE]
> Compliance results, even in the same format shown above, can be exported from the portal with [Azure Resource Graph queries](/azure/governance/policy/samples/resource-graph-samples).
## Command line
The same information available in the portal can be retrieved with the REST API, Azure CLI, and Azure PowerShell.
### REST API
For details about the REST API, see the [Azure Policy](/rest/api/policy/) reference. The REST API reference pages have a **Try It** option on each operation that allows you to run the command in a browser. You can also use Azure CLI or your preferred REST API client to run commands.
#### Summarize results
With the REST API, you can summarize by container, definition, or assignment. Here's an example of summarization at the subscription level using Azure Policy Insight's [Summarize For Subscription](/rest/api/policy/policy-states/summarize-for-subscription):
```http
POST https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.PolicyInsights/policyStates/latest/summarize?api-version=2019-10-01
```
The output summarizes the subscription, and the summarized compliance are in the `nonCompliantResources` and `nonCompliantPolicies` properties. This request provides other details, including each assignment that made up the non-compliant numbers and the definition information for each assignment. Each policy object in the hierarchy provides a `queryResultsUri` that can be used to get more detail at that level.
#### Query for resources
In the previous example, `value.policyAssignments.policyDefinitions.results.queryResultsUri` provides a sample URI for all non-compliant resources for a specific policy definition. In the `$filter` value, ComplianceState is equal (eq) to `NonCompliant`, `PolicyAssignmentId` is specified for the policy definition, and then the PolicyDefinitionId itself. The reason for including the `PolicyAssignmentId` in the filter is because the `PolicyDefinitionId` could exist in several policy or initiative assignments with different scopes. By specifying both the `PolicyAssignmentId` and the `PolicyDefinitionId`, we can be explicit in the results we're looking for. Previously, for `PolicyStates` we used `latest`, which automatically sets a `from` and `to` time window of the last 24-hours.
Example of the `queryResultsUri` value:
```http
https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.PolicyInsights/policyStates/latest/queryResults?api-version=2019-10-01&$from=2025-01-01 04:28:22Z&$to=2025-02-10 04:28:22Z&$filter=ComplianceState eq 'NonCompliant' and PolicyAssignmentId eq '/subscriptions/{subscriptionId}/resourcegroups/rg-tags/providers/microsoft.authorization/policyassignments/37ce239ae4304622914f0c77' and PolicyDefinitionId eq '/providers/microsoft.authorization/policydefinitions/1e30110a-5ceb-460c-a204-c1c3969c6d62'
```
#### View events
When a resource is created or updated, a policy evaluation result is generated. Results are called _policy events_. Use the following URI to view recent policy events associated with the subscription.
```http
https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.PolicyInsights/policyEvents/default/queryResults?api-version=2019-10-01
```
For more information about querying policy events, see [Azure Policy Events](/rest/api/policy/policy-events).
### Azure CLI
The [Azure CLI](/cli/azure/what-is-azure-cli) command group for Azure Policy covers most operations that are available in REST or Azure PowerShell. For the full list of available commands, see [az policy](/cli/azure/policy).
Get the state summary for the topmost assigned policy with the highest number of non-compliant resources.
```azurecli-interactive
az policy state summarize --top 1
```
Get the state record for the most recently evaluated resource and the output default is by timestamp in descending order.
```azurecli-interactive
az policy state list --top 1
```
Get the details for all non-compliant virtual network resources.
```azurecli-interactive
az policy state list --filter "ResourceType eq 'Microsoft.Network/virtualNetworks'"
```
Get events related to non-compliant virtual network resources that occurred after a specific date. Use the `from` parameter with a date in ISO 8601 format.
```azurecli-interactive
az policy event list --filter "ResourceType eq 'Microsoft.Network/virtualNetworks'" --from '2025-02-10T00:00:00Z'
```
### Azure PowerShell
You can run the following commands from Azure Cloud Shell.
Get the state summary for the topmost assigned policy with the highest number of non-compliant resources.
```azurepowershell-interactive
Get-AzPolicyStateSummary -Top 1
```
Get the state record for the most recently evaluated resource. The output default is by timestamp in descending order.
```azurepowershell-interactive
Get-AzPolicyState -Top 1
```
Get the details for all non-compliant virtual network resources.
```azurepowershell-interactive
Get-AzPolicyState -Filter "ResourceType eq '/Microsoft.Network/virtualNetworks'"
```
Get events related to non-compliant virtual network resources that occurred after a specific date. Use the `From` parameter with a date in ISO 8601 format.
```azurepowershell-interactive
Get-AzPolicyEvent -Filter "ResourceType eq '/Microsoft.Network/virtualNetworks'" -From '2025-02-10'
```
The output includes a `PrincipalOid` property that can be used to get a specific user with the Azure PowerShell cmdlet `Get-AzADUser`. Replace `{principalOid}` with the value you get from the previous command.
```azurepowershell-interactive
(Get-AzADUser -ObjectId {principalOid}).DisplayName
```
## Azure Monitor logs
If you have a [Log Analytics workspace](/azure/azure-monitor/logs/log-query-overview) with `AzureActivity` from the [Activity Log Analytics solution](/azure/azure-monitor/essentials/activity-log) tied to your subscription, you can also view non-compliance results from the evaluation of new and updated resources using Kusto queries and the `AzureActivity` table. With details in Azure Monitor logs, alerts can be configured to watch for non-compliance.
## Azure Resource Graph
Compliance records are stored in Azure Resource Graph (ARG). Data can be exported from ARG queries to form customized dashboards based on the scopes and policies of interest. Review our [sample queries](/azure/governance/policy/samples/resource-graph-samples) for exporting compliance data through ARG.
## Next steps
- Review examples at [Azure Policy samples](/azure/governance/policy/samples/index).
- Review the [Azure Policy definition structure](../concepts/definition-structure-basics.md).
- Review [Understanding policy effects](../concepts/effect-basics.md).
- Understand how to [programmatically create policies](programmatically-create.md).
- Learn how to [remediate non-compliant resources](remediate-resources.md).
- Review what a management group is with [Organize your resources with Azure management groups](../../management-groups/overview.md).