Skip to content

Instantly share code, notes, and snippets.

@kongou-ae
Last active August 19, 2018 16:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kongou-ae/796cae7e9438bf8714c9502109b0d2ca to your computer and use it in GitHub Desktop.
Save kongou-ae/796cae7e9438bf8714c9502109b0d2ca to your computer and use it in GitHub Desktop.
Get-AzureRmCostsPerRG.ps1
Add-Type -AssemblyName System.Web
Login-AzureRmAccount
$subscriptionId = (Get-AzureRmSubscription | Out-GridView -PassThru).SubscriptionId
Select-AzureRmSubscription -Subscription $subscriptionId
$context = Get-AzureRmContext
Write-Output "Calculating costs of $subscriptionId"
# Set API parameters
$reportedStartTime = (Get-Date).AddDays(-31).ToString("yyyy-MM-dd")
$reportedEndTime = (Get-Date).AddDays(-1).ToString("yyyy-MM-dd")
Write-Output "Calculating costs from $reportedStartTime to $reportedEndTime"
$apiVersion = "2015-06-01-preview"
$granularity = "Daily" # Can be Hourly or Daily
$showDetails = $true
$contentType = "application/json;charset=utf-8"
$UsageDatas = New-Object System.Collections.ArrayList
$continuationToken = $null
Write-Output "Start downloading costs"
Do {
$usageData = Get-UsageAggregates `
-ReportedStartTime $reportedStartTime `
-ReportedEndTime $reportedEndTime `
-AggregationGranularity $granularity `
-ShowDetails:$showDetails `
-ContinuationToken $continuationToken
$datas = $usageData.UsageAggregations.properties | Select-Object `
UsageStartTime,UsageEndTime, `
@{Label="Resources"; Expression={ $json = $_.InstanceData | convertFrom-Json; $json."Microsoft.Resources".resourceUri}}, `
@{Label="location"; Expression={ $json = $_.InstanceData | convertFrom-Json; $json."Microsoft.Resources".Location}}, `
MeterCategory,MeterSubCategory,MeterId,MeterName,Unit,Quantity
foreach($data in $datas){
$UsageDatas.Add($data) > $null
}
#$data | ForEach-Object {
# $UsageDatas.Add($_) > $null
#}
if ($usageData.NextLink) {
$continuationToken = `
[System.Web.HttpUtility]::`
UrlDecode($usageData.NextLink.Split("=")[-1])
} else {
$continuationToken = ""
}
} until (!$continuationToken)
Write-Output "finish downloading costs"
$UsageDatas = $UsageDatas | Group-Object Resources,location,MeterName,MeterId | Select-Object `
@{Label="Resources"; Expression={ $_.Values[0] }}, `
@{Label="Location"; Expression={ $_.Values[1] }}, `
@{Label="MeterName"; Expression={ $_.Values[2] }}, `
@{Label="MeterId"; Expression={ $_.Values[3] }}, `
@{Label="Quantity"; Expression={ ($_.group| Measure-Object -sum Quantity).sum }}
$offerDurableID = "MS-AZR-0003p" # http://azure.microsoft.com/en-us/support/legal/offer-details/
$currency = "JPY"
$locale = "en-US"
$region = "JP"
$token = $context.TokenCache.ReadItems() | Where-Object { $_.TenantId -eq $context.Tenant.Id }
$authHeader = "Bearer " + $token[0].AccessToken
$requestHeader = @{"Authorization" = $authHeader}
$contentType = "application/json;charset=utf-8"
Write-Output "Start downloading ratecard"
$rateCardUri = "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Commerce/RateCard?api-version=$apiVersion`&`$filter=OfferDurableId eq '$offerDurableID' and Currency eq '$currency' and Locale eq '$locale' and RegionInfo eq '$region'"
$rateCardData = Invoke-RestMethod `
-Uri $rateCardUri `
-Method Get `
-Headers $requestHeader `
-ContentType $contentType
Write-Output "Finish downloading ratecard"
$calculatedData = New-Object System.Collections.ArrayList
$selectedRateCards = New-Object System.Collections.ArrayList
# choose used meters
$usedMeters = $UsageDatas | Select-Object MeterId | Sort-Object MeterId | Get-Unique -AsString
foreach($usedMeter in $usedMeters){
$selectedRateCards.Add(($rateCardData.Meters).Where({$_.MeterId -eq $usedMeter.MeterId})) > $null
}
Write-Output "Start caliculating costs per rosource group"
foreach($data in $UsageDatas)
{
$rateData = $selectedRateCards.Where({$_.MeterId -eq $data.MeterId})
$cost = 0
$cost = ($rateData.MeterRates.0) * $data.Quantity
$data = $data |
Add-Member -NotePropertyName MeterRates -NotePropertyValue ($rateData.MeterRates.0) -Force -PassThru |
Add-Member -NotePropertyName cost -NotePropertyValue $cost -PassThru -Force 
$calculatedData.Add($data) > $null
}
$summaryData = $calculatedData | Select-Object `
@{Label="ResourceGroup"; Expression={[regex]::Match($_.Resources,"resourceGroups/(.*?)/","IgnoreCase").Groups[1].value}}, `
@{Label="ResourceName"; Expression={[regex]::Match($_.Resources,"providers/.*/.*/(.*)$","IgnoreCase").Groups[1].value}}, `
MeterName, cost
$fileName = "AzureCost-" + $reportedStartTime + "-" + $reportedEndTime + ".csv"
Write-Output "Generate $fileName"
$summaryData | Sort-Object ResourceGroup | Select-Object `
ResourceGroup,ResourceName,MeterName, `
@{Label="cost"; Expression={[Math]::Round($_.cost, 2, [MidpointRounding]::AwayFromZero)}} | Export-Csv $fileName
$perRGData = $summaryData | Group-Object ResourceGroup | Select-Object `
@{Label="ResourceGroup"; Expression={ $_.Name }}, `
@{Label="cost"; Expression={ [Math]::Round(($_.Group| Measure-Object -sum cost).sum, [MidpointRounding]::AwayFromZero) }} | sort cost -Descending
$totalCost = ($perRGData | Measure-Object -Sum cost).Sum
Write-Output "Every task was finished"
Write-Output "ReportedTime : $reportedStartTime - $reportedEndTime"
Write-Output "Total cost : $totalCost"
$perRGData | ft
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment