LEEEJEFFRIES.COM

Checking prices for azure VMs with PowerShell

 | #azure,#powershell

pricingimage

If you are trying to add VM pricing into any of your PowerShell scripts or modules, here are a couple of PowerShell functions that will help.

PowerShell:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
 
Function Get-AzureVMPrice {
    [CmdletBinding()]

    Param
    (
        [Parameter(ValueFromPipeline,HelpMessage='The VM Sku to get prices for',Mandatory=$true)]
        [string]$vmSku,
        [Parameter(HelpMessage='The currency to report back',Mandatory=$true)]
        [string]$currencyCode,
        [Parameter(HelpMessage='Azure region to get prices for',Mandatory=$true)]
        [string]$region
    )

    #Setup parameters
    $Parameters = @{
        currencyCode = $currencyCode
        '$filter' = "serviceName eq 'Virtual Machines' and armSkuName eq `'$vmSku`' and armRegionName eq `'$region`' and type eq 'Consumption'"
    }

    #Make a web request for the prices
    try {
        $request = Invoke-WebRequest -UseBasicParsing -Uri "https://prices.azure.com/api/retail/prices" -Body $Parameters -Method Get
        $result = $request.Content | ConvertFrom-JSON | Select-Object -ExpandProperty Items | Sort-Object effectiveStartDate -Descending | Select -First 1

        $vmPrice = [PSCustomObject]@{
                    SKUName = $($result.armSkuName) 
                    Region = $($result.armRegionName) 
                    Currency = $($result.currencyCode)
                    Product_Name = $($result.productName)
                    Price_Per_Minute = if ($($result.unitOfMeasure) -match 'Hour') {$($result.retailPrice)/60 } else { 0 }
                    Price_Per_Hour = if ($($result.unitOfMeasure) -match 'Hour') { $($result.retailPrice) } else { 0 }
                    Price_Per_Day = if ($($result.unitOfMeasure) -match 'Hour') { $($result.retailPrice) * 24 } else { 0 }
                }
        
        if ([string]::IsNullOrEmpty($vmPrice.SKUName)) {
            Throw
        } else {
            Return $vmPrice
        }

    } catch {
        Write-Error "Error processing request, check the SKU and region are valid"
        Write-Error $_
    }
}

Function Get-AzureVMSKUs {
    [CmdletBinding()]

    Param
    (
        [Parameter(HelpMessage='Azure region to get prices for',Mandatory=$true)]
        [string]$region
    )

    #Setup parameters
    $Parameters = @{
        currencyCode = $currencyCode
        '$filter' = "serviceName eq 'Virtual Machines' and  armRegionName eq `'$region`' and type eq 'Consumption'"
    }

    #Make a web request for the prices
    try {
        $request = Invoke-WebRequest -UseBasicParsing -Uri "https://prices.azure.com/api/retail/prices" -Body $Parameters -Method Get
        $result = $request.Content | ConvertFrom-JSON | Select-Object -ExpandProperty Items | Select-Object armSkuName

        $SKUs = foreach ($item in $result) {
            $item.armSkuName
        }

        Return $SKUs | Select-Object -Unique | Sort-Object
    } catch {
        Write-Error "Error processing request, check the region and currency are valid"
        Write-Error $_
    }
}

There are two functions here, they can be configured to feed into each other, we’ll take a look at that. Add the functions to your existing scripts or run the above script, this will load the Functions into memory. The two functions can be called independently and also chained together.

  • Get-AzureVMSKUs - Gets a list of all Azure VM SKUs in a region
  • Get-AzureVMPrice - Gets a price for a given VM SKU
1
2
3
4
5
6
7
8
9
10
Get-AzureVMSKUs -region uksouth

Basic_A1
Basic_A2
Basic_A3               Basic_A4                                                                                                                                                                            Dasv4_Type1
Dasv4_Type2
DCsv2 Type 1
Ddsv4_Type 1
Eadsv5_Type1
.........

This gets a list of all VM SKUs in the uksouth region.

1
2
3
4
5
6
7
8
9
Get-AzureVMPrice -vmSku Standard_D2_v2 -region uksouth -currencyCode GBP

SKUName          : Standard_D2_v2
Region           : uksouth
Currency         : GBP
Product_Name     : Virtual Machines Dv2 Series
Price_Per_Minute : 0.0002583333333333333333333333
Price_Per_Hour   : 0.0155
Price_Per_Day    : 0.3720

This will generate pricing information for a Standard_D2_v2 VM running in the UK South region in the currency of GBP.

You can chain these Functions together to make it interactive to select a VM SKU and get a price using Out-GridView.

1
2
3
4
5
6
7
Get-AzureVMSKUs -region uksouth | Out-GridView -PassThru | Get-AzureVMPrice -currencyCode GBP -region uksouth

SKUName          : Basic_A4Region           : uksouthCurrency         : GBP
Product_Name     : Virtual Machines A Series Basic Windows
Price_Per_Minute : 0.00613
Price_Per_Hour   : 0.3678
Price_Per_Day    : 8.8272

You can see below, I selected the Basic_A4 SKU and above; the pricing information.

pricingimage

I hope someone else finds this useful.

About Me

Photo of Leee Jeffries

I'm an IT professional with over 15 years of experience in the IT industry, I've worked in many fields in my career. This blog is to share my experience, tips and tricks.