Speeding up Azure PowerShell scripting with Azure Resource Graph

I was recently working with Azure Graph using the Az.ResourceGraph PowerShell module to query resources across our Azure tenant to test the speed compared to traditional Azure PowerShell scripts I’ve written in the past. Let’s just say I will never go back to traditional Azure PowerShell for scenarios where Azure Graph is an option moving forward!  My original Azure PowerShell script took several minutes to finish looping through all of the our subscriptions to finally output a full list of VMs in the tenant. Simply replacing this section of the script with an Azure Graph query reduced the run time to seconds! 

The script below takes a list of VM names and compares it to all VMs in the Azure Tenant, outputting the names that match. In this particular scenario, I was asked to audit for a list of SQL 2008 VMs to see if they were deployed in Azure. Using Search-AzGraph, I was able to gather this data in just a few seconds.

Whether or not the use case listed above is useful in your environment, the purpose of this post is to provide a reference which can be used to massively decrease run time for any Azure related scripting involving large Azure data sets or cross subscription queries.

Additionally, the script below includes a the necessary code to work around returned results limit imposed by Microsoft when using the Az.ResourceGraph PowerShell module. Search-AzGraph has a default returned results of 100 by default. This can be overridden using the -Limit parameter, which allows to increase the returned results to 1000 (the documentation says 5000 but this is incorrect). In researching a work around for this limitation, I came across this blog post which worked great to allow more than 1000 returned results (in my case 2900).  

Sample Script: (This is a sample script only and should only be used in a Test environment.)

[System.Collections.Arraylist]$vmList = @()
"N20-IT-MONTEST2"
"N20-IT-MONTEST3",
"N20-IT-MONTEST4",
"N20-IT-MONTEST5",
"N20-IT-MONTEST6"
)

$pageSize = 1000
$iteration = 0
$searchParams = @{Query = "where type =~ 'Microsoft.Compute/virtualMachines' | project name, id | order by name, id asc"
First = $pageSize
}

$allVms = do {
$iteration += 1
Write-Verbose "Iteration #$iteration" -Verbose
$vms = Search-AzGraph @searchParams
$searchParams.Skip += $vms.count
$vms
} while ($vms.Count -eq $pageSize)

[System.Collections.ArrayList]$finalList= @()
$allVms.ForEach({$obj = [PSCustomObject]@{VMName = $_.name};$finalList.Add($obj) | out-null})
$finalList = $finalList.Where({$_.VMName -ne $null)}
$finalList.ForEach({If ($_.VMName -in $vmList) {Write-Host $_.VMName -ForegroundColor Green}})

I think you’ll find that using Search-AzGraph to replace looping through subscriptions to query resources is a no-brainer moving forward. I’m looking forward to the addition of paging to the module and I will surely posting more about this in the future!

Leave a Reply

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

WordPress.com Logo

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

Google photo

You are commenting using your Google 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