Understanding the Azure Resource Graph query language

The query language for the Azure Resource Graph supports many operators and functions. Each work and operate based on Kusto Query Language (KQL). To learn about the query language used by Resource Graph, start with the tutorial for KQL.

This article covers the language components supported by Resource Graph:

Resource Graph tables

Resource Graph provides several tables for the data it stores about Azure Resource Manager resource types and their properties. Some tables can be used with join or union operators to get properties from related resource types. Here's the list of tables available in Resource Graph:

Resource Graph table Can join other tables? Description
Resources Yes The default table if none defined in the query. Most Resource Manager resource types and properties are here.
ResourceContainers Yes Includes management group (Microsoft.Management/managementGroups), subscription (Microsoft.Resources/subscriptions) and resource group (Microsoft.Resources/subscriptions/resourcegroups) resource types and data.
AdvisorResources Yes (preview) Includes resources related to Microsoft.Advisor.
AlertsManagementResources Yes (preview) Includes resources related to Microsoft.AlertsManagement.
DesktopVirtualizationResources Yes Includes resources related to Microsoft.DesktopVirtualization.
ExtendedLocationResources No Includes resources related to Microsoft.ExtendedLocation.
GuestConfigurationResources No Includes resources related to Microsoft.GuestConfiguration.
HealthResources Yes (preview) Includes resources related to Microsoft.ResourceHealth/availabilitystatuses.
IoTSecurityResources No Includes resources related to Microsoft.IoTSecurity.
KubernetesConfigurationResources No Includes resources related to Microsoft.KubernetesConfiguration.
MaintenanceResources Partial, join to only. (preview) Includes resources related to Microsoft.Maintenance.
PatchAssessmentResources No Includes resources related to Azure Virtual Machines patch assessment.
PatchInstallationResources No Includes resources related to Azure Virtual Machines patch installation.
PolicyResources Yes Includes resources related to Microsoft.PolicyInsights.
RecoveryServicesResources Partial, join to only. (preview) Includes resources related to Microsoft.DataProtection and Microsoft.RecoveryServices.
SecurityResources Yes (preview) Includes resources related to Microsoft.Security.
ServiceHealthResources No (preview) Includes resources related to Microsoft.ResourceHealth/events.
WorkloadMonitorResources No Includes resources related to Microsoft.WorkloadMonitor.

For a complete list, including resource types, see Reference: Supported tables and resource types.


Resources is the default table. While querying the Resources table, it isn't required to provide the table name unless join or union are used. However, the recommended practice is to always include the initial table in the query.

Use Resource Graph Explorer in the portal to discover what resource types are available in each table. As an alternative, use a query such as <tableName> | distinct type to get a list of resource types the given Resource Graph table supports that exist in your environment.

The following query shows a simple join. The query result blends the columns together and any duplicate column names from the joined table, ResourceContainers in this example, are appended with 1. As ResourceContainers table has types for both subscriptions and resource groups, either type might be used to join to the resource from Resources table.

| join ResourceContainers on subscriptionId
| limit 1

The following query shows a more complex use of join. First, the query uses project to get the fields from Resources for the Azure Key Vault vaults resource type. The next step uses join to merge the results with ResourceContainers where the type is a subscription on a property that is both in the first table's project and the joined table's project. The field rename avoids join adding it as name1 since the property already is projected from Resources. The query result is a single key vault displaying type, the name, location, and resource group of the key vault, along with the name of the subscription it's in.

| where type == 'microsoft.keyvault/vaults'
| project name, type, location, subscriptionId, resourceGroup
| join (ResourceContainers | where type=='microsoft.resources/subscriptions' | project SubName=name, subscriptionId) on subscriptionId
| project type, name, location, resourceGroup, SubName
| limit 1


When limiting the join results with project, the property used by join to relate the two tables, subscriptionId in the above example, must be included in project.

Extended properties

As a preview feature, some of the resource types in Resource Graph have more type-related properties available to query beyond the properties provided by Azure Resource Manager. This set of values, known as extended properties, exists on a supported resource type in properties.extended. To see which resource types have extended properties, use the following query:

| where isnotnull(properties.extended)
| distinct type
| order by type asc

Example: Get count of virtual machines by instanceView.powerState.code:

| where type == 'microsoft.compute/virtualmachines'
| summarize count() by tostring(properties.extended.instanceView.powerState.code)

Resource Graph custom language elements

Shared query syntax (preview)

As a preview feature, a shared query can be accessed directly in a Resource Graph query. This scenario makes it possible to create standard queries as shared queries and reuse them. To call a shared query inside a Resource Graph query, use the {{shared-query-uri}} syntax. The URI of the shared query is the Resource ID of the shared query on the Settings page for that query. In this example, our shared query URI is /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/SharedQueries/providers/Microsoft.ResourceGraph/queries/Count VMs by OS. This URI points to the subscription, resource group, and full name of the shared query we want to reference in another query. This query is the same as the one created in Tutorial: Create and share a query.


You can't save a query that references a shared query as a shared query.

Example 1: Use only the shared query

The results of this Resource Graph query are the same as the query stored in the shared query.

{{/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/SharedQueries/providers/Microsoft.ResourceGraph/queries/Count VMs by OS}}

Example 2: Include the shared query as part of a larger query

This query first uses the shared query, and then uses limit to further restrict the results.

{{/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/SharedQueries/providers/Microsoft.ResourceGraph/queries/Count VMs by OS}}
| where properties_storageProfile_osDisk_osType =~ 'Windows'

Supported KQL language elements

Resource Graph supports a subset of KQL data types, scalar functions, scalar operators, and aggregation functions. Specific tabular operators are supported by Resource Graph, some of which have different behaviors.

Supported tabular/top level operators

Here's the list of KQL tabular operators supported by Resource Graph with specific samples:

KQL Resource Graph sample query Notes
count Count key vaults
distinct Show resources that contain storage
extend Count virtual machines by OS type
join Key vault with subscription name Join flavors supported: innerunique, inner, leftouter. Limit of 3 join in a single query, 1 of which may be a cross-table join. If all cross-table join use is between Resource and ResourceContainers, then 3 cross-table join are allowed. Custom join strategies, such as broadcast join, aren't allowed. For which tables can use join, see Resource Graph tables.
limit List all public IP addresses Synonym of take. Doesn't work with Skip.
mvexpand Legacy operator, use mv-expand instead. RowLimit max of 400. The default is 128.
mv-expand List Azure Cosmos DB with specific write locations RowLimit max of 400. The default is 128. Limit of 2 mv-expand in a single query.
order List resources sorted by name Synonym of sort
parse Get virtual networks and subnets of network interfaces It's optimal to access properties directly if they exist instead of using parse.
project List resources sorted by name
project-away Remove columns from results
sort List resources sorted by name Synonym of order
summarize Count Azure resources Simplified first page only
take List all public IP addresses Synonym of limit. Doesn't work with Skip.
top Show first five virtual machines by name and their OS type
union Combine results from two queries into a single result Single table allowed: T | union [kind= inner|outer] [withsource=ColumnName] Table. Limit of 3 union legs in a single query. Fuzzy resolution of union leg tables isn't allowed. May be used within a single table or between the Resources and ResourceContainers tables.
where Show resources that contain storage

There's a default limit of 3 join and 3 mv-expand operators in a single Resource Graph SDK query. You can request an increase in these limits for your tenant through Help + support.

To support the "Open Query" portal experience, Azure Resource Graph Explorer has a higher global limit than Resource Graph SDK.

Query scope

The scope of the subscriptions or management groups from which resources are returned by a query defaults to a list of subscriptions based on the context of the authorized user. If a management group or a subscription list isn't defined, the query scope is all resources, which includes Azure Lighthouse delegated resources.

The list of subscriptions or management groups to query can be manually defined to change the scope of the results. For example, the REST API managementGroups property takes the management group ID, which is different from the name of the management group. When managementGroups is specified, resources from the first 10,000 subscriptions in or under the specified management group hierarchy are included. managementGroups can't be used at the same time as subscriptions.

Example: Query all resources within the hierarchy of the management group named My Management Group with ID myMG.


    POST https://management.azure.com/providers/Microsoft.ResourceGraph/resources?api-version=2021-03-01
  • Request Body

        "query": "Resources | summarize count()",
        "managementGroups": ["myMG"]

The AuthorizationScopeFilter parameter enables you to list Azure Policy assignments and Azure RBAC role assignments in the AuthorizationResources table that are inherited from upper scopes. The AuthorizationScopeFilter parameter accepts the following values for the PolicyResources and AuthorizationResources tables:

  • AtScopeAndBelow (default if not specified): Returns assignments for the given scope and all child scopes
  • AtScopeAndAbove: Returns assignments for the given scope and all parent scopes, but not child scopes
  • AtScopeAboveAndBelow: Returns assignments for the given scope, all parent scopes and all child scopes
  • AtScopeExact: Returns assignments only for the given scope; no parent or child scopes are included


To use the AuthorizationScopeFilter parameter, be sure to use the 2021-06-01-preview or later API version in your requests.

Example: Get all policy assignments at the myMG management group and Tenant Root (parent) scopes.


    POST https://management.azure.com/providers/Microsoft.ResourceGraph/resources?api-version=2021-06-01-preview
  • Request Body Sample

      "options": {
        "authorizationScopeFilter": "AtScopeAndAbove"
      "query": "PolicyResources | where type =~ 'Microsoft.Authorization/PolicyAssignments'",
      "managementGroups": ["myMG"]

Example: Get all policy assignments at the mySubscriptionId subscription, management group, and Tenant Root scopes.


    POST https://management.azure.com/providers/Microsoft.ResourceGraph/resources?api-version=2021-06-01-preview
  • Request Body Sample

      "options": {
        "authorizationScopeFilter": "AtScopeAndAbove"
      "query": "PolicyResources | where type =~ 'Microsoft.Authorization/PolicyAssignments'",
      "subscriptions": ["mySubscriptionId"]

Escape characters

Some property names, such as those that include a . or $, must be wrapped or escaped in the query or the property name is interpreted incorrectly and doesn't provide the expected results.

  • . - Wrap the property name as such: ['propertyname.withaperiod']

    Example query that wraps the property odata.type:

    where type=~'Microsoft.Insights/alertRules' | project name, properties.condition.['odata.type']
  • $ - Escape the character in the property name. The escape character used depends on the shell that runs Resource Graph.

    • bash - \

      Example query that escapes the property $type in Bash:

      where type=~'Microsoft.Insights/alertRules' | project name, properties.condition.\$type
    • cmd - Don't escape the $ character.

    • PowerShell - `

      Example query that escapes the property $type in PowerShell:

      where type=~'Microsoft.Insights/alertRules' | project name, properties.condition.`$type

Next steps