Azure / azure-powershell

Microsoft Azure PowerShell
Other
4.26k stars 3.86k forks source link

Get-AzConsumptionUsageDetail returns 'BadRequest' #12561

Open PcChip opened 4 years ago

PcChip commented 4 years ago

same issue as https://github.com/Azure/azure-powershell/issues/10203 , however that is closed so I'm opening a new issue

Steps to reproduce

Get-AzConsumptionUsageDetail : Operation returned an invalid status code 'BadRequest'
At line:1 char:1
+ Get-AzConsumptionUsageDetail
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : CloseError: (:) [Get-AzConsumptionUsageDetail], ErrorResponseException
    + FullyQualifiedErrorId : Microsoft.Azure.Commands.Consumption.Cmdlets.UsageDetails.GetAzureRmConsumptionUsageDetail

Environment data

PS C:\WINDOWS\system32> $PSVersionTable

Name                           Value                                                                                                                                                                         
----                           -----                                                                                                                                                                         
PSVersion                      5.1.18362.752                                                                                                                                                                 
PSEdition                      Desktop                                                                                                                                                                       
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}                                                                                                                                                       
BuildVersion                   10.0.18362.752                                                                                                                                                                
CLRVersion                     4.0.30319.42000                                                                                                                                                               
WSManStackVersion              3.0                                                                                                                                                                           
PSRemotingProtocolVersion      2.3                                                                                                                                                                           
SerializationVersion           1.1.0.1                                                                                                                                                                       
ghost commented 4 years ago

Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc @ms-premp.

dingmeng-xue commented 4 years ago

Thanks for reporting. I can see the similar issue. It seems SDK doesn't return error details.

@PcChip , please set $DebugPreference="Continue" and then execute Get-AzConsumptionUsageDetail. Then, you should get the detail information from response. Please share error message to us.

PcChip commented 4 years ago

I'm not sure what parts of this I need to sanitize so I left off a lot of previous [DEBUG] output, but this might be what you're after,

I suspect this is of importance "api-version=2018-01-31"

DEBUG: ============================ HTTP REQUEST ============================

HTTP Method:
GET

Absolute Uri:
https://management.azure.com/subscriptions/[REDACTED]/providers/Microsoft.Consumption/usageDetails?$top=1000&api-version=2018-01-31

Headers:
x-ms-client-request-id        : 24217901-244a-499d-b391-959aaf39f6e5
accept-language               : en-US

Body:

DEBUG: ============================ HTTP RESPONSE ============================

Status Code:
BadRequest

Headers:
Pragma                        : no-cache
session-id                    : f3654ade-07cc-437c-adbb-175feac17ee5
x-ms-request-id               : ea46b8d0-d573-4a3b-a1f8-98b49f0fccf9
x-ms-correlation-request-id   : c4321a65-3464-4a2e-8615-5558b2f5689e
x-ms-client-request-id        : bfa224e5-3d90-4060-aaff-94a0cf00ec64
x-ms-ratelimit-microsoft.consumption-tenant-retry-after: 60
x-ms-ratelimit-remaining-microsoft.consumption-tenant-requests: 9
OData-Version                 : 4.0
Access-Control-Allow-Origin   : *
X-Content-Type-Options        : nosniff
Strict-Transport-Security     : max-age=31536000; includeSubDomains
x-ms-ratelimit-remaining-subscription-reads: 11999
x-ms-routing-request-id       : EASTUS:20200804T165914Z:c4321a65-3464-4a2e-8615-5558b2f5689e
Cache-Control                 : no-cache
Date                          : Tue, 04 Aug 2020 16:59:14 GMT

Body:
{
  "error": {
    "code": "400",
    "message": "Subscription scope usage is not supported for current api version. Please use api version after 2019-10-01 (Request ID: ea46b8d0-d573-4a3b-a1f8-98b49f0fccf9)"
  }
}

Get-AzConsumptionUsageDetail : Operation returned an invalid status code 'BadRequest'
At line:1 char:1
+ Get-AzConsumptionUsageDetail
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : CloseError: (:) [Get-AzConsumptionUsageDetail], ErrorResponseException
    + FullyQualifiedErrorId : Microsoft.Azure.Commands.Consumption.Cmdlets.UsageDetails.GetAzureRmConsumptionUsageDetail

DEBUG: AzureQoSEvent: CommandName - Get-AzConsumptionUsageDetail; IsSuccess - False; Duration - 00:00:02.3438538;; Exception - Microsoft.Azure.Management.Consumption.Models.ErrorResponseException: Operation
 returned an invalid status code 'BadRequest'
   at Microsoft.Azure.Management.Consumption.UsageDetailsOperations.<ListWithHttpMessagesAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Azure.Management.Consumption.UsageDetailsOperationsExtensions.<ListAsync>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.Azure.Commands.Consumption.Cmdlets.UsageDetails.GetAzureRmConsumptionUsageDetail.ExecuteCmdlet();
DEBUG: Finish sending metric.
DEBUG: 11:59:23 AM - GetAzureRmConsumptionUsageDetail end processing.
dingmeng-xue commented 4 years ago

Code 400 means BadRequest. its detail message is Subscription scope usage is not supported for current api version. Please use api version after 2019-10-01 (Request ID: ea46b8d0-d573-4a3b-a1f8-98b49f0fccf9)

Service team, please check this issue.

PcChip commented 4 years ago

Hello,

any updates on this?

scott1138 commented 4 years ago

@PcChip I have the same problem and opened a ticket as I thought it had something to do with a resource provider that wouldn't register. They are telling me it has something to do with Legacy vs Modern subscriptions, which I had never heard of before. I used the API directly and was able to return results using the 2019-10-01 version. @dingmeng-xue do you know when the API will be updated in the module?

PcChip commented 4 years ago

Hi @scott1138 , thanks for the info

Microsoft, is there any update on this?

chris-holmes1111 commented 4 years ago

This is affecting us as well. We have a Azure runbook that we've created that checks for reservation utilization. Since the API version changed, the Get-AzConsumptionUsageDetail cmdlet no long works. When enabling debug preference, I see the same error as @PcChip

cristobalito commented 4 years ago

Also see the same error as @PcChip

ramaganesan-rg commented 4 years ago

thank you for your feedback. The Old SDK does not support non-EA subscription. A new version of SDK (Potentially to be released by end of this year) will fix this. REST API is the best alternative right now.

adumont commented 3 years ago

I am having the same issue as well.

The Old SDK does not support non-EA subscription

@ramaganesan-rg By SDK do you mean this Powershell module?

Do you mean I should try to use the REST API directly and I might be able to get the information?

PaulVrugt commented 3 years ago

@ramaganesan-rg why is this issue closed? The bug still exists in the latest version of Azure Powershell (5.1.2). What is the status of the new SDK that contains the fix?

dingmeng-xue commented 3 years ago

@ramaganesan-rg , could you explain this question further? If it is fixed on service side, and does user not need to update module?

DecimalZero commented 3 years ago

I'm also still having this issue. What's the status?

Can someone please point me to the REST API method? Thanks.

tomasrudh commented 3 years ago

I have had a case with MS support since December. I asked for a time estimate when this will be fixed and got this back:


I sincerely apologize for any inconvenience this may be causing, however, after considerable review with our cost management team and Technical leads, it has been confirmed that there is curently no estimated time as this feature is not supported.


I guess they mean that the API version the Powershell command is using is not supported. Our hope seem to be an update of the Powershell command to use the supported API version. I am not really happy with rewriting my scripts to use the REST API instead.

brianstringfellow commented 3 years ago

[Updated 2021.03.30 after reply from @tomasrudh] In case it helps anyone, I wrote the following to work around the problem. It is tailored to solve my particular need for daily data collection but anyone can alter to suit their needs. There is a little uncertainty in the mapping between 'legacy' and 'modern' response properties but the values seem to closely match the data I've already collected.

function Get-ConsumptionUsageDetail {
  [CmdletBinding()]
  param (
      [Parameter(Mandatory)]
      [string] $SubscriptionId,

      [Parameter(Mandatory)]
      [ValidateSet('Legacy', 'Modern')]
      [string] $SubscriptionKind,

      [Parameter(Mandatory)]
      [datetime] $Date
  )

  $isLegacy = $SubscriptionKind -eq 'Legacy'

  $resource = 'https://management.azure.com'
  $context = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile.DefaultContext
  $accessToken = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($context.Account, $context.Environment, $context.Tenant.Id.ToString(), $null, [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never, $null, $resource).AccessToken

  $dateFilter = $Date.Date.ToString('yyyy-MM-dd')
  $uriPath = "https://management.azure.com/subscriptions/$($SubscriptionId)/providers/Microsoft.Consumption/usageDetails"

  # https://docs.microsoft.com/en-us/azure/cost-management-billing/costs/manage-automation#get-usage-details-for-a-scope-during-specific-date-range
  if ($isLegacy) {
    $uriQuery = '?$expand=properties/meterDetails&$filter=properties/usageStart ge ''' + $dateFilter + ''' and properties/usageEnd le ''' + $dateFilter + '''&$top=5000&api-version=2019-10-01'
  }
  else {
    $uriQuery = '?startDate=' + $dateFilter + '&endDate=' + $dateFilter + '&$top=5000&api-version=2019-10-01'
  }
  $uri = $uriPath + $uriQuery
  $consumptionDetailsRaw = Invoke-RestMethod -Method 'Get' -Uri $uri -Headers @{ Authorization = "Bearer " + $accessToken }

  $consumptionDetails = @()
  foreach ($detail in $consumptionDetailsRaw.value) {
    $convertedDetail = @{
      SubscriptionGuid  = if ($isLegacy) { $detail.properties.subscriptionId } else { $detail.properties.subscriptionGuid }
      InstanceName      = if ($isLegacy) { $detail.properties.resourceName } else { ($detail.properties.instanceName -split '/')[-1] }
      AccountName       = if ($isLegacy) { $detail.properties.accountName } else { $detail.properties.billingAccountName }
      DepartmentName    = if ($isLegacy) { $detail.properties.invoiceSection } else { $detail.properties.billingProfileName }
      CostCenter        = $detail.properties.costCenter
      BillingPeriodName = $detail.properties.billingPeriodStartDate
      UsageStart        = $detail.properties.date
      UsageEnd          = $detail.properties.date
      ConsumedService   = $detail.properties.consumedService
      Product           = $detail.properties.product
      Currency          = if ($isLegacy) { $detail.properties.billingCurrency } else { $detail.properties.billingCurrencyCode }
      MeterDetails      = @{
        MeterName        = $detail.properties.meterDetails.meterName
        MeterCategory    = $detail.properties.meterDetails.meterCategory
        MeterSubCategory = $detail.properties.meterDetails.meterSubCategory
        Unit             = $detail.properties.meterDetails.unitOfMeasure
        MeterLocation    = $detail.properties.resourceLocation
      }
      UsageQuantity     = $detail.properties.quantity
      PreTaxCost        = if ($isLegacy) { $detail.properties.cost } else { $detail.properties.costInUSD }
    }

    $consumptionDetails += $convertedDetail
  }

  $consumptionDetails
}

I call it with something like:

$result = Get-ConsumptionUsageDetail -SubscriptionId (Get-AzContext).Subscription.Id -SubscriptionKind 'Modern' -Date '2021-03-23' -Verbose
tomasrudh commented 3 years ago

Thanks Brian! Useful script. However, for the subscription where I cannot run the cmdlet Get-AzConsumptionUsageDetail this script also don't work, it seems filtering is not working. It is working fine for another subscription. I have placed another support case to Microsoft for the REST API problem.

SebastianGoers commented 3 years ago

We are having the exact same issue. Is there any ETA by when this will be fixed?

tomasrudh commented 3 years ago

The support case I have with MS is still open, since December. Neither the above Powershell commandlet nor the REST API do work. I suspect it has to do with our subscription are 'modern'. MS support asks a question, or suggests something, I test and answer usually within a day or two. Then MS gets back after a week or two, at best. They have no ETA, they have not even said it is a known problem. If you have the possibility, please log a support case at MS.

Lira-tron commented 3 years ago

Rest API should work, you can get more information in https://docs.microsoft.com/en-us/rest/api/consumption/usage-details/list,

tomasrudh commented 3 years ago

The REST API do work, at least until you try to use filter, that function seem to be broken as well. This might also only be a problem for 'modern' subscriptions. I had a remote with MS support last week and showed them, they will investigate.

ghost commented 3 years ago

Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc @ms-premp.

Issue Details
same issue as https://github.com/Azure/azure-powershell/issues/10203 , however that is closed so I'm opening a new issue ## Steps to reproduce ```PS C:\WINDOWS\system32> Get-AzConsumptionUsageDetail Get-AzConsumptionUsageDetail : Operation returned an invalid status code 'BadRequest' At line:1 char:1 + Get-AzConsumptionUsageDetail + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : CloseError: (:) [Get-AzConsumptionUsageDetail], ErrorResponseException + FullyQualifiedErrorId : Microsoft.Azure.Commands.Consumption.Cmdlets.UsageDetails.GetAzureRmConsumptionUsageDetail ``` ## Environment data ``` PS C:\WINDOWS\system32> $PSVersionTable Name Value ---- ----- PSVersion 5.1.18362.752 PSEdition Desktop PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...} BuildVersion 10.0.18362.752 CLRVersion 4.0.30319.42000 WSManStackVersion 3.0 PSRemotingProtocolVersion 2.3 SerializationVersion 1.1.0.1 ```
Author: PcChip
Assignees: -
Labels: `Consumption`, `Consumption-UsageDetailsandExport`, `Service Attention`, `bug`, `customer-reported`
Milestone: -
c240amg commented 3 years ago

We're having the same issue.

We recently converted from a pay-as-you-go to an MCA. Not sure if that's the issue?

evogelpohl commented 3 years ago

@PcChip @c240amg @tomasrudh @DecimalZero

FWiW - Had the same issue, got BadRequest when calling Get-AzConsumptionUsageDetail using a Service Principal (in Azure Automation or from the CLI).

My org has ~12 Azure Subscriptions of various types. I could [foreach] my way through 2 of the 12 successfully w/ the Get-AzConsumptionUsageDetail command. 10 subs resulted in BadRequest.

Progress 1: While the Svc Principal account I was using had the [Billing Reader] role at the Subscription level, it wasn't at the Billing Scope level. I called our Azure Admin & got put into a top-level Billing Reader custom group he created.

Next, I ensured that the SPAccount had the Billing Reader role at each Sub level.

Success! Now, I can loop through 5 more of the 12. That explained some of my BadRequest errors. The original 2 subs that worked were bound to a different billing root (for some odd reason, perhaps having to due to the fact that we got credits years ago - not sure - not all accounts were moved over to the new root/scope.)

tomasrudh commented 3 years ago

So, the case I opened at Microsoft in December is finally closed, unfortunately without a proper solution. The problems are because our subscriptions have been changed to 'modern' subscriptions. My conclusion is this:

Pro: The invoices have better grouping of costs

Cons: Reading out cost using PowerShell do not work Reading out cost on management level do not work Filtering do not work when reading out cost using the REST API

Microsoft has no plan to fix this, not that they want to share anyway.

rajnegi commented 3 years ago

I am also facing this 'Bad Request' while executing the below code on Azure Runbook. On the local machine, it is working fine. Get-AzConsumptionUsageDetail -StartDate $startDate -EndDate $endDate | Measure-Object -Property PretaxCost -Sum

Error:

Get-AzConsumptionUsageDetail : Operation returned an invalid status code 'BadRequest' At line:44 char:16 + ... rrentCost = Get-AzConsumptionUsageDetail -StartDate $startDate -EndDa ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : CloseError: (:) [Get-AzConsumptionUsageDetail], ErrorResponseException + FullyQualifiedErrorId : Microsoft.Azure.Commands.Consumption.Cmdlets.UsageDetails.GetAzureRmConsumptionUsageDetail

After put -debug, the error is:

Get-AzConsumptionUsageDetail : A command that prompts the user failed because the host program or the command type does not support user interaction. The host was attempting to request confirmation with the following message: A command that prompts the user failed because the host program or the command type does not support user interaction. The host was attempting to request confirmation with the following message: Operation returned an invalid status code 'BadRequest' At line:44 char:16 + ... rrentCost = Get-AzConsumptionUsageDetail -StartDate $startDate -EndDa ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotImplemented: (:) [Get-AzConsumptionUsageDetail], HostException + FullyQualifiedErrorId : HostFunctionNotImplemented,Microsoft.Azure.Commands.Consumption.Cmdlets.UsageDetails.GetAzureRmConsumptionUsageDetail

I tried with -Force and -Confirm:$false but had no luck. Can someone please help with this?

evogelpohl commented 3 years ago

@rajnegi - Give up on Get-AzConsumptionUsageDetails until MS updates it to reflect the 2 methods for querying the Microsoft.Consumption Management API.

Scroll up and take note of the replacement function written by @brianstringfellow. I've adapted this, slightly, to account for the modern & legacy subscription types I'm passing in and added some try/catch to deal with gatewayTimeout retries (simple). Works as designed. I'm getting Consumption Details for all subscriptions now. Best.

tujamg commented 3 years ago

I shared the information on this issue with our on-calls they will look into it and update the thread. stay tuned.

rajnegi-condeco commented 3 years ago

Finally able to resolve this issue. Actually, i am passing date format in ("dd-MM-yyyy") for 'BillingPeriodStartDate' and 'BillingPeriodEndDate'. The date format should be ("yyyy-MM-dd") I don't know why it is correctly working with ("dd-MM-yyyy") format in my local machine. After using ("yyyy-MM-dd") format, It is working on both local and Azure runbook.

Debug logs really help me to find out the exact problem.

tomasrudh commented 3 years ago

That do not work for me. The error message says the called API is of the wrong version, so I actually don't think it is a problem with date format. But glad it worked for you!

ghost commented 2 years ago

Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc @TiagoCrewGitHubIssues.

Issue Details
same issue as https://github.com/Azure/azure-powershell/issues/10203 , however that is closed so I'm opening a new issue ## Steps to reproduce ```PS C:\WINDOWS\system32> Get-AzConsumptionUsageDetail Get-AzConsumptionUsageDetail : Operation returned an invalid status code 'BadRequest' At line:1 char:1 + Get-AzConsumptionUsageDetail + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : CloseError: (:) [Get-AzConsumptionUsageDetail], ErrorResponseException + FullyQualifiedErrorId : Microsoft.Azure.Commands.Consumption.Cmdlets.UsageDetails.GetAzureRmConsumptionUsageDetail ``` ## Environment data ``` PS C:\WINDOWS\system32> $PSVersionTable Name Value ---- ----- PSVersion 5.1.18362.752 PSEdition Desktop PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...} BuildVersion 10.0.18362.752 CLRVersion 4.0.30319.42000 WSManStackVersion 3.0 PSRemotingProtocolVersion 2.3 SerializationVersion 1.1.0.1 ```
Author: PcChip
Assignees: -
Labels: `Service Attention`, `bug`, `customer-reported`, `Consumption-UsageDetailsandExport`
Milestone: -
TiagoCrewGitHubIssues commented 2 years ago

we still have this in our backlog and have started the design for this. We'll keep this updated.

tujamg commented 2 years ago

we still have this in our backlog and have started the design for this. We'll keep this updated.

pmatsconsulting commented 2 years ago

Facing the same issue:

Subscription scope usage is not supported for current api version. Please use api version after 2019-10-01 (Request ID: 3593ef75-997f-4d71-95e6-e1bff337e570)

When this will be fixed?

jhueppauff commented 2 years ago

Get-AzConsumptionUsageDetail -StartDate $firstDay -EndDate $date works for me with the latest PS and AZ Version (7.*) for most of the subscriptions. The only difference I could spot were that those subscriptions which didn't worked were a Azure Plan Subscription: image image

Not sure if there is a difference.

lukaszch commented 2 years ago

I'm unsure why the bug label has been removed and the feature-request applied. Get-AzConsumptionUsageDetail still doesn't work for me on the latest Az version 8.2 due to the error: Subscription scope usage is not supported for current api version. Please use api version after 2019-10-01

When can we expect to have this issue fixed?

dho79 commented 1 year ago

Hello,

We are still facing the issue on Azure Plan subscriptions Body: { "error": { "code": "400", "message": "Subscription scope usage is not supported for current api version. Please use api version after 2019-10-01" } }

Version Name


9.2.0 Az 2.0.0 Az.Billing

When can we expect to have this issue fixed?

Thanks!

vukasinterzic commented 1 year ago

Just for the info, Get-AzConsumptionUsageDetail is still not working on subscriptions that are provisioned as Azure Plan, with the error : "Operation returned an invalid status code 'BadRequest'"

The same command WORKS on the subscription that is PayAsYouGo.

pcgeek86 commented 1 year ago

Same problem here. I cannot use Get-AzConsumptionUsageDetail to obtain the pending / uninvoiced charges (aka. "Current Cost" in portal) on my Azure subscription. According to Azure Portal, my subscription is "Azure Plan."

This is incredibly frustrating. When is this going to work?

image

PowerShell Environment

Name                           Value
----                           -----
PSVersion                      7.3.2
PSEdition                      Core
GitCommitId                    7.3.2
OS                             Microsoft Windows 10.0.25…
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Module Versions

ModuleType Version    PreRelease Name
---------- -------    ---------- ----
Script     2.11.2                Az.Accounts
Script     2.0.0                 Az.Billing
kyuz0 commented 1 year ago

Up, I'm on Azure Plan and it would be really useful to be able to use this API.

Sebastianbuus commented 1 year ago

UP please, would make a world of difference if it worked.

Mantrareborn commented 1 year ago

UP, can we get someone from Microsoft to give us a ETA on this API bug, crucial option that needs to be working for many people obv.

tomaustin700 commented 1 year ago

This does work through the Azure cloud shell strangely enough.

fju01 commented 1 year ago

his does work through the Azure cloud shell strangely enough.

I would say no, it does not. Seems nothing change from MSFT so far.

Roelemansk commented 1 year ago

Also waiting for this issue the get resolved

shailugit commented 9 months ago

Getting issue while running the below CLI Get-AzConsumptionUsageDetail -debug -StartDate 2024-01-01 -EndDate 2024-01-16

However the debug will throw the detailed error

SvenKribitz commented 8 months ago

Still throwing this error... Get-AzConsumptionUsageDetail: Operation returned an invalid status code 'BadRequest'

erikbailey commented 6 months ago

Last week we moved our Azure contract from an EA (Enterprise Agreement) to MCA (Microsoft Customer Agreement). That change caused our PowerShell script to break in exactly the way described here. @brianstringfellow thank you for the script - it basically worked perfectly out-of-the-box (although I find that it randomly omits some subscriptions - that certainly isn't the script's fault though). I have reported this to our Azure support team - I hope this gets addressed.

markwragg commented 2 months ago

Edit: Updated to return costInBillingCurrency so that it returns accurate costs for subscriptions billed in currencies other than USD.

I've written my own version of @brianstringfellow's excellent script, which has a couple of modifications. The API returns a "nextlink" value if there's more results to fetch, so mine will loop until its paginated all of the results. Mine also is designed to get the consumption for a full month by passing a -BillingPeriod parameter in the same way as you do to the regular Get-AzConsumptionUsageDetail.

function Get-EaConsumptionUsageDetail {
    <#
    .SYNOPSIS
        Fall back script to get consumption usage detail for Enterprise Agreement subscriptions

    .NOTES
        Credit to Brian Stringfellow who wrote the original here: https://github.com/Azure/azure-powershell/issues/12561#issuecomment-808630391
    #>
    [CmdletBinding()]
    param (
        [string]
        $SubscriptionId = (Get-AzContext).Subscription.Id,

        [ValidateSet('Legacy', 'Modern')]
        [string]
        $SubscriptionKind = 'Modern',

        [Parameter(Mandatory)]
        [string]
        $BillingPeriodName
    )

    $StartDate = [datetime]::parseexact($BillingPeriodName, 'yyyyMM', $null)
    $EndDate = $StartDate.AddMonths(1).AddDays(-1)

    $isLegacy = $SubscriptionKind -eq 'Legacy'

    $resource = 'https://management.azure.com'
    $context = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile.DefaultContext
    $accessToken = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($context.Account, $context.Environment, $context.Tenant.Id.ToString(), $null, [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never, $null, $resource).AccessToken

    $Date = $StartDate.AddDays($Day)

    $dateFilter = $Date.Date.ToString('yyyy-MM-dd')
    $endDateFilter = $EndDate.Date.ToString('yyyy-MM-dd')
    $uriPath = "https://management.azure.com/subscriptions/$($SubscriptionId)/providers/Microsoft.Consumption/usageDetails"

    # https://docs.microsoft.com/en-us/azure/cost-management-billing/costs/manage-automation#get-usage-details-for-a-scope-during-specific-date-range
    if ($isLegacy) {
        $uriQuery = '?$expand=properties/meterDetails&$filter=properties/usageStart ge ''' + $dateFilter + ''' and properties/usageEnd le ''' + $endDateFilter + '''&$top=1000&api-version=2019-10-01'
    }
    else {
        $uriQuery = '?startDate=' + $dateFilter + '&endDate=' + $endDateFilter + '&$top=1000&api-version=2019-10-01'
    }
    $uri = $uriPath + $uriQuery

    $consumptionRaw = @()
    $nextLink = $null

    $consumptionRaw += do {

        $consumptionDetailsRaw = if ($nextLink) {
            Invoke-RestMethod -Method 'Get' -Uri $nextLink -Headers @{ Authorization = "Bearer " + $accessToken }
        }
        else {
            Invoke-RestMethod -Method 'Get' -Uri $uri -Headers @{ Authorization = "Bearer " + $accessToken }
        }

        $nextLink = $consumptionDetailsRaw.nextLink
        $consumptionDetailsRaw

    } until (-not $nextLink)

    $consumptionDetails = @()

    foreach ($detail in $consumptionRaw.value) {

        $convertedDetail = [pscustomobject]@{
            SubscriptionGuid  = if ($isLegacy) { $detail.properties.subscriptionId } else { $detail.properties.subscriptionGuid }
            InstanceName      = if ($isLegacy) { $detail.properties.resourceName } else { ($detail.properties.instanceName -split '/')[-1] }
            AccountName       = if ($isLegacy) { $detail.properties.accountName } else { $detail.properties.billingAccountName }
            DepartmentName    = if ($isLegacy) { $detail.properties.invoiceSection } else { $detail.properties.billingProfileName }
            CostCenter        = $detail.properties.costCenter
            BillingPeriodName = $detail.properties.billingPeriodStartDate
            UsageStart        = $detail.properties.date
            UsageEnd          = $detail.properties.date
            ConsumedService   = $detail.properties.consumedService
            Product           = $detail.properties.product
            Currency          = if ($isLegacy) { $detail.properties.billingCurrency } else { $detail.properties.billingCurrencyCode }
            MeterDetails      = @{
                MeterName        = $detail.properties.meterDetails.meterName
                MeterCategory    = $detail.properties.meterDetails.meterCategory
                MeterSubCategory = $detail.properties.meterDetails.meterSubCategory
                Unit             = $detail.properties.meterDetails.unitOfMeasure
                MeterLocation    = $detail.properties.resourceLocation
            }
            UsageQuantity     = $detail.properties.quantity
            PreTaxCost        = if ($isLegacy) { $detail.properties.cost } else { $detail.properties.costInBillingCurrency }
        }

        $consumptionDetails += $convertedDetail
    }

    $consumptionDetails
}

I'm adding this to my AzCostTools module and it will automatically fall back to this function if it gets a Bad Request result from the AZ one.

Sebastianbuus commented 1 month ago

Works like a charm, when I changed the PreTaxCost to use $detail.properties.paygCostInBillingCurrency.