Files
2025-11-29 18:18:03 +08:00

5.4 KiB

Report Operations

Get Report Info

# Check exists
fab exists "ws.Workspace/Report.Report"

# Get properties
fab get "ws.Workspace/Report.Report"

# Get ID
fab get "ws.Workspace/Report.Report" -q "id"

Get Report Definition

# Full definition
fab get "ws.Workspace/Report.Report" -q "definition"

# Save to file
fab get "ws.Workspace/Report.Report" -q "definition" -o /tmp/report-def.json

# Specific parts
fab get "ws.Workspace/Report.Report" -q "definition.parts[?path=='definition/report.json'].payload | [0]"

Get Connected Model

# Get model reference from definition.pbir
fab get "ws.Workspace/Report.Report" -q "definition.parts[?contains(path, 'definition.pbir')].payload | [0]"

Output shows byConnection.connectionString with semanticmodelid.

Export Report

  1. Export to local directory:
fab export "ws.Workspace/Report.Report" -o /tmp/exports -f
  1. Creates structure:
Report.Report/
├── .platform
├── definition.pbir
└── definition/
    ├── report.json
    ├── version.json
    └── pages/
        └── {page-id}/
            ├── page.json
            └── visuals/{visual-id}/visual.json

Import Report

  1. Import from local PBIP:
fab import "ws.Workspace/Report.Report" -i /tmp/exports/Report.Report -f
  1. Import with new name:
fab import "ws.Workspace/NewName.Report" -i /tmp/exports/Report.Report -f

Copy Report Between Workspaces

fab cp "dev.Workspace/Report.Report" "prod.Workspace" -f

Create Blank Report

  1. Get model ID:
fab get "ws.Workspace/Model.SemanticModel" -q "id"
  1. Create report via API:
WS_ID=$(fab get "ws.Workspace" -q "id" | tr -d '"')
fab api -X post "workspaces/$WS_ID/reports" -i '{
  "displayName": "New Report",
  "datasetId": "<model-id>"
}'

Update Report Properties

# Rename
fab set "ws.Workspace/Report.Report" -q displayName -i "New Name"

# Update description
fab set "ws.Workspace/Report.Report" -q description -i "Description text"

Rebind to Different Model

  1. Get new model ID:
fab get "ws.Workspace/NewModel.SemanticModel" -q "id"
  1. Rebind:
fab set "ws.Workspace/Report.Report" -q semanticModelId -i "<new-model-id>"

Delete Report

fab rm "ws.Workspace/Report.Report" -f

List Pages

fab get "ws.Workspace/Report.Report" -q "definition.parts[?contains(path, 'page.json')].path"

List Visuals

fab get "ws.Workspace/Report.Report" -q "definition.parts[?contains(path, '/visuals/')].path"

Count Visuals by Type

  1. Export visuals:
fab get "ws.Workspace/Report.Report" -q "definition.parts[?contains(path,'/visuals/')]" > /tmp/visuals.json
  1. Count by type:
jq -r '.[] | .payload.visual.visualType' < /tmp/visuals.json | sort | uniq -c | sort -rn

Extract Fields Used in Report

  1. Export visuals (if not done):
fab get "ws.Workspace/Report.Report" -q "definition.parts[?contains(path,'/visuals/')]" > /tmp/visuals.json
  1. List unique fields:
jq -r '[.[] | (.payload.visual.query.queryState // {} | to_entries[] | .value.projections[]? | if .field.Column then "\(.field.Column.Expression.SourceRef.Entity).\(.field.Column.Property)" elif .field.Measure then "\(.field.Measure.Expression.SourceRef.Entity).\(.field.Measure.Property)" else empty end)] | unique | sort | .[]' < /tmp/visuals.json

Validate Fields Against Model

  1. Export report:
fab export "ws.Workspace/Report.Report" -o /tmp/report -f
  1. Extract field references:
find /tmp/report -name "visual.json" -exec grep -B2 '"Property":' {} \; | \
  grep -E '"Entity":|"Property":' | paste -d' ' - - | \
  sed 's/.*"Entity": "\([^"]*\)".*"Property": "\([^"]*\)".*/\1.\2/' | sort -u
  1. Compare against model definition to find missing fields.

Report Permissions

  1. Get IDs:
WS_ID=$(fab get "ws.Workspace" -q "id" | tr -d '"')
REPORT_ID=$(fab get "ws.Workspace/Report.Report" -q "id" | tr -d '"')
  1. List users:
fab api -A powerbi "groups/$WS_ID/reports/$REPORT_ID/users"
  1. Add user:
fab api -A powerbi "groups/$WS_ID/reports/$REPORT_ID/users" -X post -i '{
  "emailAddress": "user@domain.com",
  "reportUserAccessRight": "View"
}'

Deploy Report (Dev to Prod)

  1. Export from dev:
fab export "dev.Workspace/Report.Report" -o /tmp/deploy -f
  1. Import to prod:
fab import "prod.Workspace/Report.Report" -i /tmp/deploy/Report.Report -f
  1. Verify:
fab exists "prod.Workspace/Report.Report"

Clone Report with Different Model

  1. Export source:
fab export "ws.Workspace/Template.Report" -o /tmp/clone -f
  1. Edit /tmp/clone/Template.Report/definition.pbir to update semanticmodelid

  2. Import as new report:

fab import "ws.Workspace/NewReport.Report" -i /tmp/clone/Template.Report -f

Troubleshooting

Report Not Found

fab exists "ws.Workspace"
fab ls "ws.Workspace" | grep -i report

Model Binding Issues

# Check current binding
fab get "ws.Workspace/Report.Report" -q "definition.parts[?contains(path, 'definition.pbir')].payload | [0]"

# Rebind
fab set "ws.Workspace/Report.Report" -q semanticModelId -i "<model-id>"

Import Fails

# Verify structure
ls -R /tmp/exports/Report.Report/

# Check definition is valid JSON
fab get "ws.Workspace/Report.Report" -q "definition" | jq . > /dev/null && echo "Valid"