I am trying to get last month’s cost for each resource we have in Azure. I am aware of the cmdlet Get-AzConsumptionUsageDetail
and I am able to get the information I need using the following, which gets the costs for the last complete billing period:
$data = $data = Get-AzConsumptionUsageDetail -BillingPeriod $(Get-Date (Get-Date).AddMonths(-1) -Format "yyyyMM")
That command takes about 4 minutes to run, and with our thousands of resources returns over 100,000 records. Given that we have a large number of resources, I realized it would not be feasible to do a separate call for each resource, or even each resource group. Looping through each resource group using Get-AzConsumptionUsageDetail
was surpassing the threshold of calls allowed by Azure.
The end goal is to calculate the total monthly cost for each individual resource. Since I cannot do an individual call for each resource, I decided to use the command shown above to get everything at once. However if I define $Resource as
$Resources = Get-AzResource
and run the following, it took 57 seconds for a small sample of all of the resources in $Resources, due to the sheer size of $data:
measure-command {
$Resources | select-object -first 200 | foreach-object -parallel {
$test = $using:data | where-object InstanceName -eq $psitem.Name
}
}
My question is: is there a way to get this pricing/consumption information where the data already shows the monthly total? This would greatly reduce the total number of records in $data and would speed it up a lot. At the very least, is there some way I can get the information more efficiently?
2
Answers
Thank you everyone for the feedback. I ended up modifying @Jahnavi's code and got it to work, but I will provide multiple solutions in case anybody finds this thread in the future.
The final code I am using is:
I decided to group by InstanceID instead of InstanceName because we have some identical resource names in our environment. Additionally, if you use
Get-AzResource
the ResourceID of that cmdlet will match to the InstanceID.I did also look into creating an export in Azure Cost Manager and using that data instead of
Get-AzConsumptionUsageDetail
. If anybody wants to see the documentation for setting up an export click here. From there, you can useGet-AzCostManagementExport
andInvoke-AzCostManagementExecuteExport
to get and run the export. You can see that documentation here. I set up a new container on a storage account. You can get that data withGet-AzStorageAccount
,Get-AzStorageContainer
, andGet-AzStorageBlobContent
. Click here for that documentation. However, the main reasons I did not go down that route of using the export are:Get-AzConsumptionDetail
, so the only real benefit of it was speedGroup-Object
recommended by @Jahnavi greatly sped up theWhere-Object
that is required in part 2. This is for when I cross-reference the consumption detail withGet-AzResource
. Given that this already needed to change my script from ad hoc to running nightly on a schedule (due to the time it took, which was not horrible but still too long for an application user to wait for), I figured an extra minute or two would not matter at the end of the day.Get-AzConsumptionUsageDetail
may be a little slower, but it is more consistent.Thank you to everyone who contributed, and hopefully this thread can help somebody in the future.
Get-AzConsumptionUsageDetail
is commonly used inPowerShell
to collect cost use details for Azure resources. However, if you have a huge amount of data/resources, you should use the other Cost details solutions as detailed in the given MSDoc. And as @mclayton mentioned, the consumption usage informationAPI
has been deprecated and will no longer exist. For huge data sets, you can usePower BI
orcost exports
instead. You can easily go with thePortal download
orPowerShell
commands for lesser sorts of data.There are some resources in my Azure environment, but not many. I tried to extract each individual cost information using the below loop and was successful.
You can also refer Cost API requests samples for less amount of data.