BPA scanning for Fabric semantic models in Pro workspaces — no Premium capacity or XMLA endpoints required.
Combines Fabric CLI (REST API extraction) with Tabular Editor 2 (BPA rule engine) to analyze semantic models headlessly, enabling CI/CD automation for any Fabric workspace.
| Approach | XMLA Required | Premium Required | CI/CD Ready |
|---|---|---|---|
| Tabular Editor direct | Yes | Yes | Partial |
| Fabric Notebooks (semantic-link-labs) | No | Yes | Partial |
| This tool | No | No | Yes |
# Scan all models in a workspace (.Workspace suffix optional)
./scan-workspaces.ps1 -Workspaces "YourWorkspace"
# Scan multiple workspaces
./scan-workspaces.ps1 -Workspaces "Production", "Development"
# Scan specific model
./scan-workspaces.ps1 -Workspaces "YourWorkspace" -Model "YourModel.SemanticModel"
# Filter by pattern
./scan-workspaces.ps1 -Workspaces "YourWorkspace" -Filter "Sales.*"
# With custom rules
./scan-workspaces.ps1 -Workspaces "YourWorkspace" -CustomRulesFile "./my-rules.json"See docs/architecture.md for detailed component documentation.
| Parameter | Required | Description |
|---|---|---|
-Workspaces |
Yes | One or more workspace names (.Workspace suffix optional) |
-Model |
No | Specific model to scan (.SemanticModel suffix required) |
-Filter |
No | Regex pattern to filter models |
-RulesFile |
No | Path to BPA rules JSON (default: ./BPARules-PowerBI.json) |
-CustomRulesFile |
No | Path to custom rules JSON (merged with default rules) |
-OutputDir |
No | Output directory for reports (default: ./output) |
# Python dashboard (recommended)
python bpa-dashboard.py
# Or process JSON directly
cat output/bpa-analysis-*.json | jq '.violations'See PREREQUISITES.md for installation requirements:
- Fabric CLI (
fab) - https://aka.ms/fabric-cli - Tabular Editor 2 - https://github.com/TabularEditor/TabularEditor/releases
- PowerShell 5.1+
- Python 3.8+ with
richlibrary (for dashboard only)
{
"metadata": {
"timestamp": "2025-12-15T12:00:00Z",
"model": "Sales Model",
"workspace": "Production"
},
"modelStructure": {
"tables": 10,
"measures": 25,
"relationships": 8
},
"violations": [
{
"rule": "DAX_DIVISION_COLUMNS",
"object": "Sales.Revenue Ratio",
"severity": 3,
"message": "Avoid division (use DIVIDE function instead)"
}
]
}| Level | Name | Action |
|---|---|---|
| 3 | Error | Fix before deployment |
| 2 | Warning | Consider fixing |
| 1 | Info | Optional improvement |
See .github/workflows/bpa-scan.yml for a GitHub Actions template.
Required secrets:
FABRIC_CLIENT_ID- Service principal app IDFABRIC_CLIENT_SECRET- Service principal secretFABRIC_TENANT_ID- Azure AD tenant ID
pro-bpa-scanner/
├── scan-workspaces.ps1 # Main scanner entry point
├── lib/ # PowerShell modules
│ ├── Discover-Models.ps1 # Workspace model discovery
│ ├── Extract-Model.ps1 # TMDL extraction via Fabric CLI
│ ├── Analyze-Model.ps1 # BPA analysis via Tabular Editor 2
│ └── Format-Report.ps1 # JSON report generation
├── bpa_dashboard/ # Python dashboard package
├── bpa-dashboard.py # Dashboard entry point
├── BPARules-PowerBI.json # BPA rule definitions
├── output/ # JSON analysis reports (generated)
├── temp/ # TMDL extraction (temporary, auto-cleaned)
└── PREREQUISITES.md # Installation guide
When comparing scanner results with Tabular Editor 3 GUI connected directly to a model, the scanner may report fewer violations. This is due to a limitation in Tabular Editor 2 CLI mode when analyzing TMDL exports.
Affected rules (violations on Calculated Table Columns may be missed):
APPLY_FORMAT_STRING_COLUMNS- Provide format string for visible numeric columnsMETA_AVOID_FLOAT- Do not use floating point data typesMETA_SUMMARIZE_NONE- Don't summarize numeric columns
Root cause: Tabular Editor 2 CLI analyzing TMDL exports does not evaluate certain metadata rules against Calculated Table Columns the same way TE3 GUI does when connected to a live model.
Impact: Scanner results are directionally accurate but may undercount by ~5-15% for models with many Calculated Table Columns. Critical violations (DAX issues, unused columns, relationship naming) are fully detected.
- Kurt Buhler - fabric-cli reference documentation used in developing this solution
- Kurt Buhler - claude-goblin TUI design that inspired the dashboard
- Daniel Otykier - Tabular Editor and Best Practice Analyzer
- TabularEditor/BestPracticeRules - Official BPA rule definitions


