Skip to content

Instantly share code, notes, and snippets.

@JustinGrote
Created November 2, 2020 01:45
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JustinGrote/17341170ba16347ee24d5953ff3a33db to your computer and use it in GitHub Desktop.
Save JustinGrote/17341170ba16347ee24d5953ff3a33db to your computer and use it in GitHub Desktop.
Azure Retail Pricing API Proof of Concept
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