Azure Resource Graph Query Patterns
Azure Resource Graph (ARG) queries use a KQL subset against indexed Azure resource metadata. Results are near real-time across all subscriptions.
Command Format
az graph query -q "<KQL>" --query "data[].{col1:field1, col2:field2}" -o table| Flag | Purpose |
|---|---|
-q | KQL query string |
--query | JMESPath to shape output columns |
--first N | Limit to N results |
--subscriptions | Scope to specific subscription IDs |
-o table | Table output (also: json, tsv) |
Key Tables
| Table | Contents |
|---|---|
Resources | All ARM resources — name, type, location, properties, tags, sku |
ResourceContainers | Subscriptions, resource groups, management groups |
HealthResources | Resource health availability status |
ServiceHealthResources | Azure service health events/incidents |
AuthorizationResources | Role assignments and definitions |
AdvisorResources | Azure Advisor recommendations |
KQL Essentials
=~case-insensitive equals (use fortypefield — types are lowercase)properties.fieldNamenavigates the properties JSON bagmv-expandflattens arrays (subnets, IP configs)isempty()/isnotnull()checks for null/empty fieldstostring()converts dynamic fields for display
Resource Inventory Patterns
Count all resources by type:
Resources | summarize count() by type | order by count_ descInventory by type and location:
Resources | summarize count() by type, location | order by type ascCross-subscription inventory with subscription names:
Resources
| join kind=leftouter (
ResourceContainers
| where type == 'microsoft.resources/subscriptions'
| project subscriptionId, subscriptionName=name
) on subscriptionId
| summarize count() by subscriptionName, type
| order by subscriptionName asc, count_ descAll resources in a resource group:
Resources
| where resourceGroup =~ '<rg-name>'
| project name, type, location, sku.name, kindOrphaned Resource Patterns
Unattached managed disks:
Resources
| where type =~ 'microsoft.compute/disks'
| where isempty(managedBy)
| project name, resourceGroup, location, diskSizeGb=properties.diskSizeGB, sku=sku.nameUnused public IP addresses:
Resources
| where type =~ 'microsoft.network/publicipaddresses'
| where isempty(properties.ipConfiguration)
| project name, resourceGroup, location, sku=sku.nameOrphaned network interfaces:
Resources
| where type =~ 'microsoft.network/networkinterfaces'
| where isempty(properties.virtualMachine)
| project name, resourceGroup, locationIdle load balancers (no backends):
Resources
| where type =~ 'microsoft.network/loadbalancers'
| where array_length(properties.backendAddressPools) == 0
| project name, resourceGroup, locationTag & Compliance Patterns
Resources missing a required tag:
Resources
| where isnull(tags['Environment']) or isnull(tags['CostCenter'])
| project name, type, resourceGroup, tagsTag coverage analysis by type:
Resources
| extend hasTag = isnotnull(tags['Environment'])
| summarize total=count(), tagged=countif(hasTag) by type
| extend coverage=round(100.0 * tagged / total, 1)
| order by coverage ascResources with public network access:
Resources
| where properties.publicNetworkAccess =~ 'Enabled'
| project name, type, resourceGroup, locationHealth & Diagnostics Patterns
Resource health status:
HealthResources
| where type =~ 'microsoft.resourcehealth/availabilitystatuses'
| where properties.availabilityState != 'Available'
| project name, state=properties.availabilityState, reason=properties.reasonTypeActive service health incidents:
ServiceHealthResources
| where type =~ 'microsoft.resourcehealth/events'
| where properties.Status == 'Active'
| project name, title=properties.Title, status=properties.StatusFailed provisioning states:
Resources
| where properties.provisioningState != 'Succeeded'
| project name, type, resourceGroup, state=properties.provisioningStateService-Specific Patterns
App Services and their plans:
Resources
| where type =~ 'microsoft.web/sites'
| project name, kind, location, plan=properties.serverFarmId, state=properties.state, resourceGroupContainer Apps:
Resources
| where type =~ 'microsoft.app/containerapps'
| project name, location, provisioningState=properties.provisioningState, resourceGroupVNet and subnet discovery:
Resources
| where type =~ 'microsoft.network/virtualnetworks'
| mv-expand subnet=properties.subnets
| project vnetName=name, subnetName=subnet.name, prefix=subnet.properties.addressPrefixAdvisor cost recommendations:
AdvisorResources
| where properties.category == 'Cost'
| project name, impact=properties.impact, solution=properties.shortDescription.solution