Azure Azure Compute Azure PowerShell

Using an Azure PowerShell script to list and export Azure VM SKUs by region with minimum NICs




In this blog post, you’ll learn how to use an Azure PowerShell script to list and export Azure VM SKUs by region, with a specified minimum number of network interfaces (NICs), into a .CSV file.

From time to time, I’m approached by customers or community members asking if there’s a simple way to list all Azure virtual machine (VM) SKUs available in a specific region, with specific capabilities, such as the maximum number of disks allowed.

Just recently, I received another similar question, this time regarding the minimum number of network interfaces (NICs) that can be configured for an Azure VM from a specific region.

Since I received this question again and because I’m quite familiar with using Azure PowerShell for various management and operational tasks, I decided to write a script to handle it.

This Azure PowerShell script, does all of the following:

  • Remove the breaking change warning messages.
  • Import the Az.Compute module if it is not already imported.
  • Validate if the provided region is a valid Azure region, otherwise exit the script.
  • Create the C:\Temp folder if it does not exist.
  • List VM SKUs with the specified value or more network interfaces in the specified region.
  • Export the filtered SKUs to a CSV file without including type information.
  • Open the CSV file.


To use the script, start by saving a copy as “List-and-Export-VM-SKUs-in-region-with-minimum-number-of-NICs.ps1” or downloading it directly from GitHub. Adjust all variables to meet your specific needs, and if necessary, then run the script using Windows Terminal, Visual Studio Code, or Windows PowerShell.

Before running the script, make sure to sign in with the Connect-AzAccount cmdlet to link your Azure account. If you have multiple Azure tenants, use the Set-AzContext -tenantID cmdlet to select the correct tenant before executing the script.


You can then run the script, with the required parameters.

.\List-and-Export-VM-SKUs-in-region-with-minimum-number-of-NICs.ps1 -region <"Azure region here>" -minNics <"minimum number of NICs here>"



<#
.SYNOPSIS

A script used to list and export VM SKUs in a specified region that supports a specified minimum number of NICs.

.DESCRIPTION

A script used to list and export VM SKUs in a specified region that supports a specified minimum number of NICs.
The script will do all of the following:

Remove the breaking change warning messages.
Import the Az.Compute module if it is not already imported.
Validate if the provided region is a valid Azure region, otherwise exit the script
Create the C:\Temp folder if it does not exist.
List VM SKUs with the specified value or more network interfaces in the specified region.
Export the filtered SKUs to a CSV file without including type information.
Open the CSV file.

.NOTES

Filename:       List-and-Export-VM-SKUs-in-region-with-minimum-number-of-NICs.ps1
Created:        23/05/2024
Last modified:  23/05/2024
Author:         Wim Matthyssen
Version:        1.0
PowerShell:     Azure PowerShell and Azure Cloud Shell
Requires:       PowerShell Az (v10.4.1) 
Action:         Change variables where needed to fit your needs. 
Disclaimer:     This script is provided "as is" with no warranties.

.EXAMPLE

Connect-AzAccount
Get-AzTenant (if not using the default tenant)
Set-AzContext -tenantID "xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx" (if not using the default tenant)
.\List-and-Export-VM-SKUs-in-region-with-minimum-number-of-NICs.ps1 -region <"Azure region here>" -minNics <"minimum number of NICs here>"

-> .\List-and-Export-VM-SKUs-in-region-with-minimum-number-of-NICs.ps1 -region westeurope -minNics 3

.LINK

#>

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Parameters

param(
    # $region -> Name of Azure region
    [parameter(Mandatory =$true)][ValidateNotNullOrEmpty()] [string] $region,
    # $minNics -> Minimum number of network interfaces
    [parameter(Mandatory =$true)] [ValidateNotNullOrEmpty()] [ValidateRange(1,8)] [int] $minNics
)

## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Variables

$driveLetter = "C:"
$tempFolderName = "Temp"
$tempFolderPath = Join-Path -Path $driveLetter -ChildPath $tempFolderName
$itemType = "Directory"
$csvFileName = "VM_SKUs.csv"

$global:currenttime= Set-PSBreakpoint -Variable currenttime -Mode Read -Action {$global:currenttime= Get-Date -UFormat "%A %m/%d/%Y %R"}
$foregroundColor1 = "Green"
$foregroundColor2 = "Yellow"
$writeEmptyLine = "`n"
$writeSeperatorSpaces = " - "

# ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Remove the breaking change warning messages
 
Set-Item -Path Env:\SuppressAzurePowerShellBreakingChangeWarnings -Value $true | Out-Null
Update-AzConfig -DisplayBreakingChangeWarning $false | Out-Null
$warningPreference = "SilentlyContinue"

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Write script started

Write-Host ($writeEmptyLine + "# Script started. Without errors, it can take up to 1 minutes to complete" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine 

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Import the Az.Compute module if it is not already imported

if (-not (Get-Module -Name Az.Compute)) {
    Import-Module Az.Compute
}

Write-Host ($writeEmptyLine + "# Az.compute module available" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine 

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Validate if the provided region is a valid Azure region, otherwise exit the script

# Define a list of valid Azure regions
$validRegions = @(
    "eastus", "eastus2", "centralus", "northcentralus", "southcentralus", 
    "westus", "westus2", "westus3", "canadacentral", "canadaeast", 
    "brazilsouth", "brazilsoutheast", "northeurope", "westeurope", 
    "francecentral", "francesouth", "uksouth", "ukwest", 
    "germanynorth", "germanywestcentral", "norwayeast", "norwaywest", 
    "switzerlandnorth", "switzerlandwest", "italynorth", "italynorth2", 
    "eastasia", "southeastasia", "australiaeast", "australiasoutheast", 
    "australiacentral", "australiacentral2", "chinaeast", "chinanorth", 
    "chinaeast2", "chinanorth2", "centralindia", "southindia", "westindia", 
    "japaneast", "japanwest", "koreacentral", "koreasouth", 
    "southafricanorth", "southafricawest", "uaenorth", "uaecentral", 
    "israelcentral", "saudiarabiawest", "saudiarabiaeast"
)

# Check if the provided region is valid
if ($region -notin $validRegions) {
    Write-Host ($writeEmptyLine + "# The provided region $region is not a valid Azure region. Please provide a valid Azure region." + $writeSeperatorSpaces + $currentTime)`
    -foregroundcolor $foregroundColor2 $writeEmptyLine
    exit
}

Write-Host ($writeEmptyLine + "# Specified region $region is a valid Azure region" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine 

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Create the C:\Temp folder if not exists

If(!(Test-Path $tempFolderPath))
{
    New-Item -Path $driveLetter -Name $folderName -ItemType $itemType -Force | Out-Null
}

Write-Host ($writeEmptyLine + "# $tempFolderName folder available under the C: drive" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## List VM SKUs with the specified value or more network interfaces in the specified region

# Get all compute resource SKUs
$allSkus = Get-AzComputeResourceSku 

# Filter SKUs based on location, resource type, and network interface capabilities
$filteredSkus = $allSkus | Where-Object {
    $_.Locations.Contains($region) -and 
    $_.ResourceType -eq "virtualMachines" -and 
    $_.Capabilities.Where({
        $_.Name -eq "MaxNetworkInterfaces" -and 
        [int]$_.Value -ge $minNics
    })
}

# Create custom objects for each filtered SKU
$customObjects = $filteredSkus | ForEach-Object {
    $maxNics = $_.Capabilities | 
               Where-Object {$_.Name -eq "MaxNetworkInterfaces"} | 
               Select-Object -ExpandProperty Value

    # Structure the data in the CSV file with the required columns Name, Tier, Size, and MaxNetworkInterfaces
    [PSCustomObject]@{
        'Name' = $_.Name
        'Tier' = $_.Tier
        'Size' = $_.Size
        'MaxNetworkInterfaces' = $maxNics
    }
}

# Export the filtered SKUs to a CSV file without including type information
$customObjects | Export-Csv -Path C:\Temp\VM_SKUs.csv -NoTypeInformation

Write-Host ($writeEmptyLine + "# CSV file $csvFileName created" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine 

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Open the CSV file

# Combine the directory path and the filename into a full path
$fullPath = Join-Path -Path $tempFolderPath -ChildPath $csvFileName

Invoke-Item $fullPath

Write-Host ($writeEmptyLine + "# CSV file $csvFileName opened" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine 

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Write script completed

Write-Host ($writeEmptyLine + "# Script completed" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine 

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------







Conclusion

Using Azure PowerShell makes it simple to find and list all Azure VM SKUs in a specific Azure region with specific capabilities.

I hope the Azure PowerShell script explained and shared in this blog post will assist you in quickly listing and exporting all available Azure VM SKUs by region with minimum NICs into a human-readable .CSV file.

Should you have any questions or suggestions regarding this blog post or the script, please don’t hesitate to reach out to me via my X handle (@wmatthyssen) or leave a comment. I’ll be more than happy to assist you.


Unknown's avatar

Wim is an Azure Technical Advisor and Trainer with over fifteen years of Microsoft technology experience. As a Microsoft Certified Trainer (MCT), his strength is assisting companies in the transformation of their businesses to the Cloud by implementing the latest features, services, and solutions. Currently, his main focus is on the Microsoft Hybrid Cloud Platform, and especially on Microsoft Azure and the Azure hybrid services.   Wim is also a Microsoft MVP in the Azure category and a founding board member of the MC2MC user group. As a passionate community member, he regularly writes blogs and speaks about his daily experiences with Azure and other Microsoft technologies.