What it does
Surfaces Power BI reports and dashboards inside a model-driven app — as a system dashboard page, as a personal dashboard tile, or embedded directly in a main form where it can be filtered by the record you're looking at. It's how you get cross-system aggregate reporting into the same app as the Dataverse data.
Key facts
- The Power BI embedded system dashboard is a first-class solution component. You create it in the maker portal via New > Dashboards > Power BI embedded, pick a workspace and a report or dashboard, and add it to the app as a dashboard page.
- System dashboards and form embedding ignore the Power Platform admin centre Power BI visualization embedding environment setting. That setting only governs whether end users can add Power BI content to their own personal dashboards, views and charts.
- Personal dashboard embedding needs the org setting enabled, a Power BI account with access to at least one dashboard, and third-party cookies allowed in the browser — otherwise auth to Power BI fails silently.
- Embedding a report in a main form isn't a form designer operation. You add a placeholder subgrid, export the unmanaged solution, replace the
<control>block in customizations.xml with the Power BI control (class ID{8C54228C-1B25-4909-A12A-F2B968BB0D62}), and reimport. - Contextual filtering is done with a
<PowerBIFilter>element that maps Dataverse column values onto Power BI table/column filters via aliases. Tiles can only be embedded without contextual filtering. - Dataverse security roles have no effect on what the report shows. The user sees what the semantic model author would see. Row-level security in Power BI is the only lever.
- Cross-tenant embedding isn't supported, even if the report has been shared with users in the other tenant.
- Users are signed in to Power BI automatically using their Power Apps identity. If no matching Power BI account exists, they get a sign-in prompt inside the form.
When to use / skip
Use it when the question the user is asking genuinely spans systems or needs aggregation that Dataverse charts can't do — trend over time, comparison against targets from a finance system, anything with a proper date table behind it. Skip it when a native chart or view would answer the question, because the native ones inherit Dataverse security for free and load instantly. The moment you embed Power BI you've taken on a second security model, a second licensing conversation and a refresh latency the users didn't have before. That's fine when it buys something. It's a bad trade for a bar chart of open cases by owner.
Configuration decisions
- Whether the report goes on a dashboard page (whole-app context) or on a form (record context) — and whether the form case really needs contextual filtering or just a consistent summary.
- Whether the workspace and report references are hard-coded or driven by an environment variable, which is the difference between a clean ALM story and hand-editing after every deployment.
- How the Power BI RLS model reproduces the Dataverse security model, and how much of it you're honestly willing to reproduce.
- Whether the source is the Dataverse connector, Azure Synapse Link, or Fabric — which sets your refresh latency and therefore what users can expect.
- Which Power BI licence the app's user population holds, given that Dynamics 365 licences don't automatically cover Power BI content consumption.
Gotchas
- Reproducing Dataverse security in RLS is the whole job, not a detail. Business units, hierarchies, team ownership and sharing don't map to a DAX filter without deliberate design, and "the report shows everything" is a real incident when it hits go-live.
- The form designer can't render the embedded control usefully, because the customisation was made outside it. Expect it to look broken in the designer and fine at runtime.
- If the report doesn't appear after importing the solution, open the form in the designer and save it so the form JSON regenerates. This one wastes an afternoon if you don't know it.
- Data type mismatches between the Dataverse column and the Power BI column break contextual filters silently. String columns also need the alias escaped as
[\"$a\"]rather than[$a]. - Reports pinned to a Power BI dashboard aren't interactive. If you want interactivity, embed the report directly rather than pinning it.
Consultant notes
- Raise the security question in design, not in UAT. The sentence to say out loud is: "Power BI will show every user the same data unless we build row-level security to match your Dataverse roles — how much of that model do you need reproduced?"
- Use environment variables for workspace and report IDs from the first solution. Retrofitting them once the report is in three environments is tedious and avoidable.
- Set expectations on freshness. A model-driven form shows live Dataverse data; the embedded report shows data as of the last refresh, and users will notice the difference within a day.
- Form-level embedding is a solution-file edit. Make sure whoever maintains this after you leave knows that, or the next person will try to change it in the designer and give up.
Revisit if a supported form-designer experience for Power BI embedding lands, or if the Dataverse-to-RLS story changes.