Show-AzVMQuotaReport.ps1
Single-threaded Azure VM quota reporting script that provides streamlined quota analysis for smaller deployments or learning scenarios.
Overview
This PowerShell script offers a simplified approach to Azure VM quota analysis. Unlike its multi-threaded counterpart, it processes subscriptions sequentially and displays results in a formatted table, making it ideal for smaller estates or when you're learning how Azure quota management works.
Key capabilities
- Sequential processing: Straightforward single-threaded execution for easier debugging
- Formatted output: Displays results in a clean table format at completion
- Zone restriction detection: Identifies which availability zones are restricted for specific VM SKUs
- Physical zone mapping: Optional mapping of logical to physical zones for cross-subscription planning
- Educational design: Simpler code structure for understanding quota analysis patterns
When to use this script
- Learning Azure quota management concepts
- Analyzing smaller subscription counts (< 10 subscriptions)
- Debugging quota issues with verbose output
- Quick ad-hoc quota checks for specific SKUs/regions
- Teaching quota analysis patterns to new team members
Comparison with Get-AzVMQuotaUsage.ps1
| Feature | Show-AzVMQuotaReport | Get-AzVMQuotaUsage |
|---|---|---|
| Threading | Single-threaded | Multi-threaded (configurable) |
| Best for | < 10 subscriptions | 100+ subscriptions |
| Performance | Sequential | Parallel processing |
| Code complexity | Simpler | Production-optimized |
| Output format | Table + CSV | CSV only |
| Use case | Learning/debugging | Production analysis |
Prerequisites
# Install Azure PowerShell module
Install-Module -Name Az -Repository PSGallery -Force
# Authenticate to Azure
Connect-AzAccount
# Verify subscription access
Get-AzSubscription | Select-Object Name, Id, State
# Check Reader permissions
Get-AzRoleAssignment | Where-Object {$_.RoleDefinitionName -like "*Reader*"}
Parameters
| Parameter | Type | Description | Default |
|---|---|---|---|
| SKUs | String[] | Array of VM SKU names to analyze | Downloads all SKUs |
| Locations | String[] | Array of Azure regions to query | All regions |
| SubscriptionIds | String[] | Array of subscription IDs to analyze | All accessible subscriptions |
| OutputFile | String | CSV output filename | QuotaQuery.csv |
| UsePhysicalZones | Switch | Map logical zones to physical datacenters | False |
| MeterDataUri | String | URL for VM SKU metadata | Azure public data |
Usage examples
Basic quota check for specific SKUs
.\Show-AzVMQuotaReport.ps1 -SKUs @('Standard_D2s_v5', 'Standard_E4s_v5') -Locations @('eastus', 'westus2')
Analyze specific subscriptions with physical zone mapping
.\Show-AzVMQuotaReport.ps1 `
-SubscriptionIds @('sub1-guid', 'sub2-guid') `
-UsePhysicalZones `
-OutputFile "DevSubscriptionQuota.csv"
Quick quota audit for a single region
.\Show-AzVMQuotaReport.ps1 `
-SKUs @('Standard_D4s_v5') `
-Locations @('eastus') `
-OutputFile "EastUSQuotaCheck_$(Get-Date -Format 'yyyyMMdd').csv"
Full analysis with all defaults
.\Show-AzVMQuotaReport.ps1 -OutputFile "CompleteQuotaAnalysis.csv"
Sample output
Running the script produces both console output and a CSV file:
Console output
Downloading VM SKU Details
Listing Subscriptions
Processing subscription: Development (12345678-abcd-1234-5678-123456789012)
Analyzing location: eastus
Checking SKU: Standard_D2s_v5
Checking SKU: Standard_E4s_v5
Analyzing location: westus2
Checking SKU: Standard_D2s_v5
Checking SKU: Standard_E4s_v5
Results saved to: QuotaQuery.csv
Summary Table:
Subscription Location SKU CoresUsed/Total Zones Available
------------ -------- --------------- --------------- ---------------
Development eastus Standard_D2s_v5 8/100 1,2,3
Development eastus Standard_E4s_v5 0/100 1,2,3
Development westus2 Standard_D2s_v5 4/100 1,2,3
Development westus2 Standard_E4s_v5 16/100 1,2,3
CSV output
TenantId,SubscriptionId,SubscriptionName,Location,Family,Size,RegionRestricted,ZonesPresent,ZonesRestricted,CoresUsed,CoresTotal
12345678-1234-1234-1234-123456789012,abcd1234-5678-90ab-cdef-123456789012,Development,eastus,standardDSv5Family,Standard_D2s_v5,False,"1,2,3",,8,100
12345678-1234-1234-1234-123456789012,abcd1234-5678-90ab-cdef-123456789012,Development,eastus,standardESv5Family,Standard_E4s_v5,False,"1,2,3",,0,100
12345678-1234-1234-1234-123456789012,abcd1234-5678-90ab-cdef-123456789012,Development,westus2,standardDSv5Family,Standard_D2s_v5,False,"1,2,3",,4,100
12345678-1234-1234-1234-123456789012,abcd1234-5678-90ab-cdef-123456789012,Development,westus2,standardESv5Family,Standard_E4s_v5,False,"1,2,3",,16,100
Understanding the output
- TenantId: Azure AD tenant identifier
- SubscriptionId: Unique subscription identifier
- SubscriptionName: Friendly subscription name
- Location: Azure region
- Family: VM family for quota calculation
- Size: Specific VM SKU
- RegionRestricted: Whether the SKU has regional restrictions
- ZonesPresent: Available availability zones
- ZonesRestricted: Zones requiring enablement request
- CoresUsed: Current vCPU consumption
- CoresTotal: Total vCPU quota limit
Troubleshooting
Script runs slowly
This is expected behavior for the single-threaded version. For faster processing:
# Use the multi-threaded version instead
.\Get-AzVMQuotaUsage.ps1 -Threads 4
No SKU data returned
# Verify the region supports the SKU
Get-AzComputeResourceSku -Location 'eastus' |
Where-Object {$_.Name -eq 'Standard_D2s_v5'}
# Check if meter data download succeeded
Test-Path "AutofitComboMeterData.csv"
Authentication errors
# Clear and re-authenticate
Clear-AzContext -Force
Connect-AzAccount -Tenant 'your-tenant-id'
# Verify current context
Get-AzContext | Select-Object Account, Subscription, Tenant
Empty zones data
# Some regions don't support availability zones
Get-AzLocation | Where-Object Location -eq 'westus' |
Select-Object -ExpandProperty Zones
# If empty, the region doesn't support zones
Educational value
This script serves as a learning tool for understanding:
- How Azure organizes quota by VM family
- The relationship between logical and physical zones
- Sequential API interaction patterns
- CSV export for further analysis
For production use with large subscription counts, use Get-AzVMQuotaUsage.ps1 which provides:
- Parallel processing for 10x faster execution
- Configurable thread counts
- Better error handling for large-scale analysis
Performance comparison
| Subscriptions | Show-AzVMQuotaReport | Get-AzVMQuotaUsage (4 threads) |
|---|---|---|
| 5 | ~2 minutes | ~30 seconds |
| 25 | ~10 minutes | ~3 minutes |
| 100 | ~40 minutes | ~10 minutes |
Script source
Related scripts
- Get-AzVMQuotaUsage.ps1 - Multi-threaded version for production use
- Get-AzAvailabilityZoneMapping.ps1 - Dedicated zone mapping analysis