• Keep up, Get ahead

    Join over 14,000 subscribers and 50,000 readers per month who get the latest updates and expert content from across the community.

Saving time with Azure Resource Graph

This year, at the Ignite conference, Microsoft announced Azure Resource Graph service. As we can read in the documentation, Azure Resource Graph is:

a service in Azure that is designed to extend Azure Resource Management by providing efficient and performant resource exploration with the ability to query at scale across all subscriptions and management groups so that you can effectively govern your environment. These queries provide the following capabilities:

  • Ability to query resources with complex filtering, grouping, and sorting by resource properties.
  • Ability to iteratively explore resources based on governance requirements and convert the resulting expression into a policy definition.
  • Ability to assess the impact of applying policies in a vast cloud environment.

What is Azure Resource Graph?

Azure Resource Manager sends data to a cache that exposes some information about resource (Resource name, ID, Type, Resource Group, Subscriptions, and Location). Normally we make calls to each resource provider and request these informations for each resource. It means not only much more calls to make but also a need to create a script which will handle that operation.

With Azure Resource Graph, we can access these informations directly, using complex query language we know, the Kusto query language.

How to use Azure Resource Graph?

To use Azure Resource Graph, you need at least Reader (RBAC) role on the resources you want to query.

To query Azure Resource Graph, you can use Azure CLI, PowerShell, SDK or REST API directly.

Sample queries

How much time we are saving?

In simple words, a lot. Let’s consider a simple scenario with just 10 VMs in just one subscription. If we want to summarize Operating Systems we are using Without Azure Resource Graph, we need to call Azure Resource Manager for all the resources with resource type like Microsoft.Compute/virtualMachines and then iterate all VMs for storageProfile.osDisk.osType property. In Azure CLI it will be something like that:

for id in `az resource list --resource-type 'Microsoft.Compute/virtualMachines' --query '[].id' -o tsv`; do az resource show --ids $id --query 'properties.storageProfile.osDisk.osType'; done | uniq -c

The uniq -c command at the end is summarizing every unique OS type. The output of this script for my subscription is:

  3 "Windows"
  7 "Linux"

and it took a little bit more than 11s to complete.

With Azure Resource Graph I used az graph query command with simple Kusto query:

az graph query -q "where type =~ 'Microsoft.Compute/virtualMachines' | summarize count() by tostring(properties.storageProfile.osDisk.osType)" -s xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

The output of this command is:

    "count_": 7,
    "properties_storageProfile_osDisk_osType": "Linux"
    "count_": 3,
    "properties_storageProfile_osDisk_osType": "Windows"

and it took around 1.5s to complete.

As you can see, in graph query I have limited query to just one subscription – it’s because Azure Resource Graph is returning results for all resources in all subscriptions we have access to. I have also noticed, that this rule is not true for subscriptions where we are external AAD users with RBAC roles – in that situation we are receiving “Access denied” message.


ESPC call for speakers 2024
The response schema for ARG query is different than resource query. As an example, let’s check a schema for query about a VM.


az vm show -g group -n VM0



az graph query -q "where type =~ 'Microsoft.Compute/virtualMachines'" -s xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx




"aliases": {

"Microsoft.Compute/imageId": null,

"Microsoft.Compute/imageOffer": "UbuntuServer",

"Microsoft.Compute/imagePublisher": "Canonical",

"Microsoft.Compute/imageSku": "16.04-LTS",

"Microsoft.Compute/imageVersion": "latest",

"Microsoft.Compute/licenseType": null,

"Microsoft.Compute/virtualMachines/availabilitySet.id": null,

"Microsoft.Compute/virtualMachines/diagnosticsProfile.bootDiagnostics": null,

"Microsoft.Compute/virtualMachines/diagnosticsProfile.bootDiagnostics.enabled": null,

"Microsoft.Compute/virtualMachines/diagnosticsProfile.bootDiagnostics.storageUri": null,

"Microsoft.Compute/virtualMachines/imageOffer": "UbuntuServer",

"Microsoft.Compute/virtualMachines/imagePublisher": "Canonical",

"Microsoft.Compute/virtualMachines/imageSku": "16.04-LTS",

"Microsoft.Compute/virtualMachines/imageVersion": "latest",

"Microsoft.Compute/virtualMachines/networkInterfaces[*].id": [



"Microsoft.Compute/virtualMachines/osDisk.Uri": null,

"Microsoft.Compute/virtualMachines/osProfile.adminPassword": null,

"Microsoft.Compute/virtualMachines/osProfile.adminUsername": "michal",

"Microsoft.Compute/virtualMachines/osProfile.linuxConfiguration": {

"disablePasswordAuthentication": false,

"provisionVMAgent": true


"Microsoft.Compute/virtualMachines/osProfile.linuxConfiguration.disablePasswordAuthentication": false,

"Microsoft.Compute/virtualMachines/osProfile.windowsConfiguration": null,

"Microsoft.Compute/virtualMachines/osProfile.windowsConfiguration.enableAutomaticUpdates": null,

"Microsoft.Compute/virtualMachines/osProfile.windowsConfiguration.provisionVMAgent": null,

"Microsoft.Compute/virtualMachines/sku.name": "Standard_B1S",

"Microsoft.Compute/virtualMachines/storageProfile.dataDisks[*].caching": [],

"Microsoft.Compute/virtualMachines/storageProfile.dataDisks[*].createOption": [],

"Microsoft.Compute/virtualMachines/storageProfile.dataDisks[*].diskSizeGB": [],

"Microsoft.Compute/virtualMachines/storageProfile.dataDisks[*].image.uri": [],

"Microsoft.Compute/virtualMachines/storageProfile.dataDisks[*].lun": [],

"Microsoft.Compute/virtualMachines/storageProfile.dataDisks[*].managedDisk.id": [],

"Microsoft.Compute/virtualMachines/storageProfile.dataDisks[*].managedDisk.storageAccountType": [],

"Microsoft.Compute/virtualMachines/storageProfile.dataDisks[*].name": [],

"Microsoft.Compute/virtualMachines/storageProfile.dataDisks[*].vhd.uri": [],

"Microsoft.Compute/virtualMachines/storageProfile.osDisk.caching": "ReadWrite",

"Microsoft.Compute/virtualMachines/storageProfile.osDisk.createOption": "FromImage",

"Microsoft.Compute/virtualMachines/storageProfile.osDisk.encryptionSettings": null,

"Microsoft.Compute/virtualMachines/storageProfile.osDisk.encryptionSettings.enabled": null,

"Microsoft.Compute/virtualMachines/storageProfile.osDisk.managedDisk.id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/group/providers/Microsoft.Compute/disks/VM0_OsDisk_1_0d164779e1744485866c496178a21c29",

"Microsoft.Compute/virtualMachines/storageProfile.osDisk.managedDisk.storageAccountType": "Premium_LRS",

"Microsoft.Compute/virtualMachines/storageProfile.osDisk.name": "VM0_OsDisk_1_0d164779e1744485866c496178a21c29",

"Microsoft.Compute/virtualMachines/storageProfile.osDisk.osType": "Linux",

"Microsoft.Compute/virtualMachines/storageProfile.osDisk.vhd": null,

"Microsoft.Compute/virtualMachines/storageProfile.osDisk.vhd.uri": null


"id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/group/providers/Microsoft.Compute/virtualMachines/VM0",

"identity": {},

"kind": "",

"location": "westeurope",

"managedBy": "",

"name": "VM0",

"plan": {},

"properties": {

"hardwareProfile": {

"vmSize": "Standard_B1S"


"networkProfile": {

"networkInterfaces": [


"id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/group/providers/Microsoft.Network/networkInterfaces/VM0VMNic",

"resourceGroup": "group"




"osProfile": {

"adminUsername": "michal",

"allowExtensionOperations": true,

"computerName": "VM0",

"linuxConfiguration": {

"disablePasswordAuthentication": false,

"provisionVMAgent": true


"secrets": []


"provisioningState": "Creating",

"storageProfile": {

"dataDisks": [],

"imageReference": {

"offer": "UbuntuServer",

"publisher": "Canonical",

"sku": "16.04-LTS",

"version": "latest"


"osDisk": {

"caching": "ReadWrite",

"createOption": "FromImage", [372/1998]

"diskSizeGB": 30,

"managedDisk": {

"id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/group/providers/Microsoft.Compute/disks/VM0_OsDisk_1_0d164779e1744485866c496178a21c29",

"resourceGroup": "group",

"storageAccountType": "Premium_LRS"


"name": "VM0_OsDisk_1_0d164779e1744485866c496178a21c29",

"osType": "Linux"



"vmId": "8bcf4237-ae09-4ea4-8fe5-eca6a4f442b5"


"resourceGroup": "group",

"sku": {},

"subscriptionId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",

"tags": {},

"type": "microsoft.compute/virtualmachines"



If you are wondering what Aliases are, check here.

About the Author:

Michal Smereczynski
Microsoft Azure MVP. Open Source Software and interoperability evangelist.


Smereczynski, M. (2018). Saving time with Azure Resource Graph. Available at: https://lnx.azurewebsites.net/saving-time-with-azure-resource-graph/ [Accessed 30 January 2019]

Share this on...

Rate this Post:


Join our Mailing List!

Join the ESPC mailing list to receive the best, free content from across the SharePoint, Office 365 & Azure community, including our monthly newsletter and the latest conference announcements. You can unsubscribe at any time with one click.
  • Sign up to receive exclusive content and analysis from the Microsoft 365 & Azure community, as well as the latest conference updates and offers. NOTE: This is for content only. You do not need to register for conference sessions.

  • Hidden
  • This field is for validation purposes and should be left unchanged.

Resource Centre Login - Content

Resource Centre Login - Content

  • Already a member? Simply Login

  • Become an ESPC Community Member today to access a wealth of SharePoint, Office 365 and Azure knowledge for free. New content is added daily to the online Resource Centre, across a variety of topics and formats from Microsoft MVP’s and industry experts. With over 2,500 eBooks, webinars, presentations, how to videos and blogs, there is something to suit everyone’s learning styles and career goals.

    (All Fields Required) ** Verification Email will be sent **
    Check your Spam/Junk/Clutter folder
  • ** Verification Email will be sent **
    Check your Spam/Junk/Clutter folder
  • This field is for validation purposes and should be left unchanged.

Scroll to top