Build Reports Faster with Azure Resource Graph
Published May 15 2023 11:00 PM 2,995 Views
Microsoft

Introduction

Hi folks! My name is Felipe Binotto, Cloud Solution Architect, based in Australia.

 

If you are hands-on with Azure operations, I’m sure at some point you have been asked to provide some type of report containing information about your Azure environment.

 

In the past, the only way to provide this information was to programmatically iterate through all your subscriptions and retrieve the data, subscription by subscription.

 

Throughout this article I will provide a couple examples on how you would accomplish that task in the traditional way compared to using the Azure Resource Graph. Moreover, I will provide the time it takes to accomplish each task using the Measure-Command cmdlet.

The examples provided here were executed across 200+ subscriptions.

 

Azure Resource Types

Let’s imagine someone asked you to retrieve all resource types that are deployed across your 200+ subscriptions.

 

One option would be to use the Az cmdlets and iterate through all your subscriptions, querying each subscription for its resource types and storing that information in an array and finally just getting the unique values.

 

The script code would look like the following:

 

 

 

    # Get all subscriptions
    $subscriptions = Get-AzSubscription | ? State -eq "Enabled"

    # Initialize an array to store the unique resource types
    $allResourceTypes = @()

    # Iterate through each subscription
    foreach ($subscription in $subscriptions) {

        # Set the current subscription context
        Set-AzContext -Subscription $subscription

        # Get all resource types in the current subscription
        $resourceTypes = (Get-AzResource).ResourceType | Select-Object -Unique

        # Add the unique resource types for each subscription to the array
        $allResourceTypes += $resourceTypes
    }
    # Get all unique resource types across all subscriptions
    $uniqueResourceTypes = $allResourceTypes | Sort-Object -Unique

 

 

 

Another option would be to query the Azure Resource Graph. The script code would look like the following:

 

 

 

$skipCount = 1000

do {
$query = @"

    Resources

    | summarize count() by type
    | project type
    | order by type asc
"@

# Execute the Resource Graph query
$result = Search-AzGraph -Query $query -First $skipCount -SkipToken $result.SkipToken
$allResults += $result

} while ($result.Count -eq $skipCount)

 

 

 

Tip: You can use the SkipToken switch for pagination when the query returns more records than the maximum allowed which is currently set at 1000. For more information on pagination, click HERE.

 

Great! Both scripts would return the same results. However, one is much faster than the other. Let’s look at how they compare.

The following is the time it takes to run the first script, the traditional way.

 

 

 

Days              : 0
Hours             : 0
Minutes           : 6
Seconds           : 54
Milliseconds      : 288
Ticks             : 4142886516
TotalDays         : 0.00479500754166667
TotalHours        : 0.115080181
TotalMinutes      : 6.90481086
TotalSeconds      : 414.2886516
TotalMilliseconds : 414288.6516

 

 

 

The following is the time it takes to run the second script using the Azure Resource Graph.

 

 

 

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 3
Milliseconds      : 105
Ticks             : 31057119
TotalDays         : 3.59457395833333E-05
TotalHours        : 0.00086269775
TotalMinutes      : 0.051761865
TotalSeconds      : 3.1057119
TotalMilliseconds : 3105.7119

 

 

 

Wow!! From almost 7 minutes to just 3 seconds! How good is that?

 

Azure VM Sizes

Now let’s look at another example. We will take the same approach. Use the traditional method and the Azure Resource Graph to retrieve all unique VM sizes across all 200+ subscriptions.

 

The following is the script using the traditional way. I’m also including the Measure-Command cmdlet so you know how to use it.

 

 

 

Measure-Command {

    # Get all subscriptions
    $subscriptions = Get-AzSubscription | ? State -eq "Enabled"
   
    # Initialize an array to store the unique resource types
    $allVmSizes = @()
   
    # Iterate through each subscription
    foreach ($subscription in $subscriptions) {
   
        # Set the current subscription context
        Set-AzContext -Subscription $subscription.Id
   
        # Get all resource types in the current subscription
        $vmSizes = (Get-AzVM | select -expand HardwareProfile).VmSize | select -unique
  
        # Add the unique resource types to the array
        $allVmSizes += $vmSizes
    }
    $uniqueVmSizes = $allVmSizes | Sort-Object -Unique
}

 

 

 

The following is the script using the Azure Resource Graph.

 

 

 

Measure-Command { do {

        $query = "where type =~ 'Microsoft.Compute/virtualMachines' | summarize by tostring(properties.hardwareProfile.vmSize)"
        $result = Search-AzGraph -Query $query -First $skipCount -SkipToken $result.SkipToken
        $allResults += $result.properties_hardwareProfile_vmSize

    } while ($result.Count -eq $skipCount)
}

 

 

 

Now let’s compare the time it takes to execute each of the scripts.

 

The following is the time it takes to run the first script, the traditional way.

 

 

 

Days              : 0
Hours             : 0
Minutes           : 8
Seconds           : 33
Milliseconds      : 10
Ticks             : 5130106388
TotalDays         : 0.00593762313425926
TotalHours        : 0.142502955222222
TotalMinutes      : 8.55017731333333
TotalSeconds      : 513.0106388
TotalMilliseconds : 513010.6388

 

 

 

The following is the time it takes to run the second script using the Azure Resource Graph.

 

 

 

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 1
Milliseconds      : 581
Ticks             : 15810843
TotalDays         : 1.82995868055556E-05
TotalHours        : 0.000439190083333333
TotalMinutes      : 0.026351405
TotalSeconds      : 1.5810843
TotalMilliseconds : 1581.0843

 

 

 

Again, using the Azure Resource Graph is much faster. 8 minutes and a half to run in the traditional way compared to an astonishing 1 second and a half using the Azure Resource Graph.

 

Conclusion

In conclusion, Azure Resource Graph is a service that allows you to query Azure resources using a variety of filtering and aggregation methods quickly and efficiently. It provides a unified and integrated view of all resources across multiple subscriptions, making it easier to manage and analyze large-scale Azure environments. With Azure Resource Graph, you can run complex queries across all Azure resources, obtain a comprehensive view of your environment, and quickly identify any issues or areas for optimization. Additionally, Resource Graph provides the ability to export query results to different formats, such as CSV or JSON, or to integrate with other Azure services like Azure Monitor and Azure Policy. Overall, Azure Resource Graph is a powerful tool that can help you to efficiently manage, monitor, and optimize your cloud infrastructure.

 

I hope this was informative to you and thanks for reading!

 

 

Disclaimer

The sample scripts are not supported under any Microsoft standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages.

 

Co-Authors
Version history
Last update:
‎May 18 2023 11:27 AM
Updated by: