top of page
Search

Updating Your Scripts: PowerShell and Python for the New Azure PAYG APIs

  • Writer: Shannon
    Shannon
  • Nov 1, 2025
  • 3 min read

In my last post, I talked about what’s changing with Azure’s Pay-As-You-Go (PAYG) APIs and why the old Usage Details endpoint is being retired. Now it’s time to roll up our sleeves! If your FinOps automations rely on Microsoft.Commerce/UsageAggregates, you’ll need to migrate those scripts to use the Exports API or Cost Details API.


This post covers the exact code changes you need to make in PowerShell and Python (typically what I see most often with my customers and what I tend to gravitate toward in my world - if you'd like to see it in Bicep or Terraform, let me know!), shows what changes line by line, and provides enterprise-ready scripts you can drop straight into your code repositories.


Quick Recap

The legacy API was great when you only had a few resources, but it does not scale for modern Azure. The API unfortunately throttles easily, it uses inconsistent field names, and it returns data synchronously.


The new approach focuses on scheduled exports that drop CSV files into Azure Storage. Instead of “pulling” data every day, you now “subscribe” to cost data delivered on a schedule.


Here’s how the APIs compare:

Capability

Legacy Usage Details API

New Cost Details / Exports API

Endpoint

/providers/Microsoft.Commerce/UsageAggregates

/providers/Microsoft.CostManagement/exports or /costdetails

Data Format

JSON

CSV (Exports) or JSON (Cost Details)

Delivery Method

API call on demand

Scheduled export or asynchronous job

Scale

Throttled for large tenants

Handles large datasets efficiently

PAYG Support

Yes

Exports only (Cost Details coming soon)

Schema

Varied by offer type

Consistent across offers


What Actually Changes in Scripts

When migrating, you’ll mainly touch three parts of your code:


  1. The endpoint URL

  2. The HTTP method

  3. Where and how data is retrieved


PowerShell: Before and After

Before (Legacy API)

# Legacy Usage Details API (Deprecated)
$uri = "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Commerce/UsageAggregates?api-version=2015-06-01-preview"

$response = Invoke-RestMethod -Uri $uri -Headers @{ Authorization = "Bearer $token" }
$response.value | Select-Object usageStartTime, usageEndTime, resourceUri, quantity, meterCategory, cost

After (Modern API)

# Modern Exports API (Supported)
$uri = "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.CostManagement/exports/$exportName?api-version=2023-03-01"

What changed:

  • The endpoint switched from Microsoft.Commerce to Microsoft.CostManagement

  • The verb changed from GET to PUT to create or update an export

  • You no longer parse $response.value; instead, your job reads CSVs from Blob Storage


Python: Before and After

Before (Legacy API)

url = f"https://management.azure.com/subscriptions/{subscription_id}/providers/Microsoft.Commerce/UsageAggregates?api-version=2015-06-01-preview"
response = requests.get(url, headers=headers)
data = response.json()

After (Modern API)

url = f"https://management.azure.com/subscriptions/{subscription_id}/providers/Microsoft.CostManagement/exports/{export_name}?api-version=2023-03-01"
response = requests.put(url, headers=headers, json=payload)

What changed:

  • The API path changed to Microsoft.CostManagement/exports

  • The request changed from GET to PUT

  • The response now confirms export creation instead of returning usage data directly


Enterprise-Ready Scripts

Both examples below are built for production use. They are parameterized, include basic logging, and can be used in pipelines like GitHub Actions or Azure DevOps.


PowerShell (Grab it on GitHub)



How to use it:

.\Create-Or-Update-AzCostExport.ps1 `
  -SubscriptionId "00000000-0000-0000-0000-000000000000" `
  -ResourceGroupName "finops-rg" `
  -StorageAccountName "finopsstorage01" `
  -ContainerName "exports" `
  -TriggerNow

This script ensures:

  • The export job is created or updated safely

  • Data lands in Blob Storage daily

  • Optional immediate execution for validation


Python (Grab it on GitHub)



How to use it:

python scripts/create_or_update_cost_export.py

This script works perfectly in CI/CD pipelines with azure-identity (early foreshadowing). The script does not require secrets when running inside Azure-hosted agents that use Managed Identity.


Pro Tip: The Subscription Model

Stop pulling data directly. Let Azure deliver it. Scheduled exports are far more reliable than constant API calls. They automatically handle retries and time windows, and they integrate easily with Azure Data Factory or Synapse (another early foreshadowing).


Next Up


In Blog 3, we will:


  • Put this onto a CICD pipeline with GitHub Actions (if you poke around my repository now, you'll see references to that coming, but it hasn't arrived...yet)

  • Ingest exported CSVs into Azure Data Factory

  • Build transformations for FinOps dashboards

  • Create a Power BI parameterized query that automatically pulls the latest data


If Blog 1 explained why to move and Blog 2 showed how, Blog 3 is where you’ll see the results.

Comments


© 2020 Shannon B. Eldridge-Kuehn

  • LinkedIn
  • Twitter
bottom of page