# Analyst Cockpit HTML Report Guide
**Module:** `Modules/EntraChecks-HTMLReporting.psm1` (function `New-EntraChecksAnalystHtmlReport`)
**Status:** Default since PR 4 of `plans/HTML-Reporting-Consolidation-Plan.md`
**Output:** `Reports//EntraChecks-Analyst-Cockpit-.html`
---
## 1. What changed
Before, every assessment generated up to nine overlapping HTML files (comprehensive, unified, executive summary, Secure Score, Defender, Azure Policy, Purview, Delta, plus SOC 2 reports). Auditors and analysts had to open multiple tabs to understand a tenant.
Now, a normal assessment generates **one primary HTML file** — the analyst cockpit. Deep-dive reports for individual data sources are still available but are **opt-in**.
- Default `Reports//` contents:
```
EntraChecks-Analyst-Cockpit-.html
EntraChecks-Analyst-Cockpit-.html.findings.json ← integrity sidecar
Assessment-Data-.json
CSV/ ← when ImportExcel missing
EntraChecks-Comprehensive-Assessment-.xlsx ← when ImportExcel present
```
- When deep dives are requested, they land under `Reports//DeepDives/` to keep the primary cockpit at the root of the report folder.
- SOC 2 Type 1 and Type 2 reports remain separate when `SOC2.Enabled = true` — they're audit-package artefacts, not normal-assessment clutter.
- The pre-PR-4 multi-report behavior is preserved via `-HtmlReportSet LegacyAll` for users with workflows that depend on the old layout.
---
## 2. The four modes
Pick the mode that matches what you're doing. Default: `Cockpit`.
| Mode | What it generates | When to use |
|---|---|---|
| `Cockpit` | One cockpit HTML, no deep dives. | Normal assessment runs. Daily-driver default. |
| `CockpitAndDeepDives` | Cockpit + only the deep dives you listed in `-HtmlDeepDiveDomains`. | When you need cockpit *plus* a specific drill-down (e.g. Azure Policy auditor wants the framework-mapped view). |
| `DeepDivesOnly` | Only the listed deep dives. No cockpit. | Pipeline runs that consume just one upstream report (e.g. exporting only Defender for Cloud HTML). |
| `LegacyAll` | Comprehensive + unified + every available domain HTML — the pre-PR-4 layout. | Compatibility mode. Use this if you have an existing automation that depends on the old file set. |
### Command-line invocations
```powershell
# Default — produces just the cockpit
.\Start-EntraChecks.ps1
# Cockpit + Azure Policy + Defender deep dives
.\Start-EntraChecks.ps1 -HtmlReportSet CockpitAndDeepDives `
-HtmlDeepDiveDomains AzurePolicy,DefenderCompliance
# Just the Secure Score deep dive (no cockpit)
.\Start-EntraChecks.ps1 -HtmlReportSet DeepDivesOnly `
-HtmlDeepDiveDomains SecureScore
# Old multi-report behavior (compatibility mode)
.\Start-EntraChecks.ps1 -HtmlReportSet LegacyAll
```
### Config-file equivalent
```json
{
"Assessment": {
"Output": {
"Html": {
"ReportSet": "CockpitAndDeepDives",
"DeepDiveDomains": ["AzurePolicy", "DefenderCompliance"],
"OpenPrimaryReport": true,
"MaxInitialRows": 100
}
}
}
}
```
Precedence: command-line param > config-file `Assessment.Output.Html.*` > hard default (`Cockpit`, `[]`, 100).
---
## 3. Deep-dive domains
Valid values for `-HtmlDeepDiveDomains`:
| Value | Detailed report |
|---|---|
| `SecureScore` | Microsoft Secure Score per-action breakdown |
| `DefenderCompliance` | Defender for Cloud regulatory standards |
| `AzurePolicy` | Azure Policy initiative compliance |
| `PurviewCompliance` | Purview Compliance Manager scores |
| `Delta` | Snapshot delta vs the previous run |
| `PrivilegedIdentity` | Privileged Identity Roster (AD + Entra) |
Rules (per plan §12, enforced by `Get-HtmlReportPlan`):
- **Cockpit mode ignores `-HtmlDeepDiveDomains`** with a warning. The cockpit's Deep Dive Hub still shows status cards for every domain, with "Not generated this run" + how-to hint.
- **CockpitAndDeepDives** with empty `-HtmlDeepDiveDomains` does not infer "all domains" — it emits cockpit alone. This guards against accidental expansion.
- **DeepDivesOnly** with empty `-HtmlDeepDiveDomains` warns and emits no HTML.
- **LegacyAll** ignores `-HtmlDeepDiveDomains` and infers from `AvailableSources` (every collector that produced data gets a report).
- A deep-dive requested for a domain whose data wasn't collected this run produces a warning and is skipped.
- Invalid domain names produce a warning and are skipped; valid neighbours still emit.
---
## 4. Cockpit sections (top to bottom)
The cockpit is organised for analyst workflow — operational sections first, audit / inventory sections further down.
1. **Header and Executive Digest** — posture verdict (`Strong` / `Minor Deficiencies` / `Gaps Identified` / `High Risk` / `Collection Incomplete`), tenant info, total / critical / high / review / quick-wins counts, since-last-assessment delta.
2. **Action Queue** — actionable items only. Filter rule: `Disposition ∈ {Open, ActionRequired, Review, ExpiredException}`. Excludes approved non-expired exceptions, OK, INFO. Sort order: ExpiredException first → Critical/High risk → earliest DueDate → -PriorityScore desc → Owner DisplayName. Interactive: text search + status/risk/disposition selects + expandable rows + "Show more" pagination.
3. **Review Queue** — items needing human judgment. Filter: `Status='REVIEW'` OR `ReviewStatus.State ∈ {NeedsReview, InReview, ActionRequired}`. Same interactive controls as Action Queue.
4. **Source Posture** — cards summarising what was collected. Each source (EntraChecks, Secure Score, Defender, Azure Policy, Purview, Hybrid Correlation, Privileged Identity) renders as a `Collected` (green-bordered) or `Not collected` (gray-bordered) card with a short metric.
5. **Evidence and Provenance** — flat audit table: every v2 Evidence reference with `EvidenceId`, `Source`, `Provider`, `Cmdlet`, `Scope`, `ResourceId`, `Hash`, `RedactionStatus`. Section is suppressed for legacy findings with no v2 Evidence.
6. **Full Findings** — every finding regardless of disposition: FAIL, WARNING, REVIEW, INFO, OK, accepted risks, false positives, out-of-scope, resolved. Filters: text search + status + risk level + disposition + source. Pagination at `MaxInitialRows` (default 100) with a "Show more (100 at a time)" button.
7. **Deep Dive Hub** — status cards for each on-demand domain. Generated cards link directly to the deep-dive file under `DeepDives/`; pending cards show the exact command to generate them.
8. **Integrity Footer** — SHA-256 of canonical findings JSON + sidecar location + the `Test-EntraChecksReportIntegrity` command to verify.
Every dynamic value rendered into the cockpit passes through `ConvertTo-SafeHtml` so injection attempts (`