Skip to content

Get PBIWorkspaceUsageReport

github-actions[bot] edited this page Aug 19, 2026 · 4 revisions

Get-PBIWorkspaceUsageReport β€” Quick Usage Guide

v1.6 Β· PowerShell 5.1+ Β· Python 3.10+ Scripts: scripts/Graph Commands/Get-PBIWorkspaceUsageReport.ps1 | .py


Quick Start

PowerShell

# Interactive login (ad-hoc, no app registration needed)
.\Get-PBIWorkspaceUsageReport.ps1 -TenantId "<tid>" -UseInteractiveAuth

# Service Principal (automated / pipeline)
.\Get-PBIWorkspaceUsageReport.ps1 `
    -TenantId "<tid>" -ClientId "<cid>" -ClientSecret "<secret>"

# Service account / ROPC (when SP is blocked at the PBI service layer)
.\Get-PBIWorkspaceUsageReport.ps1 `
    -TenantId "<tid>" -ClientId "<cid>" `
    -Username "svc-pbi@domain.com" -Password (ConvertTo-SecureString $env:SVC_PBI_PASSWORD -AsPlainText -Force)

# Custom output path, JSON format, 60-day window, include refresh history
.\Get-PBIWorkspaceUsageReport.ps1 `
    -TenantId "<tid>" -ClientId "<cid>" -ClientSecret "<secret>" `
    -OutputPath "C:\Reports\PBI" -OutputFormat json -ActivityDays 60 -IncludeRefreshHistory

# Upload reports to S3 after generation
.\Get-PBIWorkspaceUsageReport.ps1 `
    -TenantId "<tid>" -ClientId "<cid>" -ClientSecret "<secret>" `
    -PublishToS3 -S3BucketName "my-pbi-reports" -S3KeyPrefix "powerbi/monthly" -S3Region "us-east-1"

Python

# Install dependencies once
pip install -r "scripts/Graph Commands/requirements.txt"

# Service Principal
python Get-PBIWorkspaceUsageReport.py \
    --tenant-id <tid> --client-id <cid> --client-secret <secret>

# Interactive device-code flow (browser)
python Get-PBIWorkspaceUsageReport.py \
    --tenant-id <tid> --client-id <cid> --interactive

# ROPC / service account
python Get-PBIWorkspaceUsageReport.py \
    --tenant-id <tid> --client-id <cid> \
    --username svc@domain.com --password <pw>

# With refresh history + upload to S3
python Get-PBIWorkspaceUsageReport.py \
    --tenant-id <tid> --client-id <cid> --client-secret <secret> \
    --include-refresh-history \
    --s3-bucket my-pbi-reports --s3-prefix "powerbi/$(date +%Y-%m)" --s3-region us-east-1

Parameters

PowerShell

Parameter Required Default Description
-TenantId Yes β€” Entra ID Tenant ID
-ClientId SP / ROPC β€” App Registration Client ID
-ClientSecret SP only β€” App Registration Client Secret
-UseInteractiveAuth Interactive only β€” Browser login via MicrosoftPowerBIMgmt module
-Username ROPC only β€” Service account UPN
-Password ROPC only β€” Service account password (SecureString)
-OutputPath No . Output directory (created if missing)
-OutputFormat No csv csv or json
-ActivityDays No 30 Days of activity history (max 90, standard retention = 30)
-IncludeRefreshHistory No off Fetch last refresh per dataset (one extra API call each)
-PublishToS3 No off Upload all generated report files to S3 after local export
-S3BucketName When -PublishToS3 β€” Target S3 bucket name
-S3KeyPrefix No "" S3 key prefix (virtual folder path) e.g. pbi-reports/monthly
-S3Region No β€” AWS region override; uses default AWS config if omitted
-S3ProfileName No β€” Named AWS CLI credentials profile

Python

Argument Required Default Description
--tenant-id Yes β€” Entra ID Tenant ID
--client-id Yes β€” App Registration Client ID
--client-secret SP only β€” Mutually exclusive with --interactive / --password
--interactive β€” β€” Device-code flow (browser)
--password ROPC only β€” Requires --username
--username ROPC only β€” Service account UPN
--output-path No . Output directory
--output-format No csv csv or json
--activity-days No 30 Days of activity (max 30 standard, 90 Fabric/Premium)
--include-refresh-history No off Fetch last refresh per refreshable dataset
--s3-bucket No β€” S3 bucket β€” triggers upload when set
--s3-prefix No "" S3 key prefix e.g. powerbi/2026-04
--s3-region No β€” AWS region override
--s3-profile No β€” Named AWS credentials profile
--s3-kms-key No β€” KMS key ID/ARN for SSE-KMS encryption
--s3-storage-class No STANDARD STANDARD, INTELLIGENT_TIERING, GLACIER, etc.

Output Files

All files are timestamped YYYYMMDD_HHmmss to prevent overwrites.

File Description
PBI_Report_Inventory_*.csv/json Every report in the tenant β€” workspace, type, state, storage proxy fields
PBI_Workspace_Size_*.csv/json One row per workspace β€” StorageUsedMB (Premium/Fabric only), dataset count, report count
PBI_Dataset_Health_*.csv/json One row per dataset β€” TargetStorageMode, StorageCategory, IsRefreshable, gateway flag, configured-by
PBI_Report_Usage_*.csv/json Per-report usage β€” total views, unique users, user list, device type breakdown
PBI_Report_UserDetails_*.csv/json Per-user per-report β€” view count, last viewed timestamp
PBI_DeviceType_Summary_*.csv/json Tenant-wide device type counts β€” Web, Desktop, Mobile, Excel, etc.
PBI_Usage_Summary_*.txt Human-readable summary β€” top workspaces, top reports, device breakdown, storage mode breakdown

Key Columns β€” Dataset Health

Column Details
TargetStorageMode Raw API value: Abf, DirectQuery, PremiumFiles, CompositeModel, Streaming
StorageCategory Human-readable: Import (In-Memory), DirectQuery (No Memory), Composite, etc.
IsRefreshable Whether the dataset supports scheduled refresh
IsOnPremGatewayRequired Whether an on-prem data gateway is required
LastRefreshStart/End Populated only when -IncludeRefreshHistory is set
LastRefreshDurationMin Calculated refresh duration in minutes (proxy for dataset size/complexity)
LastRefreshStatus Completed, Failed, or Unknown

Memory note: StorageUsedMB (workspace-level) and StorageCategory (dataset-level) are the closest proxies available via the REST API. Byte-level dataset memory requires XMLA DMV queries on Premium/Fabric (DISCOVER_OBJECT_MEMORY_USAGE).


Permissions Setup

Three things must all be in place for the /admin/ endpoints to work:

1. App Registration (Service Principal auth)

API Permission Type
Power BI Service Tenant.Read.All Application

Admin consent required.

2. Assign Fabric Administrator Role to the SP (fastest)

Entra ID β†’ Roles and administrators β†’ Fabric Administrator β†’ Add assignment

OR use the Fabric Admin Portal setting instead (Option B below).

3. Fabric Admin Portal β€” Admin API Settings (Option B)

Navigate to Fabric Admin Portal β†’ Tenant settings β†’ Admin API settings

  • Enable: "Service principals can access read-only admin APIs"
  • Scope to the security group containing the SP

Common confusion: "Service principals can call Fabric public APIs" (Developer settings) is a different toggle β€” it covers public endpoints, not /admin/ endpoints.

Interactive auth (-UseInteractiveAuth / --interactive)

Install-Module MicrosoftPowerBIMgmt -Scope CurrentUser

Sign in with a Power BI Administrator or Fabric Administrator account. No app registration needed.

ROPC / Service Account

  • Account must have Power BI Administrator Entra role
  • Account must not have MFA or device-compliance Conditional Access
  • App registration must have "Allow public client flows" = Yes Entra ID β†’ App registrations β†’ [App] β†’ Authentication β†’ Advanced settings

S3 Upload

Both the PowerShell and Python versions support uploading all generated report files to an Amazon S3 bucket.

PowerShell

Requires AWS.Tools.S3 (or the monolithic AWSPowerShell) module. Credentials are resolved via the standard AWS credential chain (environment variables, ~/.aws/credentials, instance profile).

Install-Module AWS.Tools.S3 -Scope CurrentUser
# Basic upload
.\Get-PBIWorkspaceUsageReport.ps1 ... `
    -PublishToS3 -S3BucketName "my-pbi-reports" -S3KeyPrefix "powerbi/2026-05"

# Using a named AWS profile and specific region
.\Get-PBIWorkspaceUsageReport.ps1 ... `
    -PublishToS3 -S3BucketName "my-pbi-reports" `
    -S3KeyPrefix "powerbi/2026-05" -S3Region "us-west-2" -S3ProfileName "prod-profile"

Python

AWS credentials are resolved automatically via the standard boto3 chain:

  1. AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY environment variables
  2. ~/.aws/credentials named profile (--s3-profile)
  3. EC2 / ECS / Lambda instance role
# Basic upload
python Get-PBIWorkspaceUsageReport.py ... \
    --s3-bucket my-pbi-reports --s3-prefix powerbi/2026-04

# With KMS encryption and Intelligent-Tiering
python Get-PBIWorkspaceUsageReport.py ... \
    --s3-bucket my-pbi-reports \
    --s3-prefix powerbi/2026-04 \
    --s3-kms-key alias/pbi-reports \
    --s3-storage-class INTELLIGENT_TIERING

# Using a named AWS profile
python Get-PBIWorkspaceUsageReport.py ... \
    --s3-bucket my-pbi-reports \
    --s3-profile my-aws-profile

All 7 output files (+ summary text) are uploaded. S3 failures are reported per-file and do not abort the run.


Common Issues

Symptom Cause Fix
401 Unauthorized Admin API tenant setting not enabled Enable "Service principals can access read-only admin APIs" in Fabric Admin Portal
0 workspaces returned Insufficient PBI permissions Verify Tenant.Read.All + admin API gate
0 activity events / per-day 400 errors Dates outside retention window Use --activity-days 30; only go higher on Fabric/Premium
AADSTS50076 (MFA) ROPC blocked by MFA policy Exclude service account from MFA CA, or use -UseInteractiveAuth
AADSTS90010 (public client) ROPC app not configured Enable "Allow public client flows" on app registration
StorageUsedMB is null Shared-capacity workspace Expected β€” only populated for Premium/Fabric workspaces
Device types all "Unknown" ClientType used (wrong field) Fixed in v1.4 β€” uses ConsumptionMethod / UserAgent parsing
pip install boto3 error S3 feature not needed Omit --s3-bucket to skip upload entirely
AWS.Tools.S3 module required PS S3 module missing Install-Module AWS.Tools.S3 -Scope CurrentUser

Identify Stale Reports

# PowerShell β€” filter zero-view reports from the usage CSV
$usage = Import-Csv "C:\Reports\PBI\PBI_Report_Usage_*.csv" | Select-Object -Last 1 -ExpandProperty PSPath |
    ForEach-Object { Import-Csv $_ }
$stale = Import-Csv (Get-ChildItem "C:\Reports\PBI\PBI_Report_Usage_*.csv" | Sort-Object LastWriteTime -Descending | Select-Object -First 1)
        | Where-Object { [int]$_.TotalViews_90d -eq 0 }
Write-Host "Stale reports: $($stale.Count)"
$stale | Select-Object ReportName, WorkspaceName, WorkspaceType | Format-Table
# Python β€” find stale reports
import csv
with open("PBI_Report_Usage_20260403_120000.csv") as f:
    stale = [r for r in csv.DictReader(f) if int(r["TotalViews_90d"]) == 0]
print(f"Stale reports: {len(stale)}")

Version History

Version Date Changes
v1.6.0 2026-05-07 PowerShell S3 upload β€” -PublishToS3, -S3BucketName, -S3KeyPrefix, -S3Region, -S3ProfileName (requires AWS.Tools.S3)
v1.5.1 2026-04-03 Python port β€” S3 upload (upload_to_s3), all PS features parity
v1.5.0 2026-04-03 Dataset health export (PBI_Dataset_Health): TargetStorageMode, StorageCategory, IsRefreshable, gateway flag; -IncludeRefreshHistory switch for last refresh per dataset
v1.4.0 2026-03-31 Workspace size export (PBI_Workspace_Size): StorageUsedMB, dataset/report count; Device type breakdown using ConsumptionMethod / UserAgent (fixes ClientType not-a-field bug)
v1.3.0 2026-03-26 ROPC / service account auth (-Username / -Password)
v1.2.0 2026-03-20 -UseInteractiveAuth via MicrosoftPowerBIMgmt; default ActivityDays 90 β†’ 30
v1.1.0 2026-03-12 Pre-flight validation, improved error handling, verbose logging
v1.0.0 β€” Initial release β€” core inventory + usage correlation

See Also

Clone this wiki locally