Installs into .claude/skills of the current project.
Are you the author of Power Bi?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/chrishuffman5-power-bi)
---
name: power-bi
description: "Microsoft Power BI expert. Deep expertise in semantic models, DAX, Power Query (M), storage modes, Fabric integration, report design, and governance. WHEN: \"Power BI\", \"Power BI Desktop\", \"Power BI Service\", \"DAX\", \"DAX formula\", \"DAX measure\", \"CALCULATE\", \"filter context\", \"row context\", \"Power Query\", \"M language\", \"query folding\", \"VertiPaq\", \"DirectQuery\", \"Direct Lake\", \"semantic model\", \"Power BI dataset\", \"Power BI report\", \"Power BI dashboard\", \"Power BI Embedded\", \"Power BI gateway\", \"Power BI refresh\", \"paginated report\", \"RDL\", \"PBIX\", \"PBIR\", \"Power BI capacity\", \"PPU\", \"Power BI Premium\", \"Fabric Power BI\", \"Power BI Copilot\", \"Power BI RLS\", \"deployment pipeline Power BI\"."
license: MIT
---
# Power BI
This skill covers Microsoft Power BI, the business intelligence and analytics platform now deeply integrated with Microsoft Fabric, in depth:
- Semantic model design (star schema, relationships, calculation groups, hierarchies)
- DAX (measures, calculated columns, row context, filter context, CALCULATE, time intelligence, visual calculations)
- Power Query / M language (transformations, query folding, dataflows Gen2)
- Storage modes (Import/VertiPaq, DirectQuery, Direct Lake, Dual, Composite)
- Power BI Service (workspaces, apps, deployment pipelines, XMLA endpoints, git integration)
- Fabric integration (OneLake, Direct Lake, Data Factory, Real-Time Intelligence)
- Embedded analytics (app-owns-data, user-owns-data, service principal auth)
- Paginated reports (RDL format, Report Builder, pixel-perfect output)
- AI features (Copilot, Q&A, Key Influencers, Smart Narratives)
- Security (RLS, OLS, workspace roles, sensitivity labels)
- Licensing (Free, Pro, PPU, Fabric F-SKUs)
Power BI is a managed service with monthly releases. There are no discrete version agents -- guidance applies to the current platform.
## How to Approach Tasks
1. **Classify** the request:
- **Data modeling / DAX** -- Load `references/architecture.md` for VertiPaq internals, DAX evaluation contexts, storage mode mechanics
- **Performance / troubleshooting** -- Load `references/diagnostics.md` for Performance Analyzer, DAX Studio, gateway issues, capacity management, refresh failures
- **Best practices / governance** -- Load `references/best-practices.md` for star schema, DAX optimization, Power Query, report design, security, ALM
- **Fabric / platform architecture** -- Load `references/architecture.md` for Service architecture, Fabric convergence, Direct Lake
2. **Determine scope** -- Identify whether the question is about Desktop authoring, Service administration, Embedded development, or Fabric integration. Behavior and licensing differ across these contexts.
3. **Load context** -- Read the relevant reference file for deep technical detail.
4. **Analyze** -- Apply Power BI-specific reasoning. Consider storage mode, filter context, relationship directions, and capacity licensing.
5. **Recommend** -- Provide actionable guidance with DAX examples, Power Query patterns, or configuration steps.
6. **Verify** -- Suggest validation steps (Performance Analyzer, DAX Studio Server Timings, "View as" role testing, VertiPaq Analyzer).
## Ecosystem
```
┌──────────────────────────────────────────────────────────┐
│ Microsoft Fabric │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────────┐ │
│ │ Data │ │ Synapse │ │ Real-Time│ │ Data │ │
│ │ Factory │ │ Eng/DS │ │ Intel │ │ Activator │ │
│ └─────┬────┘ └────┬─────┘ └────┬─────┘ └─────┬──────┘ │
│ │ │ │ │ │
│ └───────────┴─────┬──────┴──────────────┘ │
│ ┌─────▼─────┐ │
│ │ OneLake │ Delta / Parquet │
│ └─────┬─────┘ │
│ │ │
│ ┌───────────────┼──────────────┐ │
│ │ │ │ │
│ ┌──────▼──────┐ ┌──────▼─────┐ ┌─────▼──────┐ │
│ │ Direct Lake │ │ Import │ │DirectQuery │ │
│ │ (Fabric) │ │ (VertiPaq) │ │ (Source DB)│ │
│ └──────┬──────┘ └──────┬─────┘ └─────┬──────┘ │
│ └───────────────┼──────────────┘ │
│ ┌─────▼──────┐ │
│ │ Semantic │ │
│ │ Model │ │
│ └─────┬──────┘ │
│ ┌──────────────┼──────────────┐ │
│ ┌──────▼──────┐ ┌─────▼─────┐ ┌──────▼──────┐ │
│ │ Reports │ │Dashboards │ │ Paginated │ │
│ │ (.pbix/r) │ │ (tiles) │ │ (.rdl) │ │
│ └──────┬──────┘ └─────┬─────┘ └──────┬──────┘ │
└───────────┼──────────────┼──────────────┼────────────────┘
│ │ │
┌──────▼──────┐ ┌────▼─────┐ ┌──────▼──────┐
│ PBI Desktop │ │PBI Mobile│ │ PBI Embedded│
└─────────────┘ └──────────┘ └─────────────┘
```
| Component | Purpose | Platform |
|---|---|---|
| **Power BI Desktop** | Report authoring, data modeling, DAX/Power Query development | Windows desktop app |
| **Power BI Service** | Cloud sharing, collaboration, scheduled refresh, apps, web authoring | Web (app.powerbi.com) |
| **Power BI Mobile** | Dashboard consumption, offline caching, push notifications | iOS, Android |
| **Power BI Report Server** | On-premises report hosting; updated 3x/year; feature lag vs cloud | Windows Server |
| **Power BI Embedded** | Embed analytics in custom apps (app-owns-data / user-owns-data) | Azure / Fabric |
| **Microsoft Fabric** | Unified analytics platform; OneLake, Direct Lake, lakehouses | Cloud SaaS |
### Desktop vs Service Authoring
Desktop remains the primary tool for production-quality reports with complex data models. Key Desktop-only features include Performance Analyzer, What-If Parameters, and the full relationship diagram view. The Service achieved core modeling parity in September 2025 (Power Query, DAX measures, RLS, calculation groups), enabling Mac users and browser-only workflows for lighter authoring scenarios.
## Semantic Model Architecture
The semantic model (formerly "dataset") is the analytical engine between raw data and report visuals.
**Core elements:**
- **Tables** -- Imported, DirectQuery, Direct Lake, or Dual storage
- **Relationships** -- One-to-many preferred; single cross-filter direction; avoid bidirectional at the model level
- **Measures** -- DAX formulas evaluated at query time against filter context; preferred over calculated columns
- **Calculated columns** -- DAX evaluated row-by-row at refresh time; stored in model; avoid when a measure suffices
- **Calculation groups** -- Reusable DAX logic applied as calculation items; eliminates redundant time intelligence variants
- **Hierarchies** -- User-defined drill paths (Year > Quarter > Month > Day)
- **Field parameters** -- Let report readers dynamically switch measures or dimensions in visuals
**Perspectives:** Subsets of the model exposed to simplify the user experience for specific audiences. Do not provide security -- use RLS/OLS for access control.
**Editing locations:** Semantic models can be created and edited in both Desktop and Service (web authoring GA Sept 2025). Desktop remains recommended for complex production models. Web authoring supports: Power Query transformations, relationship management, DAX measures, RLS definition, DAX Query View, and calculation groups.
## DAX Fundamentals
### Evaluation Contexts
| Context | Description | Created By |
|---|---|---|
| **Row context** | Expression evaluated for each row individually | Calculated columns, iterators (SUMX, FILTER) |
| **Filter context** | Set of active filters from slicers, visuals, DAX | Report interactions, CALCULATE, CALCULATETABLE |
### CALCULATE -- The Core Function
CALCULATE modifies filter context before performing a calculation. It is the most important DAX function.
```dax
-- Override filter context: show total regardless of slicer selection
Total Sales All Regions =
CALCULATE([Total Sales], REMOVEFILTERS('Geography'))
-- Add filter: restrict to specific category
Electronics Sales =
CALCULATE([Total Sales], 'Product'[Category] = "Electronics")
```
**Context transition:** When CALCULATE is used inside a row context (e.g., inside SUMX), it converts the current row context into an equivalent filter context. This is powerful but can be a performance trap in iterators on large tables.
### Key Patterns
- **Variables (VAR/RETURN)** -- Evaluate once per query context; the single best performance optimization technique
- **Time intelligence** -- DATESYTD, SAMEPERIODLASTYEAR, DATEADD; use only in CALCULATE filter arguments; requires a proper date table with no gaps
- **Iterators** -- SUMX, COUNTX, AVERAGEX, FILTER run in the single-threaded Formula Engine; prefer native aggregations (SUM, COUNT) on large tables
- **Visual calculations** -- DAX scoped to the visual level; RUNNINGSUM, MOVINGAVERAGE, RANK; avoids complex model-level measures for visual-specific needs
- **Calculation groups** -- Define reusable DAX patterns (e.g., YTD, PY, PY YTD) as calculation items; dramatically reduces measure count in enterprise models
### Common Measure Patterns
```dax
-- Year-over-year with safe division
YoY % Change =
VAR CurrentSales = [Total Sales]
VAR PriorYear = CALCULATE([Total Sales], SAMEPERIODLASTYEAR('Date'[Date]))
RETURN DIVIDE(CurrentSales - PriorYear, PriorYear)
-- Running total using visual calculations (preferred for visual-level running totals)
-- In visual calculation pane: Running Total = RUNNINGSUM([Total Sales])
-- Dynamic ranking
Product Rank =
VAR CurrentValue = [Total Sales]
RETURN
COUNTROWS(
FILTER(
ALLSELECTED('Product'[ProductName]),
[Total Sales] > CurrentValue
)
) + 1
```
### DAX Query View
Available in both Desktop and Service for ad-hoc DAX exploration. Write EVALUATE queries to test measures, inspect filter context, and validate calculation logic without building visuals. Export results to tables for quick data validation.
## Power Query (M Language)
Power Query is the data transformation engine, using the M functional programming language.
**Query folding** is the most critical optimization -- it translates transformation steps into native source queries (SQL) for server-side processing:
- Put foldable steps first (filter, column selection, joins, aggregations)
- Delay non-foldable steps (custom columns, complex text transforms)
- Check folding: right-click a step > "View Native Query" -- greyed out means folding broke
- Use native connectors (SQL Server connector over ODBC) for better folding support
**Common folding breakers:**
- Adding custom columns with complex M logic
- Using Table.Buffer
- Merging queries from different data sources
- List.Generate or custom functions
**Staging query pattern:** Create a staging query that folds completely to the source (filters, column selection), then build dependent queries that apply non-foldable transforms. Disable load on staging queries ("Enable load" unchecked) so they don't load into the model.
**Dataflows:**
- **Gen1** -- Legacy; moving to end of active innovation
- **Gen2** -- Fabric-native; separated ETL/destination; Copilot-assisted; all new investment here
## Storage Modes
| Mode | Engine | Data Location | Freshness | Best For |
|---|---|---|---|---|
| **Import** | VertiPaq (in-memory columnar) | Compressed in model | Scheduled refresh | Most scenarios; best query performance |
| **DirectQuery** | Source database | Lives at source | Real-time | Large datasets, real-time requirements |
| **Direct Lake** | VertiPaq from Delta | OneLake (Delta/Parquet) | Near real-time | Fabric; large data; no import needed |
| **Dual** | Both Import + DirectQuery | Cached + source | Depends on query | Aggregation tables |
| **Composite** | Mix of modes per table | Multiple locations | Varies | Flexibility across sources |
**Import** is the default and preferred for most scenarios. Data is compressed in VertiPaq columnar store with the fastest query performance. Limited by model size (1 GB shared, 10 GB+ Premium). Requires scheduled refresh to update data.
**DirectQuery** sends queries to the source database at runtime. No data is copied. Real-time freshness but higher latency (1-10 seconds per query). Source must be optimized with proper indexes. Each visual generates a separate source query.
**Direct Lake** (GA March 2026) reads Delta tables directly from OneLake without import. Combines Import-like performance with DirectQuery-like freshness. Available only in Microsoft Fabric. Uses "framing" to capture Delta table snapshots. Falls back to DirectQuery via SQL analytics endpoint when data exceeds memory. Supports composite models mixing Direct Lake + Import tables.
**Composite models** allow mixing storage modes per table within a single semantic model. Common pattern: Import for dimensions (fast filtering), DirectQuery for large fact tables (real-time). Aggregation tables in Dual mode serve 95%+ of queries from cache while detail queries hit the source on demand.
## Fabric Integration
Power BI is the analytics/visualization layer within Fabric. Microsoft's strategy converges all data workloads under Fabric with Power BI as the primary consumption experience.
**Key Fabric workloads integrated with Power BI:**
- **OneLake** -- Unified data lake; Delta/Parquet format; foundation for Direct Lake mode; semantic models can write imported data to OneLake Delta tables automatically
- **Data Factory** -- Data integration and orchestration (replaces standalone dataflows for complex ETL)
- **Synapse Data Engineering** -- Spark-based data processing; writes Delta tables to OneLake consumed via Direct Lake
- **Real-Time Intelligence** -- Replacing deprecated streaming datasets (push/streaming/PubNub retiring Oct 2027); use Eventstreams and KQL databases for real-time analytics
- **Data Activator** -- Event-driven triggers from data changes; automate actions based on conditions in Power BI reports
**Standalone Power BI vs Fabric:** Standalone Pro/PPU licensing remains available, but OneLake, Direct Lake, Data Factory, Synapse, and Real-Time Intelligence are Fabric-only capabilities. Organizations with complex data engineering needs should evaluate Fabric; pure BI consumers can remain on standalone licensing.
**Streaming data migration:** Legacy push, streaming, and PubNub dataset types are deprecated (retiring October 2027). Migrate to Real-Time Intelligence in Fabric using Eventstreams for ingestion and KQL databases for real-time querying.
## Paginated Reports
Pixel-perfect, print-optimized reports using RDL (Report Definition Language) format:
- Authored in Power BI Report Builder (free desktop tool) or web-based editor
- Export to PDF, Excel, Word, CSV, XML, MHTML
- Ideal for invoices, statements, regulatory reports, multi-page tabular data
- Can connect to Power BI semantic models as data source
- Require PPU or Fabric F64+ capacity for sharing
- Parameters allow users to filter data before rendering; cascading parameters for dependent filters
- Subreports for nested/repeated report sections
- Not a replacement for interactive Power BI reports -- use paginated reports when exact print layout and multi-page tabular exports are required
## Embedded Analytics
Two embedding scenarios with different authentication and licensing models:
| Scenario | Auth Model | Licensing | Best For |
|---|---|---|---|
| **App-Owns-Data** (Embed for Customers) | Service principal (certificate-based) | F-SKU capacity; users need no PBI license | ISVs, customer-facing apps |
| **User-Owns-Data** (Embed for Your Org) | User's Entra ID token | Pro license per user (or F64+ for viewers) | Internal portals, intranets |
**App-Owns-Data best practices:**
- Always use service principal authentication (no MFA, no password expiry, certificate-based)
- Never use master user accounts in production
- JavaScript SDK (`powerbi-client`) for iframe-based embedding
- Enforce RLS through effective identity tokens in the embed call
- F64 is the minimum SKU for unlimited content viewers
## Security Model
### Layered Security
1. **Workspace roles** -- Admin, Member, Contributor, Viewer; controls who can access the workspace
2. **Row-Level Security (RLS)** -- DAX filter expressions restricting which rows users see; dynamic RLS uses USERPRINCIPALNAME()
3. **Object-Level Security (OLS)** -- Hides entire tables or columns; only enforced in Premium/PPU/Fabric capacity; define via Tabular Editor or XMLA
4. **Sensitivity labels** -- Microsoft Purview integration for data classification; carry through on export
**RLS implementation:**
- Define roles in Desktop or Service with DAX filter expressions
- Static: `[Region] = "West"` -- hardcoded filter
- Dynamic: `[SalesRep_Email] = USERPRINCIPALNAME()` -- filters by logged-in user
- Always test with "View as" role before production deployment
- Combine with OLS when certain columns must be hidden entirely from specific roles
## AI Features
- **Copilot** -- Chat-based analysis, report creation, DAX formula assistance; replacing Q&A as primary NL interface (Q&A retiring late 2026); requires PPU or Fabric capacity
- **Key Influencers** -- Identifies factors driving a metric
- **Decomposition Tree** -- Interactive root-cause analysis
- **Smart Narratives** -- Auto-generated text summaries
- **Anomaly Detection / Forecasting** -- Outlier detection and statistical predictions on time series
**AI governance:** Admins can control which AI features Copilot leverages via tenant settings. Mark AI visuals as "Approved for Copilot" for compliance-aware adoption.
## Licensing
| Tier | Cost | Key Capabilities |
|---|---|---|
| **Free** | $0 | Personal analytics in My Workspace; no sharing |
| **Pro** | $14/user/month | Share, collaborate, 8 refreshes/day, RLS, apps, Q&A |
| **PPU** | $24/user/month | Pro + paginated reports, 48 refreshes/day, AI visuals, Copilot, XMLA, deployment pipelines, dataflows |
| **Fabric F64+** | ~$5,069+/month | All PPU features + unlimited viewers (no Pro needed), all Fabric workloads, Direct Lake, Azure metered billing, pause/resume |
**Critical:** F2-F32 SKUs include Fabric workloads but do NOT include Power BI Premium features (paginated reports, XMLA, deployment pipelines, unlimited viewers). F64 is the minimum for full Power BI Premium capability.
**P-SKUs are fully retired** (late 2025). All customers transitioned to Fabric F-SKUs.
## Power BI Service Capabilities
### Workspaces and Apps
- Workspaces are organizational containers for reports, semantic models, dataflows, datamarts
- Apps are curated, read-only packages published from workspaces to broader audiences; support audience targeting
- Use Azure AD/Entra ID groups for workspace role assignment, not individual users
- Workspace roles: Admin > Member > Contributor > Viewer (principle of least privilege)
### Deployment and ALM
- **Deployment pipelines**: Built-in ALM with 2-10 stages (Dev, Test, Prod); compare and deploy selectively; automate via REST API; requires Premium or PPU
- **XMLA endpoint**: Read/write access for third-party tools (Tabular Editor, DAX Studio, ALM Toolkit); enables scripted CI/CD deployments; available in PPU and F64+
- **PBIR format**: JSON-based report format for git integration; becoming default April 2026; enables meaningful diffs and branch-based development
- **TMDL**: Tabular Model Definition Language for semantic model definitions in source control
### Development Tools
| Tool | Purpose | Cost |
|---|---|---|
| **Tabular Editor 2** | Model editing, Best Practice Analyzer | Free |
| **Tabular Editor 3** | Full IDE: IntelliSense, VertiPaq Analyzer, diagrams | Commercial |
| **DAX Studio** | DAX queries, Server Timings, VertiPaq analysis | Free |
| **ALM Toolkit** | Schema comparison and deployment | Free |
## Anti-Patterns
| Anti-Pattern | Problem | Correct Approach |
|---|---|---|
| Bidirectional relationships everywhere | Ambiguous results, slow queries, unpredictable DAX | Single-direction cross-filter; use DAX CROSSFILTER per-measure |
| Calculated columns instead of measures | Consumes storage, evaluated at refresh not query time | Use measures; they evaluate at query time and don't store data |
| Iterator on multi-million-row fact table | Single-threaded Formula Engine bottleneck | Pre-compute column in Power Query or use native aggregations |
| No date table (relying on auto date/time) | Bloated model, limited time intelligence | Create dedicated date table; mark as date table; disable auto date/time |
| 20+ visuals per report page | Slow load, excessive parallel queries | Limit to 8 visuals per page; use drillthrough for detail |
| FILTER on large table in CALCULATE | Materializes entire table in Formula Engine | Use column filter predicates directly in CALCULATE arguments |
| Nested CALCULATE calls | Hard to reason about filter context, performance cost | Restructure with VAR/RETURN to separate computation from context modification |
| No query folding awareness | Full data pulled into Power Query engine | Structure steps to maintain folding; check with "View Native Query" |
| Skipping RLS testing | Data leaks in production | Always test with "View as" role and DAX Studio before deployment |
| Manual ALM (copy/paste between environments) | Error-prone, no audit trail | Use deployment pipelines + PBIR format + git integration |
| SELECT * in Power Query | Loads all columns including unused ones | Select only needed columns; remove others early |
| Ignoring referential integrity | Orphan keys bloat model, cause blank rows in visuals | Clean orphan keys in Power Query; validate key relationships |
| Using Report Server for new deployments | Feature lag, no AI, no Direct Lake, no monthly updates | Use Power BI Service unless regulatory/compliance mandates on-premises |
| All refreshes at midnight | Capacity contention, throttling | Stagger refresh schedules across 2-hour windows |
## Cross-References
- `ssas` skill, this plugin -- SSAS/Tabular model overlap (shared VertiPaq engine, DAX, XMLA protocol)
- `sql-server` skill, database plugin -- SQL Server as common data source; query folding targets SQL
- `overview` skill, this plugin -- technology comparison and selection guidance across BI tools
## Reference Files
- `references/architecture.md` -- VertiPaq engine internals, DirectQuery mechanics, Direct Lake architecture, Service architecture, Fabric convergence, DAX evaluation engine details
- `references/best-practices.md` -- Star schema modeling, DAX performance, Power Query optimization, report design, deployment/ALM, security/governance, large dataset strategies
- `references/diagnostics.md` -- Performance Analyzer workflow, DAX Studio analysis, VertiPaq Analyzer, gateway troubleshooting, capacity management, refresh failure diagnosis
## Diagnostic Scripts
Ready-made PowerShell (MicrosoftPowerBIMgmt / SqlServer modules) in `scripts/`, numbered by investigation order. All read-only; placeholders are `__UPPER_SNAKE__` tokens.
- `scripts/01-workspace-inventory.ps1` -- Tenant-wide workspace/dataset/report inventory (admin scope)
- `scripts/02-activity-events.ps1` -- One day of tenant activity events (usage audit, export forensics)
- `scripts/03-dataset-refresh-history.ps1` -- Refresh history with status, duration, failure cause
- `scripts/04-xmla-model-memory.ps1` -- Table sizes of a Premium model via XMLA DMV; the full SSAS DMV pack in the `ssas` skill's `scripts/` works against the same endpoint