Created
November 2, 2020 01:45
-
-
Save JustinGrote/17341170ba16347ee24d5953ff3a33db to your computer and use it in GitHub Desktop.
Azure Retail Pricing API Proof of Concept
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Get-AzSpotPrice { | |
[CmdletBinding()] | |
param ( | |
#VM SKU (e.g. Standard_F8s) | |
[String]$Sku, | |
#Azure Region (e.g. brazilsouth) | |
[String]$Region, | |
#ODATA filter to use on the data | |
[String]$Filter, | |
#Maximum number of records to retrieve, or specify 'Unlimited' for all records. Defaults to 100. This behaves like the Exchange Cmdlets | |
[String]$ResultSize, | |
#Path to the prices API. You usually do not need to specify this. | |
[UriBuilder]$Uri = 'https://prices.azure.com/api/retail/prices' | |
) | |
$SpotFilter = @("contains(skuName,'Spot')") | |
if ($Filter) { | |
$SpotFilter += $Filter | |
} | |
if ($Region) { | |
$SpotFilter += $Region.foreach{ | |
"armRegionName eq '$PSItem'" | |
} | |
} | |
if ($Sku) { | |
$SpotFilter += $Sku.foreach{ | |
"armSkuName eq '$PSItem'" | |
} | |
} | |
$queryFilter = $SpotFilter -join ' and ' | |
$AzRetailPriceParams = @{ | |
Filter = $QueryFilter | |
} | |
if ($ResultSize) {$AzRetailPriceParams.ResultSize = $ResultSize} | |
Get-AzRetailPrice @AzRetailPriceParams | |
} | |
function Get-AzRetailPrice { | |
[CmdletBinding()] | |
param( | |
#ODATA filter to use on the data | |
[String]$Filter, | |
#Maximum number of records to retrieve, or specify 'Unlimited' for all records. Defaults to 100. This behaves like the Exchange Cmdlets | |
[String]$ResultSize, | |
#Path to the prices API. You usually do not need to specify this. | |
[UriBuilder]$Uri = 'https://prices.azure.com/api/retail/prices' | |
) | |
#The query builder object has to be initialized indirectly | |
$query = [Web.HTTPUtility]::ParseQueryString('') | |
if ($Filter) { | |
$query.add('$filter',$Filter) | |
} | |
if ($ResultSize -ne '' -and $ResultSize -ne 'Unlimited') { | |
$query.add('$top',$ResultSize) | |
} | |
#TODO: Add case insensitivity to the query | |
$result = $null | |
do { | |
if ($result.NextPageLink) { | |
if ($ResultSize -ne '') { | |
Write-Warning "Only returning the first 100 prices by default for safety. Adjust the -ResultSetSize parameter if you wish to retrieve more." | |
return | |
} | |
$Uri = [uribuilder]$result.NextPageLink | |
} else { | |
$Uri.Query = $query.ToString() | |
} | |
$result = Invoke-RestMethod -Uri $Uri.uri | |
$result.Items | |
} until ( | |
$result.count -lt 100 -or | |
#TODO: This is a quirk for if you specify exactly 100 records, maybe should track this clientside instead | |
$result.NextPageLink -notmatch 'skip=\d+$' | |
) | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment