Get-BenefitRecommendations.ps1
Queries the Azure Cost Management API to retrieve detailed benefit recommendations that aren't fully exposed in the Azure portal.
Overview
This PowerShell script extracts comprehensive savings plan and reserved instance recommendations directly from the Azure Cost Management API. The API returns additional details and granular data that the portal interface doesn't display, providing deeper insights for cost optimization decisions.
Key capabilities
- API-level detail extraction: Accesses recommendation data not visible in portal
- Flexible lookback periods: Analyze 7, 30, or 60 days of historical usage
- Multiple commitment terms: Compare 1-year vs 3-year savings plans
- Billing scope flexibility: Works at subscription or billing account level
When to use this script
- Extracting detailed recommendation data for FinOps reporting
- Comparing savings opportunities across different commitment terms
- Analyzing recommendations based on different usage windows
- Accessing API data fields not shown in portal views
- Building automated cost optimization workflows
Prerequisites
# Install Azure PowerShell module
Install-Module -Name Az -Repository PSGallery -Force
# Authenticate to Azure
Connect-AzAccount
# Verify Cost Management Reader permissions
Get-AzRoleAssignment | Where-Object {$_.RoleDefinitionName -like "*Cost Management*"}
# Find your billing account (for MCA)
Get-AzBillingAccount | Select-Object Name, Id
# List available subscriptions
Get-AzSubscription | Select-Object Name, Id
Parameters
| Parameter | Type | Description | Default |
|---|---|---|---|
| BillingScope | String | Billing scope path (required) | None |
| LookBackPeriod | String | Historical period to analyze | Last7Days |
| Term | String | Commitment term: P1Y or P3Y | P3Y |
BillingScope format
For subscriptions:
subscriptions/12345678-1234-1234-1234-123456789012
For billing accounts:
providers/Microsoft.Billing/billingAccounts/12345678
LookBackPeriod values
Last7Days- Analyze last 7 days of usageLast30Days- Analyze last 30 days of usageLast60Days- Analyze last 60 days of usage
Term values
P1Y- 1-year commitment termP3Y- 3-year commitment term
Usage examples
Basic subscription analysis
# Get 3-year recommendations based on last 7 days
.\Get-BenefitRecommendations.ps1 `
-BillingScope "subscriptions/12345678-1234-1234-1234-123456789012"
Extended analysis period
# Analyze 30 days of usage for 1-year commitments
.\Get-BenefitRecommendations.ps1 `
-BillingScope "subscriptions/12345678-1234-1234-1234-123456789012" `
-LookBackPeriod "Last30Days" `
-Term "P1Y"
Billing account level
# Get billing account ID
$billingAccount = Get-AzBillingAccount | Select-Object -First 1
# Analyze entire billing account
.\Get-BenefitRecommendations.ps1 `
-BillingScope "providers/Microsoft.Billing/billingAccounts/$($billingAccount.Name)" `
-LookBackPeriod "Last60Days" `
-Term "P3Y"
Export results for analysis
# Run script and capture output
$result = .\Get-BenefitRecommendations.ps1 `
-BillingScope "subscriptions/12345678-1234-1234-1234-123456789012" `
-LookBackPeriod "Last30Days"
# The script outputs raw JSON and formatted tables
# Capture and process as needed for your workflows
Output format
The script provides three types of output:
- Raw JSON output - Complete API response for processing
- Recommended savings plan - Primary recommendation in table format
- All savings plan recommendations - Full list of recommendations
API endpoint
The script calls the Cost Management API:
https://management.azure.com/{BillingScope}/providers/Microsoft.CostManagement/benefitRecommendations
With parameters:
$filter: Filters by lookback period and term$expand: Includes usage and recommendation detailsapi-version: 2024-08-01
Troubleshooting
No recommendations returned
# Verify you have usage data in the period
Get-AzConsumptionUsageDetail `
-StartDate (Get-Date).AddDays(-7) `
-EndDate (Get-Date) |
Measure-Object
# Check permissions
Get-AzRoleAssignment -Scope "/subscriptions/YOUR-SUB-ID" |
Where-Object {$_.RoleDefinitionName -like "*Cost Management*"}
Authentication errors
# Clear cached credentials
Clear-AzContext -Force
# Re-authenticate
Connect-AzAccount
# Set specific subscription context
Set-AzContext -SubscriptionId "YOUR-SUB-ID"
API access issues
# Test direct API access
$scope = "subscriptions/YOUR-SUB-ID"
$uri = "https://management.azure.com/$scope/providers/Microsoft.CostManagement/query?api-version=2024-08-01"
Invoke-AzRestMethod -Uri $uri -Method POST
Integration patterns
Scheduled analysis
# Weekly analysis across all subscriptions
$subscriptions = Get-AzSubscription | Where-Object State -eq "Enabled"
foreach ($sub in $subscriptions) {
Write-Host "Analyzing subscription: $($sub.Name)"
.\Get-BenefitRecommendations.ps1 `
-BillingScope "subscriptions/$($sub.Id)" `
-LookBackPeriod "Last30Days"
}
CI/CD integration
# Azure DevOps pipeline
- task: AzurePowerShell@5
inputs:
azureSubscription: 'ServiceConnection'
ScriptType: 'FilePath'
ScriptPath: '$(System.DefaultWorkingDirectory)/Get-BenefitRecommendations.ps1'
ScriptArguments: >
-BillingScope "subscriptions/$(SubscriptionId)"
-LookBackPeriod "Last30Days"
-Term "P3Y"
azurePowerShellVersion: 'LatestVersion'