My Practical Intro to Azure Resource Graph

The Azure Resource Graph is attractive to me for its ability to query Azure resources at scale. I find this relevant in situations where you are managing a large number of subscriptions, resource groups and resources. And you are in situations to analyze and report on them.

Without Azure Resource Graph, I would use Azure PowerShell to query for resources but you are usually within scope of a single subscription that you select for your context.

For example,

Select-AzureRmSubscription -Subscription "App Service"
Get-AzureRmContext | format-table -AutoSize
Get-AzureRmResourceGroup | ft -AutoSize

But what if you want to query for resources across all our subscriptions? This is where Azure Resource Graph can help.

Azure Resource Graph as defined as follows:

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 features:

  • 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.

For starters, this is most basic query to get all resources:

Search-AzureRmGraph -Query “” | Out-GridView

Returns an interactive grid to filter and sort the output.

The query result schema

The property names that are returned from the query are

  • Id
  • sku
  • name
  • type
  • kind
  • plan
  • tags
  • aliases
  • location
  • properties
  • resourceGroup
  • subscrionId
  • managedBy
  • identity
  • tenantId
  • ResourceId

Let’s look at the properties which contain the system and user settings of the resource.

Search-AzureRmGraph -Query "where type =~ 'Microsoft.Web/sites' | limit 1" | ConvertTo-Json
    "type":  "microsoft.web/sites",
    "id":  "/subscriptions/xxxxxxxxxx-37db-4f9e-99b0-dc0f00cd8be3/resourceGroups/Default
    "sku":  {

    "name":  "mvc",
    "kind":  "app",
    "plan":  {

    "tags":  {
esourceGroups/Default-Web-EastUS/providers/Microsoft.Web/serverfarms/Default0":  "Reso
    "aliases":  {
                    "Microsoft.Web/sites/hostNameSslStates[*].sslState":  [
                    "Microsoft.Web/sites/clientCertEnabled":  false,
                    "Microsoft.Web/sites/availabilityState":  "Normal",
                    "Microsoft.Web/sites/hostNames[*]":  [
                    "Microsoft.Web/sites/serverFarmId":  "/subscriptions/xxxxxxxxxx-37db
                    "Microsoft.Web/sites/usageState":  "Normal",
                    "Microsoft.Web/sites/httpsOnly":  false
    "location":  "eastus",
    "properties":  {
                       "name":  "mvc",
                       "hostingEnvironmentProfile":  null,
                       "enabled":  true,
                       "hostingEnvironmentId":  null,
                       "hostingEnvironment":  null,
                       "state":  "Stopped",
                       "domainVerificationIdentifiers":  null,
                       "functionExecutionUnitsCache":  null,
                       "possibleOutboundIpAddresses":  ",,168.
                       "storageRecoveryDefaultState":  "Running",
                       "runtimeAvailabilityState":  "Normal",
                       "contentAvailabilityState":  "Normal",
                       "trafficManagerHostNames":  null,
                       "resourceGroup":  "Default-Web-EastUS",
                       "serverFarmId":  "/subscriptions/xxxxxxxxxx-37db-4f9e-99b0-dc0f00
                       "clientAffinityEnabled":  true,
                       "dailyMemoryTimeQuota":  0,
                       "lastModifiedTimeUtc":  "\/Date(1548064316783)\/",
                       "outboundIpAddresses":  ",,
                       "computeMode":  null,
                       "siteDisabledReason":  0,
                       "scmSiteAlsoStopped":  false,
                       "repositorySiteName":  "mvc",
                       "maxNumberOfWorkers":  null,
                       "clientCertEnabled":  false,
                       "hostNameSslStates":  [
                                                 "@{; toU
pdateIpBasedSsl=; ipBasedSslResult=; ipBasedSslState=NotConfigured; thumbprint=; virtu
alIP=; sslState=Disabled; toUpdate=; hostType=Standard}",
 toUpdateIpBasedSsl=; ipBasedSslResult=; ipBasedSslState=NotConfigured; thumbprint=; v
irtualIP=; sslState=Disabled; toUpdate=; hostType=Repository}"
                       "availabilityState":  "Normal",
                       "hostNamesDisabled":  false,
                       "enabledHostNames":  [
                       "sslCertificates":  null,
                       "defaultHostName":  "",
                       "deploymentId":  "mvc",
                       "kind":  "app",
                       "webSpace":  "eastuswebspace",
                       "targetSwapSlot":  null,
                       "slotSwapStatus":  null,
                       "siteProperties":  {
                                              "properties":  " ",
                                              "metadata":  null,
                                              "appSettings":  null
                       "siteMode":  null,
                       "reserved":  false,
                       "containerSize":  0,
                       "suspendedTill":  null,
                       "adminEnabled":  true,
                       "isXenon":  false,
                       "cloningInfo":  null,
                       "hostNames":  [
                       "sku":  "Shared",
                       "siteConfig":  null,
                       "serverFarm":  null,
                       "usageState":  "Normal",
                       "hyperV":  false,
                       "selfLink":  "https://waws-prod-blu-001.api.azurewebsites.windo
                       "httpsOnly":  false,
                       "tags":  {
s/Default0":  "Resource"
                       "owner":  null,
                       "cers":  null,
                       "csrs":  [

    "resourceGroup":  "default-web-eastus",
    "subscriptionId":  "xxxxxxxxxx-37db-4f9e-99b0-dc0f00cd8be3",
    "managedBy":  "",
    "identity":  {

    "tenantId":  "d4697920-75d5-4b07-bdbb-ca7abb88444d",
    "ResourceId":  "/subscriptions/xxxxxxxxxx-37db-4f9e-99b0-dc0f00cd8be3/resourceGroups

Using ARM Resource explorer at, you can compare and analyze the properties values. I find it easier at times to browse between azure resources and their properties with this tool.

Search-AzureRmGraph -Query "where type =~ 'Microsoft.Web/sites' and properties.state=='Stopped' |project name, type, location, subscriptionId, resourceGroup"

Now we see several azure web sites in stopped status across two different subscriptions. And the query is quite fast.

By applying this type of query for virtual machines, storage accounts, VNets, NSGs, etc for Azure tenants with a very large amount of subscriptions then Azure Resource Graph becomes your friend.

Online Resources:

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s