{"slug": "example-how-to-query-resource-agents-and-workflows-copilot-credit-consumption-a", "title": "Example how to query resource (agents and workflows) Copilot credit consumption for a given time period.  Allows for reporting at the user level or total the values per resource.", "summary": "A developer shared a PowerShell script that queries Copilot credit consumption for Power Platform resources such as agents and workflows over a specified time period. The script uses Azure authentication and the Power Platform API to retrieve resource data, enabling user-level or per-resource reporting.", "body_md": "| #requries -modules \"Az.Accounts\" | |\n| function Get-AccessToken | |\n| { | |\n| [CmdletBinding()] | |\n| param | |\n| ( | |\n| [Parameter(Mandatory=$true)] | |\n| [string] | |\n| $ResourceUrl | |\n| ) | |\n| if (-not (Get-AzContext)) | |\n| { | |\n| Write-Host \"No Azure context - launching sign-in...\" -ForegroundColor Yellow | |\n| Connect-AzAccount -WarningAction SilentlyContinue | Out-Null | |\n| } | |\n| $azAccessToken = Get-AzAccessToken -ResourceUrl $ResourceUrl -WarningAction SilentlyContinue | |\n| if ($azAccessToken.Token -is [System.Security.SecureString]) | |\n| { | |\n| return [System.Net.NetworkCredential]::new('', $azAccessToken.Token).Password | |\n| } | |\n| return $azAccessToken.Token | |\n| } | |\n| function Get-PowerPlatformResource | |\n| { | |\n| [CmdletBinding()] | |\n| param | |\n| ( | |\n| [Parameter(Mandatory=$false)] | |\n| [switch] | |\n| $IncludeAgentResources, | |\n| [Parameter(Mandatory=$false)] | |\n| [switch] | |\n| $IncludeWorkflowResources | |\n| ) | |\n| begin | |\n| { | |\n| $accessToken = Get-AccessToken -ResourceUrl \"https://api.powerplatform.com/\" | |\n| $headers = @{ \"Authorization\" = \"Bearer $accessToken\"; \"Content-Type\" = \"application/json\"; \"Accept\" = \"application/json\" } | |\n| $skipToken = \"\" | |\n| $skip = 0 | |\n| $top = 1000 | |\n| $resourceQueryTemplate = @' | |\n| {{ | |\n| \"Options\": {{ | |\n| \"Top\": {0}, | |\n| \"Skip\": {1}, | |\n| \"SkipToken\": \"{2}\" | |\n| }}, | |\n| \"TableName\": \"PowerPlatformResources\", | |\n| \"Clauses\": [ | |\n| {{ | |\n| \"$type\": \"where\", | |\n| \"FieldName\": \"type\", | |\n| \"Operator\": \"in~\", | |\n| \"Values\": [ {3} ] | |\n| }}, | |\n| {{ | |\n| \"$type\": \"extend\", | |\n| \"FieldName\": \"joinKey\", | |\n| \"Expression\": \"tolower(tostring(properties.environmentId))\" | |\n| }}, | |\n| {{ | |\n| \"$type\": \"project\", | |\n| \"FieldList\": [ | |\n| \"joinKey\", | |\n| \"resourceId = tolower(name)\", | |\n| \"type\", | |\n| \"resourceName = properties.displayName\", | |\n| \"resourceType = iif( type == 'microsoft.powerautomate/agentflows', 'Agent Workflow', iif( properties.isGithubCopilotAgent == 1, 'GitHub Copilot Harness Agent',iif(properties.model == 'Microsoft 365 Copilot','M365 Copilot Chat Harness Agent','Standard Harness Agent')))\", | |\n| \"properties\" | |\n| ] | |\n| }}, | |\n| {{ | |\n| \"$type\": \"join\", | |\n| \"JoinKind\": \"leftouter\", | |\n| \"RightTable\": {{ | |\n| \"TableName\": \"PowerPlatformResources\", | |\n| \"Clauses\": [ | |\n| {{ | |\n| \"$type\": \"where\", | |\n| \"FieldName\": \"type\", | |\n| \"Operator\": \"==\", | |\n| \"Values\": [ | |\n| \"'microsoft.powerplatform/environments'\" | |\n| ] | |\n| }}, | |\n| {{ | |\n| \"$type\": \"project\", | |\n| \"FieldList\": [ | |\n| \"joinKey = tolower(name)\", | |\n| \"environmentId = tolower(name)\", | |\n| \"environmentName = properties.displayName\", | |\n| \"environmentRegion = location\", | |\n| \"environmentType = properties.environmentType\", | |\n| \"isManagedEnvironment = properties.isManaged\", | |\n| \"environmentGroupId = tolower(properties.environmentGroupId)\" | |\n| ] | |\n| }} | |\n| ] | |\n| }}, | |\n| \"LeftColumnName\": \"joinKey\", | |\n| \"RightColumnName\": \"joinKey\" | |\n| }}, | |\n| {{ | |\n| \"$type\": \"join\", | |\n| \"JoinKind\": \"leftouter\", | |\n| \"RightTable\": {{ | |\n| \"TableName\": \"PowerPlatformResources\", | |\n| \"Clauses\": [ | |\n| {{ | |\n| \"$type\": \"where\", | |\n| \"FieldName\": \"type\", | |\n| \"Operator\": \"==\", | |\n| \"Values\": [ | |\n| \"'microsoft.powerplatform/environmentgroups'\" | |\n| ] | |\n| }}, | |\n| {{ | |\n| \"$type\": \"project\", | |\n| \"FieldList\": [ | |\n| \"environmentGroupId = tolower(name)\", | |\n| \"environmentGroupName = properties.displayName\" | |\n| ] | |\n| }} | |\n| ] | |\n| }}, | |\n| \"LeftColumnName\": \"environmentGroupId\", | |\n| \"RightColumnName\": \"environmentGroupId\" | |\n| }} | |\n| ] | |\n| }} | |\n| '@ | |\n| } | |\n| process | |\n| { | |\n| $uri = \"https://api.powerplatform.com/resourcequery/resources/query?api-version=2022-03-01-preview\" | |\n| $resourceTypes = @() | |\n| if( $IncludeAgentResources.IsPresent ) | |\n| { | |\n| $resourceTypes += \"`\"'microsoft.copilotstudio/agents'`\"\" | |\n| } | |\n| if( $IncludeWorkflowResources.IsPresent ) | |\n| { | |\n| $resourceTypes += \"`\"'microsoft.powerautomate/agentflows'`\"\" | |\n| } | |\n| $page = 0 | |\n| $resources = do | |\n| { | |\n| $page++ | |\n| Write-Verbose \"[$(Get-Date)] - Querying Power Platform resources, page $page.\" | |\n| $body = $resourceQueryTemplate -f $top, $skip, $skipToken, ($resourceTypes -join \",\") | |\n| $response = Invoke-RestMethod -Method Post -Uri $uri -Body $body -Headers $headers -Verbose:$false | |\n| $skipToken = $response.skipToken | |\n| $skip += $top | |\n| $response.data | |\n| } | |\n| while( $skipToken ) | |\n| $resources = foreach( $resource in $resources ) | |\n| { | |\n| [PSCustomObject] @{ | |\n| ResourceType = $resource.resourceType | |\n| ResourceName = $resource.resourceName | |\n| ResourceId = $resource.resourceId | |\n| EnvironmentId = $resource.environmentId | |\n| EnvironmentName = $resource.environmentName | |\n| EnvironmentRegion = $resource.environmentRegion | |\n| EnvironmentType = $resource.environmentType | |\n| EnvironmentIsManaged = $resource.isManagedEnvironment | |\n| EnvironmentGroupId = $resource.environmentGroupId | |\n| EnvironmentGroupName = $resource.environmentGroupName | |\n| ResourceCreatedAt = $resource.properties.createdAt | |\n| ResourceCreatedBy = $resource.properties.createdBy | |\n| ResourceOwnerId = $resource.properties.ownerId | |\n| ResourceLastPublishedAt = $resource.properties.lastPublishedAt | |\n| } | |\n| } | |\n| if( $IncludeAgentResources.IsPresent ) | |\n| { | |\n| $rows = @($resources | where-object -Property ResourceType -eq \"Agent Workflow\") | |\n| Write-Verbose \"[$(Get-Date)] - Discovered $($rows.Count) Power Platform Agent resources.\" | |\n| } | |\n| if( $IncludeWorkflowResources.IsPresent ) | |\n| { | |\n| $rows = @($resources | where-object -Property ResourceType -ne \"Agent Workflow\") | |\n| Write-Verbose \"[$(Get-Date)] - Discovered $($rows.Count) Power Platform Workflow resources.\" | |\n| } | |\n| $resources | |\n| } | |\n| end | |\n| { | |\n| } | |\n| } | |\n| function Get-PowerPlatformResourceMessageConsumption | |\n| { | |\n| [CmdletBinding()] | |\n| param | |\n| ( | |\n| [Parameter(Mandatory=$true)] | |\n| [Guid] | |\n| $ResourceId, | |\n| [Parameter(Mandatory=$true,ParameterSetName=\"PerUserCreditConsumption\")] | |\n| [switch] | |\n| $PerUserCreditConsumption, | |\n| [Parameter(Mandatory=$true,ParameterSetName=\"TotalCreditConsumption\")] | |\n| [switch] | |\n| $TotalCreditConsumption, | |\n| [Parameter(Mandatory=$true)] | |\n| [DateTime] | |\n| $StartDate, | |\n| [Parameter(Mandatory=$true)] | |\n| [DateTime] | |\n| $EndDate | |\n| ) | |\n| begin | |\n| { | |\n| $accessToken = Get-AccessToken -ResourceUrl \"https://api.powerplatform.com/\" | |\n| $headers = @{ \"Authorization\" = \"Bearer $accessToken\"; \"Content-Type\" = \"application/json\"; \"Accept\" = \"application/json\" } | |\n| $uri = 'https://api.powerplatform.com/licensing/entitlements/MCSMessages/resources/{0}/users?fromDate={1}&toDate={2}&api-version=2024-10-01' -f $ResourceId, $StartDate.ToString(\"MM-dd-yyyy\"), $EndDate.ToString(\"MM-dd-yyyy\") | |\n| } | |\n| process | |\n| { | |\n| Write-Verbose \"[$(Get-Date)] - Querying resource '$ResourceId' for usage.\" | |\n| $response = Invoke-RestMethod -Method GET ` | |\n| -Uri $uri ` | |\n| -Headers $headers ` | |\n| -ErrorAction Stop ` | |\n| -Verbose:$false | |\n| if( $TotalCreditConsumption.IsPresent ) | |\n| { | |\n| Write-Verbose \"[$(Get-Date)] - Calculating total usage across $($response.value.users.Count) users.\" | |\n| $totalBillableCreditsUsed = $totalCreditsUsed = $totalUserCount = $consumedUserCount = $billableConsumedUserCount = 0 | |\n| foreach( $user in $response.value.users ) | |\n| { | |\n| $totalUserCount++ | |\n| $totalBillableCreditsUsed += $user.consumed | |\n| $totalCreditsUsed += $user.metadata.NonBillableQuantity | |\n| if( $user.consumed -gt 0 ) | |\n| { | |\n| $billableConsumedUserCount++ | |\n| } | |\n| if( $user.metadata.NonBillableQuantity -gt 0 ) | |\n| { | |\n| $consumedUserCount++ | |\n| } | |\n| } | |\n| [PSCustomObject] @{ | |\n| BillableCreditsUsed = $totalBillableCreditsUsed | |\n| CreditsUsed = $totalCreditsUsed | |\n| BillableCreditUserCount = $billableConsumedUserCount | |\n| CreditUserCount = $consumedUserCount | |\n| TotalUserConsumptionCount = $totalUserCount | |\n| } | |\n| } | |\n| else | |\n| { | |\n| Write-Verbose \"[$(Get-Date)] - Calculating user level usage.\" | |\n| if( $response.value.users ) | |\n| { | |\n| foreach( $user in $response.value.users ) | |\n| { | |\n| [PSCustomObject] @{ | |\n| UserId = $user.userId | |\n| BillableCreditsUsed = $user.consumed | |\n| CreditsUsed = $user.metadata.NonBillableQuantity | |\n| CreditUsageAsOfDate = $user.asOfDate | |\n| } | |\n| } | |\n| } | |\n| } | |\n| } | |\n| end | |\n| { | |\n| } | |\n| } | |\n| # lookback last 30 days | |\n| $startDate = [DateTime]::Today.AddDays(-31) | |\n| $endDate = [DateTime]::Today.AddDays(-1) | |\n| # show total or per user per resource credit consumption | |\n| $reportPerUserCreditConsumption = $false | |\n| # get all copilot studio agents and agent workflows | |\n| $resources = Get-PowerPlatformResource -IncludeAgentResources -IncludeWorkflowResources -Verbose | |\n| # example filters if you want to narrow the scope | |\n| # $resources = $resources | Where-Object -Property ResourceType -eq \"Agent Workflow\" | |\n| # $resources = $resources | Where-Object -Property ResourceType -eq \"GitHub Copilot Harness Agent\" | |\n| # $resources = $resources | Where-Object -Property ResourceType -eq \"Standard Harness Agent\" | |\n| # pull agent usage | |\n| $results = foreach( $resource in $resources ) | |\n| { | |\n| if( $reportPerUserCreditConsumption ) | |\n| { | |\n| $messages = Get-PowerPlatformResourceMessageConsumption -ResourceId $resource.ResourceId -StartDate $startDate -EndDate $endDate -PerUserCreditConsumption -Verbose | |\n| foreach( $message in $messages ) | |\n| { | |\n| $row = $resource.psobject.Copy() | |\n| $row | Add-Member -MemberType NoteProperty -Name \"UserId\" -Value $message.UserId | |\n| $row | Add-Member -MemberType NoteProperty -Name \"BillableCreditsConsumed\" -Value $message.BillableCreditsUsed | |\n| $row | Add-Member -MemberType NoteProperty -Name \"CreditsConsumed\" -Value $message.CreditsUsed | |\n| $row | Add-Member -MemberType NoteProperty -Name \"CreditUsageAsOfDate\" -Value $message.CreditUsageAsOfDate | |\n| $row | |\n| } | |\n| } | |\n| else | |\n| { | |\n| $messages = Get-PowerPlatformResourceMessageConsumption -ResourceId $resource.ResourceId -StartDate $startDate -EndDate $endDate -TotalCreditConsumption -Verbose | |\n| $resource | Add-Member -MemberType NoteProperty -Name \"BillableCreditsConsumed\" -Value $messages.BillableCreditsUsed | |\n| $resource | Add-Member -MemberType NoteProperty -Name \"CreditsConsumed\" -Value $messages.CreditsUsed | |\n| $resource | Add-Member -MemberType NoteProperty -Name \"BillableCreditUserCount\" -Value $messages.BillableCreditUserCount | |\n| $resource | Add-Member -MemberType NoteProperty -Name \"CreditUserCount\" -Value $messages.CreditUserCount | |\n| $resource | Add-Member -MemberType NoteProperty -Name \"TotalUserConsumptionCount\" -Value $messages.TotalUserConsumptionCount | |\n| $resource | |\n| } | |\n| } | |\n| $timestamp = Get-Date -Format FileDateTime | |\n| $results | Export-Csv -Path \"C:\\_temp\\PowerPlatformResourceMessageConsumption_$timestamp.csv\" -NoTypeInformation |", "url": "https://wpnews.pro/news/example-how-to-query-resource-agents-and-workflows-copilot-credit-consumption-a", "canonical_source": "https://gist.github.com/joerodgers/335c428de741451e2f1eecbbb49f58cb", "published_at": "2026-08-24 16:52:51+00:00", "updated_at": "2026-08-25 19:44:32.290001+00:00", "lang": "en", "topics": ["developer-tools"], "entities": ["Power Platform", "Azure", "Copilot"], "alternates": {"html": "https://wpnews.pro/news/example-how-to-query-resource-agents-and-workflows-copilot-credit-consumption-a", "markdown": "https://wpnews.pro/news/example-how-to-query-resource-agents-and-workflows-copilot-credit-consumption-a.md", "text": "https://wpnews.pro/news/example-how-to-query-resource-agents-and-workflows-copilot-credit-consumption-a.txt", "jsonld": "https://wpnews.pro/news/example-how-to-query-resource-agents-and-workflows-copilot-credit-consumption-a.jsonld"}}