How to Retrieve Azure Resource Costs Using PowerShell or REST API for a Specific Resource Group and Resource Type?

Mohsin Khan 85 Reputation points
2026-10-24T21:30:27.53+00:00

Hi Team,

I am trying to retrieve Azure resource cost details programmatically using PowerShell or the Azure REST API (Invoke-AzRestMethod), but I have been unable to find a suitable approach.

My requirement is to retrieve cost reports based on the following filters:

  • Resource Group: A specific resource group.

Resource Type: A specific Azure resource type, such as Microsoft.Compute/virtualMachines.

Cost Details: The cost incurred by resources matching these filters over a specified period (for example, the last 30 days).

I have explored PowerShell commands and REST API methods but have not yet found a working solution to retrieve cost data filtered by both resource group and resource type.

My questions are:

Is there an Azure Cost Management API that supports filtering cost data by resource group and resource type?

Can this be achieved using PowerShell with Invoke-AzRestMethod or another Azure PowerShell cmdlet?

Which API version and request body should be used to retrieve the cost report?

Is it possible to retrieve the cost for individual resources within the specified resource group and resource type?

I would appreciate a working PowerShell example or REST API request demonstrating how to achieve this.Hi Team,

I am trying to retrieve Azure resource cost details programmatically using PowerShell or the Azure REST API (Invoke-AzRestMethod), but I have been unable to find a suitable approach.

My requirement is to retrieve cost reports based on the following filters:

Resource Group: A specific resource group.

Resource Type: A specific Azure resource type, such as Microsoft.Compute/virtualMachines.

Cost Details: The cost incurred by resources matching these filters over a specified period (for example, the last 30 days).

I have explored PowerShell commands and REST API methods but have not yet found a working solution to retrieve cost data filtered by both resource group and resource type.

My questions are:

Is there an Azure Cost Management API that supports filtering cost data by resource group and resource type?

Can this be achieved using PowerShell with Invoke-AzRestMethod or another Azure PowerShell cmdlet?

Which API version and request body should be used to retrieve the cost report?

Is it possible to retrieve the cost for individual resources within the specified resource group and resource type?

I would appreciate a working PowerShell example or REST API request demonstrating how to achieve this.

Cost Management
Cost Management

A Microsoft offering that enables tracking of cloud usage and expenditures for Azure and other cloud providers.


2 answers

Sort by: Most helpful
  1. Marcin Policht 112.4K Reputation points MVP Volunteer Moderator
    2026-10-24T23:22:31.7833333+00:00

    Yep - Azure Cost Management provides a REST API for retrieving resource-level cost data. Try the following PowerShell example, which queries virtual machine costs for a resource group over the previous 30 days and displays the results as PowerShell objects.

    Connect-AzAccount
    
    $subscription = (Get-AzContext).Subscription.Id
    $group = "Production-East"
    $begin = (Get-Date).ToUniversalTime().AddDays(-30).ToString("yyyy-MM-dd")
    $finish = (Get-Date).ToUniversalTime().ToString("yyyy-MM-dd")
    
    $scope = "/subscriptions/$subscription/resourceGroups/$group"
    $uri = "https://management.azure.com$scope/providers/Microsoft.CostManagement/query?api-version=2025-03-01"
    
    $query = @{
        type = "ActualCost"
        timeframe = "Custom"
        timePeriod = @{
            from = "${begin}T00:00:00Z"
            to   = "${finish}T00:00:00Z"
        }
        dataset = @{
            granularity = "None"
            aggregation = @{
                total = @{
                    name = "PreTaxCost"
                    function = "Sum"
                }
            }
            filter = @{
                dimensions = @{
                    name = "ResourceType"
                    operator = "In"
                    values = @("Microsoft.Compute/virtualMachines")
                }
            }
            grouping = @(
                @{
                    type = "Dimension"
                    name = "ResourceId"
                }
            )
        }
    } | ConvertTo-Json -Depth 10
    
    $response = Invoke-AzRestMethod -Method POST -Uri $uri -Payload $query
    $report = $response.Content | ConvertFrom-Json
    
    $columns = $report.properties.columns.name
    foreach ($values in $report.properties.rows) {
        $entry = [ordered]@{}
        for ($i = 0; $i -lt $columns.Count; $i++) {
            $entry[$columns[$i]] = $values[$i]
        }
        [pscustomobject]$entry
    }
    

    Replace Production-East with the resource group's actual name. The output contains aggregated cost data grouped by resource ID. Set granularity to Daily if you need daily cost records instead of a total for the period. Separately billed resources, such as managed disks and public IP addresses, require queries for their respective resource types. For production reporting, handle pagination if the response includes a nextLink and verify that the selected cost metric matches your billing requirements.


    If the above response helps answer your question, remember to "Accept Answer" so that others in the community facing similar issues can easily find the solution. Your contribution is highly appreciated.

    hth

    Marcin

    Was this answer helpful?

    0 comments No comments

  2. AI answer

    2026-10-24T21:31:19.9766667+00:00

    Use the Cost Management Query API at the resource-group scope, filter on the ResourceType dimension, and group by ResourceId to return the cost of each matching resource.

    PowerShell with Invoke-AzRestMethod

    The Query API version 2025-03-01 supports resource-group scopes, custom periods, filters, aggregation, and grouping.^1^

    Connect-AzAccount
    
    $subscriptionId = (Get-AzContext).Subscription.Id
    $resourceGroup   = "my-resource-group"
    $resourceType    = "Microsoft.Compute/virtualMachines"
    
    $from = (Get-Date).AddDays(-30).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
    $to   = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
    
    $body = @{
        type      = "ActualCost"
        timeframe = "Custom"
        timePeriod = @{
            from = $from
            to   = $to
        }
        dataset = @{
            granularity = "None"
            aggregation = @{
                totalCost = @{
                    name     = "PreTaxCost"
                    function = "Sum"
                }
            }
            filter = @{
                dimensions = @{
                    name     = "ResourceType"
                    operator = "In"
                    values   = @($resourceType)
                }
            }
            grouping = @(
                @{ type = "Dimension"; name = "ResourceId" }
            )
        }
    } | ConvertTo-Json -Depth 10
    
    $uri = "https://management.azure.com/subscriptions/[Subscription ID]" +
           "/resourceGroups/[Resource Group] Group]/providers/Microsoft.CostManagement/query" +
           "?api-version=2025-03-01"
    
    $response = Invoke-AzRestMethod -Method POST -Uri $uri -Payload $body
    $result = $response.Content | ConvertFrom-Json
    $result.properties
    

    Azure documents the same ActualCost, PreTaxCost, custom 30-day period, and dimension-filter pattern in an executable cost-query example.^2^

    The returned properties object contains:

    • columns: column names and data types.
    • rows: cost rows grouped by ResourceId.
    • nextLink: present if another response page must be retrieved.

    To convert the column/row representation into PowerShell objects:

    $names = @($result.properties.columns.name)
    
    $costs = foreach ($row in $result.properties.rows) {
        $item = [ordered]@{}
        for ($i = 0; $i -lt $names.Count; $i++) {
            $item[$names[$i]] = $row[$i]
        }
        [pscustomobject]$item
    }
    
    $costs | Format-Table -AutoSize
    

    Filtering both dimensions explicitly

    Using the resource-group URL already restricts the query to that resource group. If querying at subscription scope instead, combine ResourceGroup and ResourceType using and:

    filter = @{
        and = @(
            @{ dimensions = @{
                name = "ResourceGroup"; operator = "In"; values = @($resourceGroup)
            }}
            @{ dimensions = @{
                name = "ResourceType"; operator = "In"; values = @($resourceType)
            }}
        )
    }
    

    In that case, change the URI scope to:

    $uri = "https://management.azure.com/subscriptions/[Subscription ID]/providers/" +
           "Microsoft.CostManagement/query?api-version=2025-03-01"
    

    Resource group, Resource type, and ResourceId are supported Cost Management grouping/filtering properties.^3^

    Azure PowerShell cmdlet alternative

    Invoke-AzCostManagementQuery from Az.CostManagement exposes the equivalent scope, timeframe, aggregation, filter, and grouping parameters.^4^ For a compound filter, however, constructing the REST body directly is generally clearer than composing several in-memory query-filter objects.

    Important cost interpretation details

    • Grouping by ResourceId gives individual-resource rows when the charge includes an Azure Resource Manager resource ID.
    • Not every charge has a resource group, resource type, or resource ID. Purchases, support, Marketplace items, and some classic charges can therefore be absent from this filtered result or appear under non-resource categories.^3^
    • A VM query for Microsoft.Compute/virtualMachines does not automatically include separately charged disks, public IP addresses, or other related resources with different resource types. Cost Management does not automatically understand every dependency relationship.
    • The caller needs at least Cost Management Reader or Contributor at the queried resource-group or subscription scope. EA accounts must also have the applicable view-charges setting enabled.^5^

    For large, unaggregated datasets, use the asynchronous Cost Details Report API instead; the Query API is the appropriate choice for this filtered and aggregated per-resource report.^6^


    References

    1. Query - Usage
    2. Builds a date range for the last 30 days and constructs a JSON query to request daily pre-tax cost data for a specific Azure resource ID from Azure Cost Managem...
    3. Group and filter options in Cost Analysis and Budgets
    4. Creates a filter with specific dimensions and invokes the AzCostManagementQuery cmdlet to query usage data for a given subscription scope with monthly granulari...
    5. Assign access to Cost Management data
    6. Automation scenarios for billing and cost management
    AI-generated content may be incorrect. Read our transparency notes for more information.

    Was this answer helpful?

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.