Azure Billing – PowerShell

Billing in Azure can be a beast to get your head around. But the new billing API that was announced last year by Scott Guthrie makes it easy to export the billing information to a .CSV file, where you can massage it in Excel and make it look pretty. There’s two parts to it, the Azure Usage API and the Azure RateCard API, we will focus on the forma.

The PowerShell script below pieced together runs through exporting Azure usage from the Billing API. The problem is the fact that there’s a limit to the number of lines of data you can get from the API, it’s a limit of 1000 lines. Having large date ranges will easily take you over this limit. To mitigate this, I have compiled this script to invoke the API call multiple times once per day and append the data.

In saying this, make sure you edit the data range near the top of this script before running the script. This is only an example, I would recommend massaging the script below to allow for particular information to be exported more suited to what you are looking for.

# Authenticate to Azure

#Choose subscription 'old' Azure
$subscriptionid = (Get-AzureSubscription | Out-GridView -Title "Select the Azure subscription that you want to use ..." -PassThru).SubscriptionID

# Set date range for exported usage data
$reportedStartTime = "2016-04-01"
$reportedEndTime = "2016-05-01"

$reportedTime = New-TimeSpan –Start $reportedStartTime –End $reportedEndTime

$StartTimeInt = 0
$EndTimeInt = $reportedTime.Days - 1
$results1 = @()

$newStartTime = (Get-Date -Date $reportedStartTime).AddDays($StartTimeInt)
$newEndTime = (Get-Date -Date $reportedEndTime).AddDays(-$EndTimeInt)

# Set path to exported CSV file
$filename = "$env:USERPROFILE\Desktop\usageData-${subscriptionId}-${reportedStartTime}-${reportedEndTime}.csv"

# Set Azure AD Tenant for selected Azure Subscription
$adTenant = 
    (Get-AzureSubscription `
        -SubscriptionId $subscriptionid).TenantId

# Set parameter values for Azure AD auth to REST API
$clientId = "1950a258-227b-4e31-a9cf-717495945fc2" # Well-known client ID for Azure PowerShell
$redirectUri = "urn:ietf:wg:oauth:2.0:oob" # Redirect URI for Azure PowerShell
$resourceAppIdURI = "" # Resource URI for REST API
$authority = "$adTenant" # Azure AD Tenant Authority

# Load ADAL Assemblies
$adal = "${env:ProgramFiles(x86)}\Microsoft SDKs\Azure\PowerShell\ServiceManagement\Azure\Services\Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
$adalforms = "${env:ProgramFiles(x86)}\Microsoft SDKs\Azure\PowerShell\ServiceManagement\Azure\Services\Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll"

Add-Type -Path $adal
Add-Type -Path $adalforms

# Create Authentication Context tied to Azure AD Tenant
$authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority

# Acquire Azure AD token
$authResult = $authContext.AcquireToken($resourceAppIdURI, $clientId, $redirectUri, "Auto")

# Create Authorization Header
$authHeader = $authResult.CreateAuthorizationHeader()

# Set REST API parameters
$apiVersion = "2015-06-01-preview"
$granularity = "Daily" # Can be Hourly or Daily
$showDetails = "true"
$contentType = "application/json;charset=utf-8"

# Set HTTP request headers to include Authorization header
$requestHeader = @{"Authorization" = $authHeader}


# Set initial URI for calling Billing REST API
$uri = "$subscriptionId/providers/Microsoft.Commerce/UsageAggregates?api-version=$apiVersion&reportedStartTime=$newStartTime&reportedEndTime=$newEndTime&aggregationGranularity=$granularity&showDetails=$showDetails"

# Get all usage data in raw format
$usageData = Invoke-RestMethod -Uri $Uri -Method Get -Headers $requestHeader -ContentType $contentType
$AzureVMs = Find-AzureRmResource -ExpandProperties | ? {$_.ResourceType -match 'Compute'}
$AzureVMUses = $ | ? {$_.meterCategory -eq 'Virtual Machines' -and $_.infofields -match "project"}
$projects = $AzureVMUses
foreach($AzureVMUse in $AzureVMUses){
    $x = new-object psObject | select elementType, elementName, aliasName, sampleTime, totalTime

        $x.elementType = $AzureVMUse.infoFields.meteredServiceType
        $x.elementName = $AzureVMUse.meterSubCategory
        $x.aliasName = $AzureVMUse.infoFields.project
        $x.sampleTime = $AzureVMUse.usageStartTime
        $x.totalTime = $AzureVMUse.quantity
        $Results1 += $x

$newStartTime = $newEndTime.AddDays(1)
$newEndTime = $newStartTime.AddDays(1)

} until($newEndTime -eq (Get-Date -Date $reportedEndTime) -or $newStartTime -eq (Get-Date -Date $reportedEndTime))

$Results1 | Export-Csv -notypeinformation -Path $filename


Leave a Reply

Please log in using one of these methods to post your comment: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: