Zero Trust Assessment Dashboard
Turn a ZeroTrustAssessmentReport.html into a severity-scored, remediation-prioritized Excel dashboard and a Power BI-ready dataset — from PowerShell
Microsoft’s Zero Trust Assessment runs hundreds of read-only checks against your Entra / Intune / Azure / Purview tenant and writes a ZeroTrustAssessmentReport.html. That report is excellent for browsing but hard to act on as a team. This guide walks you — entirely from PowerShell — through turning it into:
- an Excel dashboard (charts + pillar × risk heatmap, findings grouped by pillar, severity scored 0–100, and a remediation priority P1–P4 with quick-wins called out), and
- a Power BI-ready CSV (one tidy row per check, every derived column).
The assessment report and everything derived from it contain sensitive tenant configuration — effectively a map of where you are weak. Keep all input and output inside your authorization boundary, share only with authorized personnel, and do not publish raw findings. Remediation guidance is advisory: apply changes only through your normal change-control process.
What you get
| Output | Description |
|---|---|
…-dashboard.xlsx |
Dashboard sheet with four embedded charts; Findings (ranked, severity color-scale, P1–P4 fills); By Pillar; All Tests; Methodology (the exact scoring, documented). |
charts\*.png |
The individual charts (status, findings-by-pillar, pillar × risk heatmap, severity × effort remediation quadrant). |
…-powerbi.csv |
One row per check with severity, priority, applicability, and SKU columns — import directly into Power BI. |
Prerequisites
- PowerShell 7+ — install guide.
- Python 3.11+ on
PATH. - The Federal Modernization Program toolkit (provides the
fmpcommand):pip install fmpfrom the repository, which brings in theopenpyxlandmatplotlibdependencies the dashboard needs. - A
ZeroTrustAssessmentReport.html(or.json) from a completed assessment run — produced in Step 1 below.
# one-time: confirm the toolkit is available
fmp --version
fmp zta --helpStep 1 — Run the Zero Trust Assessment
If you have not already produced a report, run the assessment (read-only). The first run needs a Global Administrator to consent; later runs can use Global Reader. See Microsoft’s get-started guide.
Install-Module ZeroTrustAssessment -Scope CurrentUser
Connect-ZtAssessment
Invoke-ZtAssessment # writes .\ZeroTrustReport\ZeroTrustAssessmentReport.htmlThe assessment can take a while on large tenants. The HTML it opens by default already embeds the full dataset — the dashboard reads it directly, so you do not need a separate JSON export.
Step 2 — Generate the dashboard
Download Invoke-ZtDashboard.ps1 (see Downloads) and run it against the report:
.\Invoke-ZtDashboard.ps1 -ReportPath .\ZeroTrustReport\ZeroTrustAssessmentReport.html -OutputDirectory .\zt-dashboardThat is a thin wrapper over the toolkit; the equivalent direct call is:
fmp zta dashboard --input .\ZeroTrustReport\ZeroTrustAssessmentReport.html --out-dir .\zt-dashboardYou can also produce the lighter text/CSV digests (executive summary, Markdown, worklist) with:
fmp zta digest --input .\ZeroTrustReport\ZeroTrustAssessmentReport.html --out-dir .\zt-digestStep 3 — Build a remediation playbook
To get a per-finding how-to-fix guide, run:
fmp zta remediate --input .\ZeroTrustReport\ZeroTrustAssessmentReport.html --out-dir .\zt-remediationThis writes a Markdown playbook and a CSV tracker. For each failed check it surfaces — from the assessment’s own content — the admin console the fix lives in (Entra / Intune / Purview / Azure / …), the check’s remediation steps, Microsoft Learn references, and deep links to the specific failing objects. The tracker has blank Status / Owner / Notes columns so a team can work the list. Add --status Investigate to include manual-review items.
The playbook gives portal steps and Microsoft Learn links only — no scripts. Each step routes you to the right console; make the change there through your normal change-control process.
Reading the dashboard
- Outcomes are recomputed from the per-test results. The report’s own summary block is intentionally ignored because it does not reconcile.
- Only
FailedandInvestigateare findings.Skipped(not applicable / unlicensed) andPlanned(a check Microsoft has not implemented yet) are shown but are not gaps — don’t chase them. - Severity (0–100) = risk × status weighting. Priority = severity ÷ effort, so a high-severity, low-effort check (a quick win) outranks a high-severity, high-effort one. Buckets: P1 ≥ 50, P2 ≥ 30, P3 ≥ 15, P4 > 0.
- The Findings sheet is your worklist — sorted P1 first, severity color-scaled.
- The remediation quadrant chart splits findings into quick-wins (top-left) vs major projects (top-right).
Many checks require premium / P2-class SKUs (flagged in the ApplicabilityNote column). In a GCC / FedRAMP Moderate tenant some of those capabilities may not be available or authorized — so a “skipped” or “failed” premium check may not be a real gap. Confirm the SKU applies in your boundary before scoring it as one.
The same caution applies when carrying results into a FedRAMP 20x package. A skipped check is not evidence that a CR26 indicator fails; it is the absence of evidence, which is a different claim and belongs in the package as such. Scoring an unavailable capability as a failed indicator overstates the gap; scoring it as a pass overstates the posture.
Power BI quickstart
- Power BI Desktop → Get Data → Text/CSV → select
…-powerbi.csv. - It’s already tidy (one row per check). Build visuals directly — e.g. a matrix of
Pillar×Status, a bar ofPriorityBucket, or a card for count ofIsFinding = yes. - Useful measures: count of findings (
IsFinding = "yes"), averageSeverityScorebyPillar, P1 count byPillar.
Troubleshooting
| Symptom | Fix |
|---|---|
fmp: command not found |
The toolkit isn’t installed/active. pip install fmp, or the wrapper will fall back to python -m fmp.cli.app if Python is on PATH. |
Unicode / cp1252 errors in the console |
Run "$env:PYTHONUTF8 = 1" before invoking, or use PowerShell 7. |
could not locate an embedded reportData object |
The input isn’t a Zero Trust Assessment report — point -ReportPath at the real …Report.html or a .json export. |
Script parameters
Invoke-ZtDashboard.ps1 accepts these parameters:
| Parameter | Type | Default | Purpose |
|---|---|---|---|
-ReportPath |
string |
(required) | Path to the ZeroTrustAssessmentReport.html or .json export. Falls back to the FMP_REPORTPATH environment variable when the parameter is omitted. |
-OutputDirectory |
string |
./zt-dashboard |
Where to write the dashboard, charts, and Power BI CSV. Falls back to the FMP_OUTPUT environment variable when omitted. |
-CheckPrereqs |
switch |
off | Run FMP.ConfigTools prereq validation before executing: checks PowerShell 7+, Python 3.11+, the fmp package, and Microsoft Graph context. Silently ignored when FMP.ConfigTools is not installed. |
-EnableLogging |
switch |
off | Start a timestamped transcript under <OutputDirectory>\logs\. Requires FMP.ConfigTools; silently ignored when the module is absent. |
Environment variables
| Variable | Overrides |
|---|---|
FMP_REPORTPATH |
Default value of -ReportPath |
FMP_OUTPUT |
Default value of -OutputDirectory |
FMP.ConfigTools integration
When the FMP.ConfigTools shared module (included in fmp-cli.zip under scripts\FMP.ConfigTools\) is installed, the script uses it for structured coloured output and optional transcript logging. Absent the module, it falls back to plain Write-Host.
# Install the module from the kit
$dest = "$env:USERPROFILE\Documents\PowerShell\Modules\FMP.ConfigTools"
Copy-Item .\fmp-cli\scripts\FMP.ConfigTools $dest -Recurse -Force
# Run with prereq check and logging
.\Invoke-ZtDashboard.ps1 -ReportPath .\ZeroTrustReport\ZeroTrustAssessmentReport.html `
-CheckPrereqs -EnableLoggingDownloads
| Script | Version | SHA-256 |
|---|---|---|
Invoke-ZtDashboard.ps1 |
1.1 | f30811fd01616e2960e12dd0e870a4d19cd52a7c5c79f0e3bcc592ca5d13d509 (v1.0 base) |
Verify the download before running it:
Get-FileHash .\Invoke-ZtDashboard.ps1 -Algorithm SHA256