The Power of Azure Resource Graph

Quite often, I get a request to share Azure resource data to different teams. I am a great fan of Azure PowerShell and REST API. However, Azure Resource Graph using Kusto Query Language (KQL) is super awesome for this purpose. In this blog post, let me walk you through a few real-world queries I used at my workplace.

Prerequisites

  1. Azure Account
  2. PowerShell
  3. Az.ResourceGraph (PowerShell Module)

Retrieve Unattached Disk

$Query = "Resources
            | where type =~ 'Microsoft.Compute/disks'
            | where properties.diskState =~ 'Unattached'
            | project id, name, subscriptionId, resourceGroup, diskInGB = properties.diskSizeGB, diskState = properties.diskState, timeCreated = properties.timeCreated" 
$pageSize = 5000
$iteration = 0
$searchParams = @{
    Query = $($Query)
    First = $pageSize
}
[System.Collections.ArrayList]$results = @()
do {
    $iteration += 1
    $pageResults = Search-AzGraph @searchParams -Verbose
    $searchParams.Skip += $pageResults.Count
    $results.AddRange($pageResults)
} while ($pageResults.Count -eq $pageSize)
Azure Resource Graph

Retrieve All Virtual Machines (With IP Information)

$Query = 'Resources
            | where type == "microsoft.compute/virtualmachines"
            | extend hostName = properties.osProfile.computerName
            | mvexpand nic = properties.networkProfile.networkInterfaces
            | extend nicId = tostring(nic.id)
            | project subscriptionId, vmName = name, resourceGroup, location, nicId, hostName
            | join kind=leftouter (
           Resources
                | where type == "microsoft.network/networkinterfaces"
                | mvexpand ipconfig=properties.ipConfigurations
                | extend privateIp = ipconfig.properties.privateIPAddress
                | project nicId = id, privateIp) on nicId
                | project-away nicId1
                | project subscriptionId, vmName, resourceGroup, location, privateIp, hostName' 
$pageSize = 5000
$iteration = 0
$searchParams = @{
    Query = $($Query)
    First = $pageSize
}
[System.Collections.ArrayList]$results = @()
do {
    $iteration += 1
    $pageResults = Search-AzGraph @searchParams -Verbose
    $searchParams.Skip += $pageResults.Count
    $results.AddRange($pageResults)
} while ($pageResults.Count -eq $pageSize)
Azure Resource Graph

Check the performance

The below snippet is to list the Virtual Machine information

$VirtualMachines = Get-AzVM
foreach($VirtualMachine in $VirtualMachines)
{
    $VirtualMachine
}
Azure Resource Graph

Here is using the Resource Graph Query

$Query = "Resources | where type =~ 'microsoft.compute/virtualMachines'"
$pageSize = 5000
$iteration = 0
$searchParams = @{
    Query = $($Query)
    First = $pageSize
}
[System.Collections.ArrayList]$results = @()
do {
    $iteration += 1
    $pageResults = Search-AzGraph @searchParams -Verbose
    $searchParams.Skip += $pageResults.Count
    $results.AddRange($pageResults)
} while ($pageResults.Count -eq $pageSize)
Azure Resource Graph
PowerShell Resource Graph (KQL)
Days             : 0
Hours             : 0
Minutes         : 0
Seconds        : 8
Milliseconds      : 303
Ticks             : 83035985
TotalDays        : 9.61064641203704E-05
TotalHours        : 0.00230655513888889
TotalMinutes      : 0.138393308333333 TotalSeconds      : 8.3035985
TotalMilliseconds : 8303.5985
Days               : 0
Hours              : 0
Minutes            : 0
Seconds           : 3
Milliseconds   : 34
Ticks              : 30341366
TotalDays         : 3.51173217592593E-05
TotalHours        : 0.000842815722222222
TotalMinutes      : 0.0505689433333333 TotalSeconds      : 3.0341366
TotalMilliseconds: 3034.1366    

Summary

5 seconds of difference is an enormous difference. Because it is for one subscription with 200+ VM’s imagine if we have 100+ subscriptions. Try out the Azure Resource Graph and Kusto and get your reporting on time. In my next blog post, let me share some additional real-world examples.

About the Author Chendra Venkatesan