| title | Starter query samples |
|---|---|
| description | Use Azure Resource Graph to run some starter queries, including counting resources, ordering resources, or by a specific tag. |
| author | daphnemamsft |
| ms.author | daphnema |
| ms.date | 08/31/2023 |
| ms.topic | sample |
| ms.custom | devx-track-azurepowershell, devx-track-azurecli |
The first step to understanding queries with Azure Resource Graph is a basic understanding of the Query Language. If you aren't already familiar with Kusto Query Language (KQL), it's recommended to review the KQL tutorial to understand how to compose requests for the resources you're looking for.
This article uses the following starter queries:
- Count Azure resources
- Count Key Vault resources
- List resources sorted by name
- Show all virtual machines ordered by name in descending order
- Show first five virtual machines by name and their OS type
- Count virtual machines by OS type
- Show resources that contain storage
- List all Azure virtual network subnets
- List all public IP addresses
- Count resources that have IP addresses configured by subscription
- List resources with a specific tag value
- List all storage accounts with specific tag value
- List all tags and their values
- Show unassociated network security groups
- List Azure Monitor alerts ordered by severity
- List Azure Monitor alerts ordered by severity and alert state
- List Azure Monitor alerts ordered by severity, monitor service, and target resource type
If you don't have an Azure subscription, create a free account before you begin.
Azure CLI (through an extension) and Azure PowerShell (through a module) support Azure Resource Graph. Before running any of the following queries, check that your environment is ready. See Azure CLI and Azure PowerShell for steps to install and validate your shell environment of choice.
This query returns number of Azure resources that exist in the subscriptions that you have access to. It's also a good query to validate your shell of choice has the appropriate Azure Resource Graph components installed and in working order.
Resources
| summarize count()By default, Azure CLI queries all accessible subscriptions but you can specify the --subscriptions parameter to query specific subscriptions.
az graph query -q "Resources | summarize count()"
This example uses a variable for the subscription ID.
subid=$(az account show --query id --output tsv)
az graph query -q "Resources | summarize count()" --subscriptions $subid
You can also query by the scopes for management group and tenant. Replace <managementGroupId> and <tenantId> with your values.
az graph query -q "Resources | summarize count()" --management-groups '<managementGroupId>'
az graph query -q "Resources | summarize count()" --management-groups '<tenantId>'
You can also use a variable for the tenant ID.
tenantid=$(az account show --query tenantId --output tsv)
az graph query -q "Resources | summarize count()" --management-groups $tenantid
By default, Azure PowerShell gets results for all subscriptions in your tenant.
Search-AzGraph -Query "Resources | summarize count()"
This example uses a variable to query a specific subscription ID.
$subid = (Get-AzContext).Subscription.Id
Search-AzGraph -Query "authorizationresources | summarize count()" -Subscription $subid
You can query by the scopes for management group and tenant. Replace <managementGroupId>with your value. The UseTenantScope parameter doesn't require a value.
Search-AzGraph -Query "Resources | summarize count()" -ManagementGroup '<managementGroupId>'
Search-AzGraph -Query "Resources | summarize count()" -UseTenantScope
Try this query in Azure Resource Graph Explorer:
- Azure portal: portal.azure.com
- Azure Government portal: portal.azure.us
- Microsoft Azure operated by 21Vianet portal: portal.azure.cn
This query uses count instead of summarize to count the number of records returned. Only key
vaults are included in the count.
Resources
| where type =~ 'microsoft.keyvault/vaults'
| countaz graph query -q "Resources | where type =~ 'microsoft.keyvault/vaults' | count"
Search-AzGraph -Query "Resources | where type =~ 'microsoft.keyvault/vaults' | count"
Try this query in Azure Resource Graph Explorer:
- Azure portal: portal.azure.com
- Azure Government portal: portal.azure.us
- Azure operated by 21Vianet portal: portal.azure.cn
This query returns any type of resource, but only the name, type, and location
properties. It uses order by to sort the properties by the name property in ascending (asc)
order.
Resources
| project name, type, location
| order by name ascaz graph query -q "Resources | project name, type, location | order by name asc"
Search-AzGraph -Query "Resources | project name, type, location | order by name asc"
Try this query in Azure Resource Graph Explorer:
- Azure portal: portal.azure.com
- Azure Government portal: portal.azure.us
- Azure operated by 21Vianet portal: portal.azure.cn
To list only virtual machines (which are type Microsoft.Compute/virtualMachines), we can match
the property type in the results. Similar to the previous query, desc changes the order by
to be descending. The =~ in the type match tells Resource Graph to be case insensitive.
Resources
| project name, location, type
| where type =~ 'Microsoft.Compute/virtualMachines'
| order by name descaz graph query -q "Resources | project name, location, type| where type =~ 'Microsoft.Compute/virtualMachines' | order by name desc"
Search-AzGraph -Query "Resources | project name, location, type| where type =~ 'Microsoft.Compute/virtualMachines' | order by name desc"
Try this query in Azure Resource Graph Explorer:
- Azure portal: portal.azure.com
- Azure Government portal: portal.azure.us
- Azure operated by 21Vianet portal: portal.azure.cn
This query uses top to only retrieve five matching records that are ordered by name. The type
of the Azure resource is Microsoft.Compute/virtualMachines. project tells Azure Resource Graph
which properties to include.
Resources
| where type =~ 'Microsoft.Compute/virtualMachines'
| project name, properties.storageProfile.osDisk.osType
| top 5 by name descaz graph query -q "Resources | where type =~ 'Microsoft.Compute/virtualMachines' | project name, properties.storageProfile.osDisk.osType | top 5 by name desc"
Search-AzGraph -Query "Resources | where type =~ 'Microsoft.Compute/virtualMachines' | project name, properties.storageProfile.osDisk.osType | top 5 by name desc"
Try this query in Azure Resource Graph Explorer:
- Azure portal: portal.azure.com
- Azure Government portal: portal.azure.us
- Azure operated by 21Vianet portal: portal.azure.cn
Building on the previous query, we're still limiting by Azure resources of type
Microsoft.Compute/virtualMachines, but are no longer limiting the number of records returned.
Instead, we used summarize and count() to define how to group and aggregate the values by
property, which in this example is properties.storageProfile.osDisk.osType. For an example of how
this string looks in the full object, see explore resources - virtual machine
discovery.
Resources
| where type =~ 'Microsoft.Compute/virtualMachines'
| summarize count() by tostring(properties.storageProfile.osDisk.osType)az graph query -q "Resources | where type =~ 'Microsoft.Compute/virtualMachines' | summarize count() by tostring(properties.storageProfile.osDisk.osType)"
Search-AzGraph -Query "Resources | where type =~ 'Microsoft.Compute/virtualMachines' | summarize count() by tostring(properties.storageProfile.osDisk.osType)"
Try this query in Azure Resource Graph Explorer:
- Azure portal: portal.azure.com
- Azure Government portal: portal.azure.us
- Azure operated by 21Vianet portal: portal.azure.cn
A different way to write the same query is to extend a property and give it a temporary name for
use within the query, in this case os. os is then used by summarize and count() as in
the previous example.
Resources
| where type =~ 'Microsoft.Compute/virtualMachines'
| extend os = properties.storageProfile.osDisk.osType
| summarize count() by tostring(os)az graph query -q "Resources | where type =~ 'Microsoft.Compute/virtualMachines' | extend os = properties.storageProfile.osDisk.osType | summarize count() by tostring(os)"
Search-AzGraph -Query "Resources | where type =~ 'Microsoft.Compute/virtualMachines' | extend os = properties.storageProfile.osDisk.osType | summarize count() by tostring(os)"
Try this query in Azure Resource Graph Explorer:
- Azure portal: portal.azure.com
- Azure Government portal: portal.azure.us
- Azure operated by 21Vianet portal: portal.azure.cn
Note
Be aware that while =~ allows case insensitive matching, use of properties (such as
properties.storageProfile.osDisk.osType) in the query require the case to be correct. If the
property is the incorrect case, a null or incorrect value is returned and the grouping or
summarization would be incorrect.
Instead of explicitly defining the type to match, this example query finds any Azure resource
that contains the word storage.
Resources
| where type contains 'storage' | distinct typeaz graph query -q "Resources | where type contains 'storage' | distinct type"
Search-AzGraph -Query "Resources | where type contains 'storage' | distinct type"
Try this query in Azure Resource Graph Explorer:
- Azure portal: portal.azure.com
- Azure Government portal: portal.azure.us
- Azure operated by 21Vianet portal: portal.azure.cn
This query returns a list of Azure virtual networks (VNets) including subnet names and address prefixes. Thanks to Saul Dolgin for the contribution.
Resources
| where type == 'microsoft.network/virtualnetworks'
| extend subnets = properties.subnets
| mv-expand subnets
| project name, subnets.name, subnets.properties.addressPrefix, location, resourceGroup, subscriptionIdaz graph query -q "Resources | where type == 'microsoft.network/virtualnetworks' | extend subnets = properties.subnets | mv-expand subnets | project name, subnets.name, subnets.properties.addressPrefix, location, resourceGroup, subscriptionId"
Search-AzGraph -Query "Resources | where type == 'microsoft.network/virtualnetworks' | extend subnets = properties.subnets | mv-expand subnets | project name, subnets.name, subnets.properties.addressPrefix, location, resourceGroup, subscriptionId
Try this query in Azure Resource Graph Explorer:
- Azure portal: portal.Azure.com
- Azure Government portal: portal.Azure.us
- Azure operated by 21Vianet portal: portal.Azure.cn
Similar to the previous query, find everything that is a type with the word publicIPAddresses.
This query expands on that pattern to only include results where properties.ipAddress
isnotempty, to only return the properties.ipAddress, and to limit the results by the top
100. You may need to escape the quotes depending on your chosen shell.
Resources
| where type contains 'publicIPAddresses' and isnotempty(properties.ipAddress)
| project properties.ipAddress
| limit 100az graph query -q "Resources | where type contains 'publicIPAddresses' and isnotempty(properties.ipAddress) | project properties.ipAddress | limit 100"
Search-AzGraph -Query "Resources | where type contains 'publicIPAddresses' and isnotempty(properties.ipAddress) | project properties.ipAddress | limit 100"
Try this query in Azure Resource Graph Explorer:
- Azure portal: portal.azure.com
- Azure Government portal: portal.azure.us
- Azure operated by 21Vianet portal: portal.azure.cn
Using the previous example query and adding summarize and count(), we can get a list by subscription of resources with configured IP addresses.
Resources
| where type contains 'publicIPAddresses' and isnotempty(properties.ipAddress)
| summarize count () by subscriptionIdaz graph query -q "Resources | where type contains 'publicIPAddresses' and isnotempty(properties.ipAddress) | summarize count () by subscriptionId"
Search-AzGraph -Query "Resources | where type contains 'publicIPAddresses' and isnotempty(properties.ipAddress) | summarize count () by subscriptionId"
Try this query in Azure Resource Graph Explorer:
- Azure portal: portal.azure.com
- Azure Government portal: portal.azure.us
- Azure operated by 21Vianet portal: portal.azure.cn
We can limit the results by properties other than the Azure resource type, such as a tag. In this example, we're filtering for Azure resources with a tag name of Environment that have a value of Internal.
Resources
| where tags.environment=~'internal'
| project nameaz graph query -q "Resources | where tags.environment=~'internal' | project name"
Search-AzGraph -Query "Resources | where tags.environment=~'internal' | project name"
Try this query in Azure Resource Graph Explorer:
- Azure portal: portal.azure.com
- Azure Government portal: portal.azure.us
- Azure operated by 21Vianet portal: portal.azure.cn
To also provide what tags the resource has and their values, add the property tags to the
project keyword.
Resources
| where tags.environment=~'internal'
| project name, tagsaz graph query -q "Resources | where tags.environment=~'internal' | project name, tags"
Search-AzGraph -Query "Resources | where tags.environment=~'internal' | project name, tags"
Try this query in Azure Resource Graph Explorer:
- Azure portal: portal.azure.com
- Azure Government portal: portal.azure.us
- Azure operated by 21Vianet portal: portal.azure.cn
Combine the filter functionality of the previous example and filter Azure resource type by type property. This query also limits our search for specific types of Azure resources with a specific tag name and value.
Resources
| where type =~ 'Microsoft.Storage/storageAccounts'
| where tags['tag with a space']=='Custom value'az graph query -q "Resources | where type =~ 'Microsoft.Storage/storageAccounts' | where tags['tag with a space']=='Custom value'"
Search-AzGraph -Query "Resources | where type =~ 'Microsoft.Storage/storageAccounts' | where tags['tag with a space']=='Custom value'"
Try this query in Azure Resource Graph Explorer:
- Azure portal: portal.azure.com
- Azure Government portal: portal.azure.us
- Azure operated by 21Vianet portal: portal.azure.cn
Note
This example uses == for matching instead of the =~ conditional. == is a case sensitive match.
This query lists tags on management groups, subscriptions, and resources along with their values.
The query first limits to resources where tags isnotempty(), limits the included fields by only
including tags in the project, and mvexpand and extend to get the paired data from the
property bag. It then uses union to combine the results from ResourceContainers to the same
results from Resources, giving broad coverage to which tags are fetched. Last, it limits the
results to distinct paired data and excludes system-hidden tags.
ResourceContainers
| where isnotempty(tags)
| project tags
| mvexpand tags
| extend tagKey = tostring(bag_keys(tags)[0])
| extend tagValue = tostring(tags[tagKey])
| union (
resources
| where isnotempty(tags)
| project tags
| mvexpand tags
| extend tagKey = tostring(bag_keys(tags)[0])
| extend tagValue = tostring(tags[tagKey])
)
| distinct tagKey, tagValue
| where tagKey !startswith "hidden-"az graph query -q "ResourceContainers | where isnotempty(tags) | project tags | mvexpand tags | extend tagKey = tostring(bag_keys(tags)[0]) | extend tagValue = tostring(tags[tagKey]) | union (resources | where notempty(tags) | project tags | mvexpand tags | extend tagKey = tostring(bag_keys(tags)[0]) | extend tagValue = tostring(tags[tagKey]) ) | distinct tagKey, tagValue | where tagKey !startswith "hidden-""
Search-AzGraph -Query "ResourceContainers | where isnotempty(tags) | project tags | mvexpand tags | extend tagKey = tostring(bag_keys(tags)[0]) | extend tagValue = tostring(tags[tagKey]) | union (resources | where notempty(tags) | project tags | mvexpand tags | extend tagKey = tostring(bag_keys(tags)[0]) | extend tagValue = tostring(tags[tagKey]) ) | distinct tagKey, tagValue | where tagKey !startswith "hidden-""
Try this query in Azure Resource Graph Explorer:
- Azure portal: portal.azure.com
- Azure Government portal: portal.azure.us
- Azure operated by 21Vianet portal: portal.azure.cn
This query returns Network Security Groups (NSGs) that aren't associated to a network interface or subnet.
Resources
| where type =~ "microsoft.network/networksecuritygroups" and isnull(properties.networkInterfaces) and isnull(properties.subnets)
| project name, resourceGroup
| sort by name ascaz graph query -q "Resources | where type =~ 'microsoft.network/networksecuritygroups' and isnull(properties.networkInterfaces) and isnull(properties.subnets) | project name, resourceGroup | sort by name asc"
Search-AzGraph -Query "Resources | where type =~ 'microsoft.network/networksecuritygroups' and isnull(properties.networkInterfaces) and isnull(properties.subnets) | project name, resourceGroup | sort by name asc"
Try this query in Azure Resource Graph Explorer:
- Azure portal: portal.azure.com
- Azure Government portal: portal.azure.us
- Azure operated by 21Vianet portal: portal.azure.cn
alertsmanagementresources
| where type =~ 'microsoft.alertsmanagement/alerts'
| where todatetime(properties.essentials.startDateTime) >= ago(2h) and todatetime(properties.essentials.startDateTime) < now()
| project Severity = tostring(properties.essentials.severity)
| summarize AlertsCount = count() by Severity
alertsmanagementresources
| where type =~ 'microsoft.alertsmanagement/alerts'
| where todatetime(properties.essentials.startDateTime) >= ago(2h) and todatetime(properties.essentials.startDateTime) < now()
| project Severity = tostring(properties.essentials.severity),
AlertState= tostring(properties.essentials.alertState)
| summarize AlertsCount = count() by Severity, AlertStatealertsmanagementresources
| where type =~ 'microsoft.alertsmanagement/alerts'
| where todatetime(properties.essentials.startDateTime) >= ago(2h) and todatetime(properties.essentials.startDateTime) < now()
| project Severity = tostring(properties.essentials.severity),
MonitorCondition = tostring(properties.essentials.monitorCondition),
ObjectState = tostring(properties.essentials.alertState),
MonitorService = tostring(properties.essentials.monitorService),
AlertRuleId = tostring(properties.essentials.alertRule),
SignalType = tostring(properties.essentials.signalType),
TargetResource = tostring(properties.essentials.targetResourceName),
TargetResourceType = tostring(properties.essentials.targetResourceName), id
| summarize AlertsCount = count() by Severity, MonitorService , TargetResourceType- Learn more about the query language.
- Learn more about how to explore resources.
- See samples of Advanced queries.