All scripts
Azure AI 464

Get-AzureVMExtensionInventory

Lists every VM extension installed across all VMs in the subscription with its provisioning state, so failed or outdated extensions get caught during a health review.

Get-AzureVMExtensionInventory.ps1
<#
.SYNOPSIS
    Inventories VM extensions across the subscription.

.DESCRIPTION
    Lists every extension installed on every VM along with its
    provisioning state and type handler version, so failed or outdated
    extensions (monitoring agents, disk encryption, custom scripts)
    stand out during a health review.

.EXAMPLE
    .\Get-AzureVMExtensionInventory.ps1

.NOTES
    Requires the Az.Compute module and an active Connect-AzAccount session.

.AUTHOR
    Shehryar Hassan
#>

$vms = Get-AzVM

$report = foreach ($vm in $vms) {
    $extensions = Get-AzVMExtension -ResourceGroupName $vm.ResourceGroupName -VMName $vm.Name
    foreach ($ext in $extensions) {
        [pscustomobject]@{
            VMName    = $vm.Name
            Extension = $ext.Name
            Type      = $ext.ExtensionType
            Version   = $ext.TypeHandlerVersion
            State     = $ext.ProvisioningState
        }
    }
}

$report | Where-Object { $_.State -ne "Succeeded" } | Format-Table -AutoSize
Write-Host "$($report.Count) total extension(s) across $($vms.Count) VM(s)" -ForegroundColor Cyan

Read it before you run it, and test in a safe tenant first.