🦊 MigrationFox Docs

Power Platform Inventory

A per-tenant pre-migration audit of every Power Platform environment, Dataverse solution, Power Automate flow, Power App, connector, and DLP policy. Surfaces the risks that are invisible from the Power Apps portal: orphan flows, connectors blocked by DLP but still referenced, environments with zero governance, and premium connector sprawl.

What it produces

Five data slices per scan: environments, solutions, flows, apps, and DLP policies. Plus a tenant-wide connector usage matrix that aggregates every connector referenced by any flow or app and cross-references it against every active DLP policy to flag “blocked connectors still in use” — the silently-broken artefacts in every tenant.

When to run it

Access requirements

Power Platform admin APIs use a different authentication surface than Microsoft Graph. The same Azure AD service principal you use for a governance assessment authenticates fine — only the audience and the authorization model are different. Grants are layered in three tiers. Each tier unlocks a specific data slice in the scan result:

Tier 1 — Required

Tenant-level BAP access

What you get: environments list, DLP policies list. Without this tier the scan cannot proceed at all — the inventory result will show a prereq checklist instead of data.

What to grant:

  1. Assign the Entra directory role Power Platform Administrator to the service principal. (Global Administrator also works but is more access than needed.)
  2. Register the service principal with BAP as a tenant management app — one PowerShell command, run once per tenant.
Install-Module -Name Microsoft.PowerApps.Administration.PowerShell -Scope CurrentUser -Force
Add-PowerAppsAccount                         # sign in as a Global Administrator
New-PowerAppManagementApp -ApplicationId <YOUR_CLIENT_ID>

Why both: the directory role opens the door; the management-app registration lets app-only tokens through. Human users don’t need the management-app step because their delegated tokens already carry identity. Service principals do. This is Microsoft’s documented pattern — the same one the CoE Starter Kit uses. See Fix: Power Platform scan returns 0 flows + 0 apps for the full troubleshooting walk-through.

Token audience: https://service.powerapps.com/.default

Symptom when missing: the scan completes but the result shows “BAP access prerequisites missing” with the one-time setup checklist. Zero environments, zero DLP policies, zero flows, zero apps. Nothing to act on except the checklist.

Tier 2 — For flows + apps

Environment Admin on each environment

What you get: the flow list and app list for every environment where you grant this role. Without it, Tier 1 gives you environment names but the per-environment /flows and /powerApps endpoints return empty arrays.

What to grant:

  1. Open the Power Platform Admin Center.
  2. Go to Environments, click each environment you want inventoried.
  3. Under Access → Environment Admin, click Edit and add the service principal’s Application (client) ID.
  4. Allow up to one hour for the role assignment to propagate.

Why per-environment: Microsoft deliberately keeps environments autonomous. Having tenant-level Power Platform Admin lets you see that environments exist, but each environment owner decides who reads its contents. The per-env admin role is what unlocks the flow and app enumeration endpoints.

Token audience: same as Tier 1 (https://service.powerapps.com/.default) — the authorization check is where this differs, not the audience.

Symptom when missing: the inventory shows environment and DLP counts correctly, but the Apps stat turns amber at 0 and a “Scan Diagnostics” panel appears with a message like “listApps returned 0 apps across N environments. Typical cause: the service principal has Power Platform Administrator but is not Environment Admin on each environment”. Flow details (connector references) may also be partial.

Tier 3 — For Dataverse solutions

Application user per Dataverse environment

What you get: the Dataverse solution list for each environment (unique name, friendly name, version, managed or unmanaged, publisher). Environments with no Dataverse database are skipped cleanly.

What to grant:

  1. Power Platform Admin Center → Environments → your env → Settings → Users + permissions → Application users.
  2. Click + New app user.
  3. Select the service principal’s app registration.
  4. Assign a role that can read the solutions table. System Administrator works; a narrower custom role with Solution: Read is preferable in production.

Why this is a separate grant: Dataverse is its own identity plane. The BAP admin role doesn’t imply Dataverse access. Each Dataverse organization authorises via its own role-based access and needs an explicit Application User record per service principal.

Token audience: {dataverseUrl}/.default — different per environment because the audience is the org’s own URL (e.g. https://contoso.crm.dynamics.com/.default). Our BAP client caches Dataverse tokens per URL so the overhead is one token per scan per env.

Symptom when missing: Solutions count is 0 for that specific environment. Other environments (where the grant is correct) still show solutions. No scan-wide failure.

Token audience reference

Data sliceEndpointToken audienceRequired tier
Environmentsapi.bap.microsoft.com/.../admin/environmentsservice.powerapps.com/.defaultTier 1
DLP policiesapi.bap.microsoft.com/.../Governance/v2/policiesservice.powerapps.com/.defaultTier 1
Flowsapi.flow.microsoft.com/.../admin/environments/{env}/v2/flowsservice.powerapps.com/.defaultTier 2
Appsapi.bap.microsoft.com/.../admin/environments/{env}/powerAppsservice.powerapps.com/.defaultTier 2
Solutions{dataverseUrl}/api/data/v9.2/solutions{dataverseUrl}/.defaultTier 3 (per env)

Graceful degradation

The scan never hard-fails because a tier is missing. Every missing tier produces a diagnostic message on the result page:

This lets you run the scan immediately after granting Tier 1 to confirm the plumbing works, then iterate on Tier 2 and Tier 3 grants without re-running the whole audit from scratch each time.

What the scan result looks like

A completed inventory page opens with a stats row (environments, solutions, flows, apps, DLP policies), followed by risk highlights. The tenant-wide connector usage matrix lists every connector used anywhere in the tenant, sorted by total flow + app references, with pills for Premium, Business-classified, Non-Business-classified, and Blocked. Rows where a connector is Blocked by DLP but still has non-zero references are highlighted — those flows and apps are silently broken and the owner doesn’t know.

Each environment renders as a collapsible card with per-env flow and app tables (owner email, state, connectors). The DLP policies section shows each policy’s Business / Non-Business / Blocked buckets with the first few connectors previewed. A one-click CSV export dumps all five data slices for handover to the client.

Scan scope and caps

Troubleshooting

SymptomLikely causeFix
Inventory says “BAP access prerequisites missing” Tier 1 not granted: either the directory role is missing or New-PowerAppManagementApp was never run. Follow Tier 1 in Access requirements, then re-run.
Environments show but 0 apps across all Tier 2 missing. Service principal is not Environment Admin on any environment. Follow Tier 2. Remember the 1-hour propagation window.
Solutions count is 0 for specific environments only Tier 3 Application User is missing for those envs. Others are fine because they have it. Follow Tier 3 for the envs with 0 solutions.
Flow rows show but with empty connector lists Scan hit the 150-flow detail-fetch cap, or some flows have no connections configured. Check the Scan Diagnostics panel — it reports “N of M flows still had no connectors after enrichment”. Beyond the cap is expected; genuinely empty connections are legit for triggered-without-action flows.
DLP policies listed but all three buckets show 0 connectors The v2 /policies list endpoint returns policy summaries with empty connectorGroups. We fetch the detail endpoint per policy to hydrate buckets. Ensure the scan reached completion — the Scan Diagnostics panel will show how many policies needed detail-fetching and how many still had empty buckets.

One service principal, different audiences

You do not need a separate credential for Power Platform vs Graph. The same Azure AD app registration (clientId + secret) authenticates against Microsoft Graph, BAP, Flow admin, and Dataverse — each uses a different audience in the token exchange. MigrationFox handles the token caching and audience switching automatically; you just grant the roles above to the same service principal you already use for governance assessments.

Related