Skip to content

Validation Matrix ​

Collection phases 1–21 are code-complete. This page is the validation record for phases 5–21: every check, and how it is verified.

Each check falls into one of two categories:

MarkerMeaning
AutomatedCovered by the Pester suite. Runs offline on every push and pull request via ci.yml. No Azure credentials required.
Live tenantRequires a real Azure tenant with the relevant service deployed. Cannot be verified offline — mocked data proves the code path, not the shape of real API responses.

The distinction matters: an automated pass proves AzureScout handles the documented response shape correctly. Only a live-tenant run proves the shape is what Azure actually returns today.

Current state ​

The suite is 1,648 automated tests across 56 files, run by ci.yml on every push and pull request.

powershell
Import-Module Pester -RequiredVersion 5.7.1 -Force
Invoke-Pester -Path .\tests\ -Output Detailed

Live-tenant checks are run against a scratch subscription before a release. The azure-inventory.yml workflow (workflow_dispatch) is the harness for that — it runs a real headless scan with a service principal and uploads the reports as artifacts for inspection.

Phase 5 — Entra ID modules ​

CheckVerification
Entra modules produce populated worksheetsLive tenant — needs a tenant with Graph permissions granted
Graph pagination, throttling, and backoffAutomated — Invoke-AZSCGraphRequest.Tests.ps1
All 26 Entra catalog entries normalize or report disabled/unavailable status correctlyAutomated — Start-AZSCEntraExtraction.Tests.ps1
Each Entra collector's Processing and Reporting phasesAutomated — Identity.Module.Tests.ps1

Phase 6 — JSON output layer ​

CheckVerification
-OutputFormat Json produces machine-readable results onlyAutomated — output contract tests
-OutputFormat All selects exactly React, Json, and JsonEvidenceAutomated — output contract tests
JSON evidence structureAutomated — Report.JsonEvidence.Tests.ps1

Phase 8 — ARM module expansion ​

CheckVerification
Azure Local modules populate worksheetsLive tenant — needs an Azure Local deployment
Arc modules populate worksheetsLive tenant — needs Arc-enabled machines
Enhanced VPN fields for S2S, P2S, ExpressRouteLive tenant — needs each connection type provisioned
Hybrid collector Processing and Reporting phasesAutomated — Hybrid.Module.Tests.ps1
Networking collector Processing and Reporting phasesAutomated — Networking.Module.Tests.ps1

Phase 10 — Excel specialized tabs ​

CheckVerification
Overview tab holds only tenant-level summaryAutomated — Report.Excel.Tests.ps1
Cost Management tab rendersAutomated — Report.Excel.Tests.ps1
Security Overview tab rendersAutomated — Report.Excel.Tests.ps1
Azure Update Manager tab rendersAutomated — Report.Excel.Tests.ps1
Azure Monitor tab rendersAutomated — Report.Excel.Tests.ps1
Chart/shape/tab styling (EPPlus-native, no Excel COM)Automated — Private.Reporting.Tests.ps1 (Build-AZSCExcelChartStyle unit tests, plus an end-to-end assertion that no EXCEL process was ever started). Needs no Excel install, so it runs on a hosted runner.
Overview pivots P0–P9 and their charts build from a real ReportCacheAutomated — Private.Reporting.Tests.ps1; the P6 pivot is pinned in both directions (skipped cleanly on an empty source worksheet, built when the source has rows)

Phase 11 — Subscription and management group logging ​

CheckVerification
All subscriptions listed, including empty and disabledAutomated — Private.Extraction.Tests.ps1
All management groups listed with hierarchyLive tenant — needs a real MG tree and Management Group Reader
Management group access probe reports the countAutomated — RunIsolation.Tests.ps1
Missing tenant-root role prints the remediation tipAutomated — RunIsolation.Tests.ps1
Overview counts cover all subs and MGs, not just resource-bearing onesAutomated — Report.Excel.Tests.ps1

Phase 12 — Scope and auth defaults ​

CheckVerification
Default run performs ARM-only discoveryAutomated — Invoke-AzureScout.Tests.ps1
-Scope All includes Entra IDAutomated — Invoke-AzureScout.Tests.ps1
Permission pre-flight warns on missing Graph permissionsAutomated — Test-AZSCPermissions.Tests.ps1
Resource provider check warns on unregistered providersAutomated — PermissionAudit.Tests.ps1
SPN + secret and SPN + certificate loginAutomated — Connect-AZSCLoginSession.Tests.ps1
Device-code loginLive tenant — interactive by definition

Phase 13 — Azure Monitor and Insights coverage ​

CheckVerification
All 24 monitoring collectors execute without errorAutomated — Monitor.Module.Tests.ps1
Diagnostic settings capture resource-level configurationLive tenant — needs resources with diagnostics configured
App Insights deep-data modules handle missing configurationAutomated — Monitor.Module.Tests.ps1
Report contains a worksheet per monitoring collectorAutomated — Monitor.Module.Tests.ps1

Phase 14 — AI, Foundry, and ML coverage ​

CheckVerification
All 27 AI/ML collectors execute without errorAutomated — AI.Module.Tests.ps1
OpenAI deployments capture model detailsLive tenant — needs an Azure OpenAI resource
AI Foundry hubs and projects detected via Kind filteringLive tenant — needs a Foundry hub
ML workspace child resources enumerateLive tenant — needs an ML workspace with compute and datastores
Resource provider warnings fire for unregistered AI providersAutomated — PermissionAudit.Tests.ps1

Phase 15 — Azure Virtual Desktop ​

CheckVerification
Host pools, application groups, workspaces enumerateAutomated — Compute.Module.Tests.ps1
Session hosts capture status and session countsLive tenant — needs running session hosts
Scaling plans capture all four time periodsAutomated — Compute.Module.Tests.ps1
AVD on Azure Local detection via Arc associationLive tenant — needs AVD on Azure Local
Report contains all six AVD worksheetsAutomated — Compute.Module.Tests.ps1

Phase 16 — Arc enhanced configuration ​

CheckVerification
Arc site configurations enumerateLive tenant — needs Arc sites
Arc extensions capture version, settings, auto-upgradeAutomated — Hybrid.Module.Tests.ps1
Arc-enabled SQL Server captures database count and ESU statusLive tenant — needs Arc-enabled SQL
Arc Data Services handles direct and indirect connectivityAutomated — Hybrid.Module.Tests.ps1
Report contains the four Arc worksheetsAutomated — Hybrid.Module.Tests.ps1

Phase 17 — VM and Arc enrichment ​

CheckVerification
VM extensions enumerate with versions and settingsAutomated — Compute.Module.Tests.ps1
Backup status identifies protected vs unprotected VMsLive tenant — needs a Recovery Services vault
Update compliance shows pending patch countsLive tenant — needs Azure Update Manager
Arc servers capture the same depth as Azure VMsAutomated — Hybrid.Module.Tests.ps1
Performance metrics populate when the Monitor agent is installedLive tenant — needs the agent deployed
Cost estimates appear for VMsLive tenant — needs Cost Management API access
500 VMs complete in under 30 minutes with parallel processingLive tenant — a scale test
Graceful degradation: VMs without enrichment show N/A, no errorsAutomated — Compute.Module.Tests.ps1
Per-subscription context is restored after quota collectionAutomated — RunIsolation.Tests.ps1

Phase 18 — Category filtering ​

CheckVerification
Module auto-discovery works after the folder restructureAutomated — CategoryFiltering.Tests.ps1
Single category runs only that category's modulesAutomated — CategoryFiltering.Tests.ps1
Multiple categoriesAutomated — CategoryFiltering.Tests.ps1
Hybrid category runs Arc and Azure Local modulesAutomated — CategoryFiltering.Tests.ps1
Category combined with scopeAutomated — CategoryFiltering.Tests.ps1
Every alias resolves to its canonical valueAutomated — CategoryFiltering.Tests.ps1
Monitor is canonical, Monitoring is the aliasAutomated — CategoryFiltering.Tests.ps1
Report contains worksheets only for selected categoriesAutomated — Report.Excel.Tests.ps1

The alias set itself is documented in the Category Reference.

Phase 19 — Final validation (cross-phase) ​

CheckVerification
Full tenant scan completesLive tenant — the end-to-end acceptance run
Empty tenant completes with zero resources and no errorsAutomated — Pipeline.Tests.ps1
1000+ resources complete with graceful throttlingLive tenant — a scale test
SPN auth scans both ARM and EntraLive tenant — needs consented Graph application permissions
Multi-subscription tenant scans every subscriptionLive tenant
Management groups capture parent-child relationshipsLive tenant
Policy compliance captures recent compliance statesAutomated — Management.Module.Tests.ps1
Defender assessments, secure score, alerts, pricingAutomated — Security.Module.Tests.ps1
Non-terminating errors do not abort the pipelineAutomated — Pipeline.NonTerminatingErrors.Tests.ps1
Collection resilience under partial failureAutomated — Collect.Resilience.Tests.ps1

Phase 20 — Permission audit ​

CheckVerification
-PermissionAudit exits early — no extraction, no reportAutomated — PermissionAudit.Tests.ps1
ARM output shows subscriptions and role assignmentsAutomated — PermissionAudit.Tests.ps1
-IncludeEntraPermissions produces the Graph permission tableAutomated — PermissionAudit.Tests.ps1
Limited-permission SPN shows warningsAutomated — PermissionAudit.Tests.ps1
Fully-permissioned SPN shows all green for ARMAutomated — PermissionAudit.Tests.ps1
Global Reader satisfies supported user-role checks; OAuth token scopes are reported separatelyLive tenant — needs the directory role assigned
Provider table shows Registered/NotRegistered correctlyAutomated — PermissionAudit.Tests.ps1
-PermissionAudit -OutputFormat Json saves a JSON reportAutomated — PermissionAudit.Tests.ps1
The audit restores the caller's subscription contextAutomated — PermissionAudit.Tests.ps1, RunIsolation.Tests.ps1
Audit survives a scalar-collapsing single subscription under StrictModeAutomated — PermissionAudit.Tests.ps1

Phase 21 — held Markdown and AsciiDoc implementations ​

These checks cover retained legacy implementation code. Markdown-file and AsciiDoc renderers are on hold in every run mode; passing an internal renderer test does not make either value a live -OutputFormat.

CheckVerification
Markdown implementation generates a valid .md fixtureInternal compatibility test — OutputFormat.Tests.ps1
AsciiDoc implementation generates a valid .adoc fixtureInternal compatibility test — OutputFormat.Tests.ps1
Markdown tables render on GitHub (pipe-table format)Internal compatibility test — OutputFormat.Tests.ps1
AsciiDoc converts to PDF via asciidoctor-pdfHeld-renderer development check — external toolchain
AsciiDoc converts to Word via PandocHeld-renderer development check — external toolchain
Legacy Excel/AsciiDoc implementations remain testable from fixturesInternal compatibility test — OutputFormat.Tests.ps1
Modules with zero resources are skipped in Markdown/AsciiDocInternal compatibility test — OutputFormat.Tests.ps1
Large-fixture Markdown implementation streams without OOMHeld-renderer development check — scale fixture
AsciiDoc admonitions appear for security findingsInternal compatibility test — OutputFormat.Tests.ps1
Legacy Markdown permission-report implementation remains testableInternal compatibility test — PermissionAudit.Tests.ps1

Running the live-tenant checks ​

The live-tenant rows need a scratch subscription. The minimum useful setup is a subscription with a VM, a storage account, a virtual network, and a Log Analytics workspace; each additional service unlocks the rows that name it.

powershell
# Full scan, all formats, into a named run folder
Invoke-AzureScout -TenantID '<tenant-id>' -Scope All -RunName 'release-validation' -Debug

# Scale check
Invoke-AzureScout -TenantID '<tenant-id>' -Category Compute -Debug

# Permission audit
Invoke-AzureScout -TenantID '<tenant-id>' -PermissionAudit -IncludeEntraPermissions

-RunName keeps each validation run in its own folder, so a re-run does not overwrite the evidence from the previous one — see Output Files & Formats.

Released under the MIT License.