Changelog
The full changelog is maintained in the repository root and rendered on GitHub.
Summary
AzureScout follows Keep a Changelog format and Semantic Versioning.
| Version | Highlights |
|---|---|
| v3.12.3 (2026-08-11) | Every collector tells the truth. Restores ARM-child discovery on supported Az.Accounts, gives precise Entra/MG/Defender/DevOps availability, adds operational progress and terminal run logging, and independently reconciles every collector in a live HCS acceptance run. Raw and cache evidence remains retained. See CHANGELOG.md and AB#7279. |
| v3.12.2 (2026-08-11) | Honest collection, retained evidence. Guided runs authenticate and audit once; management-group and Graph readiness reflect collectible data; known Graph gaps are classified before requests; held Lighthouse is removed; Security Center payloads retry safely; expected ARM absence stays quiet; and complete raw/cache evidence remains until explicit cleanup. See CHANGELOG.md and AB#7279. |
| v3.12.1 (2026-08-11) | One sign-in, one tenant. Microsoft Graph now uses the same selected Azure PowerShell account and tenant as ARM collection, never an unrelated Azure CLI session. A common Entra authentication failure is attempted and reported once instead of repeated for every dataset. See CHANGELOG.md and AB#7279. |
| v3.12.0 (2026-08-10) | Less waiting, same evidence. Category-filtered inventory now uses a conservative manifest-derived dependency plan and server-side resource-type filters; combined runs reuse completed security/policy data; vault, protected-item, and storage-context work is cached at its real scope; and the ARM REST sweep follows pagination with transient-only retry instead of fixed success-path sleeps. Full, unknown, and assessment-backed runs retain complete evidence coverage. See CHANGELOG.md and AB#7279. |
| v3.11.0 (2026-08-10) | One output contract, logs that explain the run. React, Json, and JsonEvidence are the only live outputs across inventory, assessment, combined, wizard, and automation paths; held names remain compatibility inputs that warn and fall back safely; inventory React/evidence rendering reuses the completed collection offline; and the run log captures detailed phase, row-count, timing, rule, and renderer diagnostics without adding console noise. See CHANGELOG.md and AB#7279. |
| v3.10.2 (2026-08-10) | Tenant means tenant. Restores user and tenant display names, makes Y retain the current tenant and N force login followed by an accessible-tenant picker, suppresses the native subscription picker, and keeps Graph out of the default ARM-only permission preflight. See CHANGELOG.md and AB#7278. |
| v3.10.1 (2026-08-10) | Combined means combined. Fixes the v3.10.0 startup rejection for inventory + assessment with React/JsonEvidence; hardens tenant-scoped collection, non-Excel completion, permission filtering, paging, jobs, and StrictMode paths; makes unavailable governance and incomplete compliance data honest; restores canonical React scoring/evidence; and strengthens CI, packaging, dependency, and zero-skip release contracts. See CHANGELOG.md and AB#7278. |
| v3.10.0 (2026-08-09) | The last three, closed for real. Executive/Consultant/Data view modes now materially differ on every report section, not just 2 of 6; the Azure Landing Zone assessment renders BECU-style per-domain chapters instead of one flat list; a self-contradicting scorecard (two design areas both named "Security") and the evidence-identity defect (findings resolving to .NET type metadata instead of a resource name) are fixed at the root cause; PSScriptAnalyzer is at zero Error/Warning violations repo-wide, down from 1,465. See CHANGELOG.md for AB#6936, AB#6938, AB#6451. |
| v3.9.0 (2026-08-09) | The backlog sweep. Ten service-category coverage gaps (Analytics, IoT, DevOps, Management and governance, AI and machine learning, Storage, Compute, Security, Databases, Networking) closed with real new collectors wired into the assessment collect, not only the inventory export; cost projections and Azure Local licence/Hybrid Benefit collection added; the React report now surfaces Defender alert/assessment/secure-score detail and Azure Local child resources it was silently dropping; the wizard's category and format menus derive their coverage figures from the collector manifests instead of hand-typed counts, with a menu-honesty gate to keep it that way. See CHANGELOG.md for the full per-story list. |
| v3.6.1–v3.8.4 (2026-08-08) | Six field defects found and fixed from live runs in a single session: a Graph token that read the wrong tenant's licence state, a combined run that wrote the React report into an undiscoverable sibling folder, user-mode Graph probes that told a Global Administrator to grant permissions Azure CLI can never acquire, a per-subscription ARM check that failed accounts holding Owner/Contributor, a PIM Assignments query 400ing on every run, and the four approved network diagrams (plus real peering-pair edges, hybrid connectivity detail, and two new diagrams) shipped into the product for the first time; the assessment registry's naming also unified into one CAF/WAF/Microsoft/Scout/Workload taxonomy with a full alias layer so no existing -Assessment script broke. See CHANGELOG.md for AB#7184–AB#7226. |
| v3.5.1 (2026-08-04) | Three things v3.5.0 said were fine — each found by using the product, not by reading test results. The wizard offered every format except the one it renders: picking inventory + assessment (the commonest path) fell through to the inventory-only list, which has no React, while the list it skipped still offered six held renderers with Html as the default; a menu-honesty test now fails if the wizard ever offers a format the product declines to produce. One tenant in eight could not render: dotted member enumeration over an empty collection resolves against the array object, so a tenant with management groups but no policy assignments threw and produced nothing — all eight corpus tenants now render. The diagram-overlap gate was green because it inspected nothing — the fixture wrote flat keys while the payload uses dotted paths, so every diagram hit its empty guard; the gate now reads real topology and was proved to fail on a manufactured overlap. |
| v3.5.0 (2026-08-04) | The report is a product, not a page. The owner-approved v6 design ships: the React report becomes a multi-page application — Overview, Inventory & audit, Assessments, Diagrams, Data & drift, Remediation plan — rendered from the run's own data. Inventory becomes a blade view on the documented 18-category taxonomy with every collector listed including zeros, filterable/sortable item tables, tenant structure, audit callouts and a full cost-optimization blade. Each assessment carries the complete conformance register: every check, a gap block for every fail (resource-grain evidence, why it matters, numbered fix, per-check Learn link), the manual review agenda, and a What's-next section. A Diagrams page adds MG hierarchy, VNet/subnet IP utilization, estate and gaps figures with full-screen zoom. Executive/Consultant/Data become a depth toggle; exports add Markdown and JSON. Conformance clause R-04 is enforced for real — the renderer no longer re-invokes the scoring engine. All other assessment formats remain on hold. See AB#6928, AB#6936, AB#6937, AB#6938, AB#7035. |
| v3.3.4 (2026-08-04) | One report, and it is the deliverable. Reading a full multi-tenant render end to end found all six rendered formats weak in a different way — a blank dashboard, a 10/10 maturity score with no explanation, documents that never named their assessment, text over text in the PDF, figures off the slide, a Word file that opened with a repair prompt. The React single-page report is now the deliverable: one adaptive page hosting inventory and every assessment, navigation built from what actually ran, each assessment answering what was run / what was found / what to fix per CAF/WAF, and every score shown with its numerator, denominator and exclusions. Every other rendered format is on hold and will be regenerated from that report; Json/JsonEvidence are data and are never held; a held format asked for by name warns and still renders React, so a run never returns an empty folder. Also fixes a cited Learn guidance URL that 404'd while stamped "verified", plus a link-rot audit over all 26 citations. See AB#6922, AB#6913. |
| v3.3.3 (2026-08-03) | The corpus told the truth — five collection defects, none visible from a green suite. The v3.3.2 vault fix never reached the collect result (dead hashtable-PSObject guard + a copy loop that never visited the key); Export-Pptx's module-scope Get-ScoutProp shadowed the collect walker and nulled every nested properties.* read on product runs — the defect that corrupted the banked corpus; management groups collected for the first time in the product's history (-UseTenantScope, 92 MGs across 8 reference tenants); security.defenderPlans collected per subscription instead of hardcoded @() while CAF/WAF rules queried it; same-second runs no longer overwrite each other's run folder. Adds the committed corpus harness with integrity checks and per-collector coverage verdicts (36 working, 0 unexplained empties). See AB#6896–AB#6903. |
| v3.3.2 (2026-08-03) | Field fixes from real tenant runs. Advisor ingestion contained per subscription (one unregistered Microsoft.Advisor provider no longer costs the tenant every recommendation); Entra ID P2-gated Graph features report NOT LICENSED — requires Microsoft Entra ID P2 instead of DENIED; Recovery Services vaults collected from rows the raw pass already holds instead of a hardcoded empty array; the LandingZone rule glob scoped to its own 13 areas (was sweeping in 34); GovernanceReport reachable from -OutputFormat All; evidence truncation made visible ("25 of 198 matched"). Adds the customer-facing overview and least-privilege access guide plus licence-tier documentation. See AB#6893–AB#6895, AB#6890, AB#6863, AB#6864. |
| v3.3.1 (2026-08-03) | Figures reach every format, and the Power BI pages actually bind. Figures embed in PowerPoint and PDF, not only Word (the PDF route needed no JPEG — /FlateDecode is zlib, which the rasteriser already emits). Power BI visual containers get all three required blobs (config, query, dataTransforms) instead of only config, so pages bind data instead of drawing empty frames. Verified by re-rendering all eight reference tenants offline: 29 artefacts each, 0 empty. See AB#6883, AB#6886. |
| v3.3.0 (2026-08-03) | The reports become deliverables (Epic AB#6450). docs/design/report-conformance.md is normative (40 clauses) and the conformance suite asserts every automatic clause against an emitted package read back off disk. Word gains real styles, chapter numbering, a theme, header/footer with live PAGE fields, a TOC, a cover and appendices. Figures rasterise to PNG in managed code — no Graphviz, headless browser or System.Drawing. Power BI becomes a PBIP project (TMDL semantic model, relationships, measures, authored pages) instead of four CSVs. The deck states what was not assessed; the workbook gains a cover, full ARM ids and triage verdicts. |
| Unreleased | Hardening pass over real-world collection and reporting failures. -InventoryAndAssessment/-Both makes the collect-once inventory+assessment path reachable from a script, not just the wizard. Tenant-wide collection (management groups, custom role/policy definitions) is unconditional instead of gated behind a dead switch. Two new evidence artifacts (raw-inventory.json, collector-rowcounts.json) and a per-collector permission-impact table replace a bare pre-flight verdict. Fifteen per-category assessment names are prefixed Assess: to stop colliding with inventory category names. A resource-type existence gate found eight real defects; six collectors retired, three corrected, 242 → 236. See Epic AB#6731 and CHANGELOG.md [Unreleased]. |
| v3.2.0 (2026-08-01) | Deep governance and compliance analytics. Scout goes from one real assessment to roughly twenty-eight, and from one enumerated source framework to all fourteen. Five WAF pillars, eight CAF landing-zone design areas, the WAF Maturity Model, MCSB plus one assessment per assigned regulatory initiative, Cloud Governance across seven risk categories with a 1-10 maturity report, and the AI, AVD, AVS, AVS Landing Zone, CASA, Azure Local, FinOps and DevOps reviews. NotAssessed is now a first-class status excluded from every denominator, so a control nobody chose to evaluate no longer reads as a pass. Two false-pass rules removed and waf.storage.yaml retired — it scored a WAF pillar WAF does not define. Hybrid/ArcSites and Hybrid/VirtualMachines re-sourced off Resource Graph, which indexes neither; verified live against real estates. See Epic AB#6454. |
| v3.1.0 (2026-07-31) | Eighteen-category service coverage. Added the missing Migration, General and DevOps categories plus 62 collectors — measured service coverage rises from 41% to 66%. Removed the Resource Graph exclusion that hid Logic Apps in every prior release. Added child-resource collection (Key Vault secret/key expiry, blob containers with public-access level, file shares, lifecycle policies, Backup vault instances) — control plane only, Reader-only. Added a declarative cross-resource join to the rule engine with six rules, including "which VMs have no backup". Added the SMART migration-readiness assessment on a date-stamped published-source enumeration. Fixed a golden suite that failed on any day but its recording date, and a wizard that never listed the real assessments. See Epic AB#6741. |
| v3.0.9 (2026-07-30) | Live-run hardening. Fixed two fatal crashes found live against a real 8-subscription tenant (JSON report export .Count-on-null under StrictMode; SupportTickets null-date collector), isolated each report format behind its own try/catch, removed a permanently-broken Arc CPU metrics call, added retry/backoff to the operational-enrichment ARM helper, quieted an expected ReplicationEligibility 404, closed the wizard's Scope/Entra silent-default gap, added a Cost Data module pre-flight check, and clarified a DefenderAlerts null-reference message. See Epic AB#6731. |
| v3.0.8 (2026-07-29) | Suppress Az module breaking-change warnings in non-debug output. |
| v3.0.7 (2026-07-29) | Avoid a StrictMode VariableIsUndefined error on common parameters (e.g. -Debug). |
| v3.0.6 (2026-07-28) | Resilience and logging improvements for the Excel report build and ARC-enabled server collection. |
| v3.0.5 (2026-07-28) | VM cost-row regression correction. Cost Management nested result rows no longer skip the production VM collector. See v3.0.5. |
| v3.0.4 (2026-07-28) | VM runtime regression correction. Repeated Compute SKU MemoryGB values no longer skip the production VM collector. See v3.0.4. |
| v3.0.3 (2026-07-28) | Production runtime collection. Hardened ARM-child, storage, and security/policy collectors now run in the standard extraction path. See v3.0.3. |
| v3.0.2 (2026-07-28) | Runtime collector hardening. Retired App Insights endpoints are not queried, and storage service-property lookups run in the owning subscription. See v3.0.2. |
| v3.0.1 (2026-07-28) | Tenant-scoped authentication and wizard correction. Every Azure context switch binds the requested tenant; a verified live run makes no unrelated-tenant authentication attempts. Interactive common parameters no longer suppress the wizard. See v3.0.1. |
| v3.0.0 (2026-07-28) | Epic AB#5638 engine rebuild. The 174-definition declarative collector catalog now powers collection and reporting under StrictMode; the retired collector-script tree and imperative fallback are gone. Canonical contracts cover 174 ordered row sets and 348 worksheet cases. See v3.0.0. |
| v2.11.0 (2026-07-26) | 138 of 176 collectors declarative, and the definitions gated in CI. Modules/ still holds 221 .ps1, the collector folder still holds 176, 138 of 176 are declarative, 20 StrictMode weakening sites remain (4 live), and reporting is not cut over. See the roadmap. The audit had classified 20 cross-resource-join collectors as escape-hatch alongside those making live cmdlet calls; re-examining all 48 showed its reasons were right but its inference was not -- a cross-resource join is not the same thing as a live cmdlet call, since each filters the already-collected set a second time and correlates over data the pipeline already holds. Two schema keys (SetupPreamble / SetupVariables, declared rather than harvested) unlocked 14 conversions. Verified live: 138 declarative, 36 imperative. Definitions are now gated in CI before the test suite, including a drift check that regenerates each definition from its source collector and requires a byte-for-byte match -- added because a definition had already drifted for a release while its equivalence test stayed green, since with StrictMode off the stale and current accessors agreed on the fixture. The gate is proven to fail, not assumed to: 13 tests each write a deliberately broken definition and assert the message names the fault. Fixed: the conversion tool could never have handled Web/APPServicePlan correctly -- it treated every filtered assignment as a row source, so that collector's secondary filter would have been lifted onto the row set and silently dropped every app service plan; plus a non-reproducible fixture generator, case-variant duplicate JSON keys, and a missing pipeline pass-through that left joined columns null on both paths and therefore passed equivalence. Honest limit: of the 14 conversions, only 5 have the join itself exercised by the fixture; the other 9 agree while both paths take the not-found branch, and each is pinned by name so the list can only shorten. Not done: reporting is still not cut over |
| v2.10.0 (2026-07-26) | The declarative collectors actually run — v2.9.0 converted 124 of 176 collectors to .psd1 definitions but nothing called the interpreter, so the live pipeline still executed the imperative .ps1 for every collector and the conversion delivered nothing to a user. Routing now uses the HasDeclarativeDefinition / DefinitionPath that Get-ScoutCollector already reported; verified live, the run log shows 124 declarative / 50 imperative. Proving it needed a different technique than the conversion did — a row comparison can never detect a routing regression, since both paths agree by construction — so the proof is by impossibility: a fixture collector whose entire imperative branch is a throw completes successfully, and fails with that exact message when the kill switch is on. A full pass over an 845-resource estate gave 1654 rows either way, zero deltas, byte-identical ReportCache JSON. Kill switch: AZURESCOUT_FORCE_IMPERATIVE_COLLECTORS=1, an env var so it works on an installed build. The non-ARG collection half is inverted — Get-ScoutApiResources, Get-ScoutVmQuotas, Get-ScoutVmSkuDetails and Get-ScoutCostInventory, dead since v2.7.0, are now the real path with the v1 implementations retired to shims and pinned by AST tests. Fixed: two shape regressions from @() wrapping — CostData in an array made the anomaly detector return zero records with no error, and unrolling changed the shape of every single-row endpoint response; and Management/ManagementGroups, whose fallback had been returning nothing on every run, making this the first release with zero collector failures (that sheet still needs Management Group Reader at the root to carry rows). Not done: reporting is not cut over — Start-AZSCExcelJob still runs each collector's .ps1 reporting branch through its own duplicate discovery |
| v2.9.0 (2026-07-26) | The collectors become data and the module runs strict — 124 of 176 collectors are now .psd1 definitions rather than PowerShell (up from 13), each pinned by an equivalence test comparing the imperative and declarative paths key-by-key on rows and cell-by-cell on the written .xlsx, under both tag modes. That gate caught six interpreter defects, including a field whose source is an if/else statement being silently unreachable, dropped per-loop preambles that emptied Security/Vault's permission columns, and a dropped filter preamble that made AI/AppliedAIServices produce a silently empty sheet. All 174 collectors now pass under Set-StrictMode -Version Latest, proved real by diffing emitted rows before and after with StrictMode off (20 of 23 byte-identical), with an AST-parsed CI guard against weakening it. Fixed: AB#402 error detection had gone blind — it compared $Error.Count across a phase, but $Error is a fixed-size ring buffer, so once saturated the delta is permanently zero and non-terminating errors stopped being reported entirely; ChartP6, where a worksheet that exists but holds no cells has a $null dimension so the pivot range lookup threw and took the chart with it; and an out-of-scope subscription name that had changed from $null to '', making one estate render two different blanks. Management/ManagementGroups was never a StrictMode fault — it fails parameter binding on Get-AzManagementGroup -Expand -Recurse with no -GroupId, explaining the long-standing live-run failure. Limits: the equivalence fixtures are generated from each definition's AST, not recorded from a tenant, and the live pipeline still executes the imperative .ps1 for every collector |
| v2.8.0 (2026-07-26) | Collection actually happens once — a default assessment collect now issues 4 Resource Graph queries instead of 35 (AB#5648). v2.7.0 shipped the single-pass collection functions but nothing called them, so the round-trip count was unchanged; they are now the real path. Both numbers were re-derived by counting invocations against a stub in place of Search-AzGraph and are pinned by hard count assertions, because a query count with no test regresses silently. It is 4 rather than 1 for stated reasons: three raw tables plus sqlDefenderPricing, which reads SecurityResources and cannot be served from inventory. Inventory extraction stays at 8 because those are eight distinct ARG tables, not filters over one — what changed there is ownership, not count: one paging implementation instead of two. The legacy paging/batching/retry engine Invoke-AZTIInventoryLoop.ps1 is deleted and Start-AZTIGraphExtraction is now a shim that issues no ARG call, both enforced by AST-based tests. Fixed: the inverted path returned an empty tags array for every estate — a blank report section, no error, invisible to all 2144 passing tests — because the raw pass omits the tags column unless asked while the contract aggregates its top-level tags key from subscriptions[*].tags. Trade-offs, unmeasured: the raw pass carries the full properties bag, so 1000-row page counts can rise even as query counts fall, and -Categories no longer reduces what is fetched, only what is shaped; -Source TypedQueries remains supported at 35 queries. Not done: the non-ARG half — Get-ScoutApiResources, Get-ScoutVmQuotas, Get-ScoutVmSkuDetails and Get-ScoutCostInventory are still dead code and a live run uses the v1 ARM REST, quota/SKU and Cost Management paths |
| v2.7.0 (2026-07-26) | Reporting leaves Modules/ and Excel COM is deleted — second phase of the engine rebuild. All 26 inventory renderers moved to src/report/renderers/, each file renamed to match the function it defines, and Build-AZTIExcelComObject.ps1 removed outright; chart styling runs on EPPlus/ImportExcel only. COM is why -Lite defaulted to true and why the module surfaced a raw 0x80040154 on every machine and CI runner without Excel. Verified live on a machine with no Excel: a 42-worksheet workbook with SecurityCenter at 489 rows. The 13 Databases collectors became .psd1 data interpreted at runtime, each pinned by an equivalence test comparing the imperative and declarative paths row-by-row and cell-by-cell under both tag modes — which caught two interpreter defects that would have silently changed shipped reports (tag columns appended rather than inserted; ResourceTypes treated as a membership test rather than a grouping). An AST audit of all 176 collectors ships alongside: 115 of the remaining 163 are mechanically convertible, 48 must stay hand-written. A single-pass collection layer landed as capability only — five new src/collect/ functions and a 128-type map, one raw pass satisfying 34 of 35 collect queries, but no production caller yet, so ARG round-trips are unchanged from v2.6.0 (inversion is AB#5648). Fixed: an unbound [string[]] is $null and @($null).Count is 1, so Invoke-Collect's subscription-resolution branch never fired on the default path — the subscription list was never derived from resourcecontainers and every later table degraded to one un-batched tenant-wide call with no per-batch isolation |
| v2.6.0 (2026-07-25) | The engine no longer uses background jobs — first phase of the engine rebuild. Processing created one Start-Job per category, each creating one [PowerShell]::Create() runspace per collector; every defect of the v2.5.x wave lived in that coordination rather than in the collectors. All 176 collectors now run in-process in a fixed order, so identical input yields an identical report cache — proven against a live tenant across two consecutive runs. One collector's failure no longer empties its category or aborts the batch, and Wait-AZSCJob and the job machinery are deleted. Fixed, all pre-existing and all invisible behind the job boundary: the Security Center worksheet had been empty in every release that had one; five collectors threw on their first log call; per-file .CATEGORY filtering had never matched a file; the Excel loop ran every collector regardless of data because @($null).Count is 1, not 0; and all four exporters read the cache unguarded |
| v2.5.3 (2026-07-25) | A normal Azure response aborted the run — The property 'ReservationRecomen' cannot be found on this object killed a full inventory against a real tenant. Not a null-reference fault: the module runs under StrictMode, where member enumeration over a collection reports the property missing when the enumeration yields nothing at all — which is what an empty collection on every element produces. Azure returns { "value": [] } for a subscription with no reservation recommendations, so a healthy tenant crashed. Swept the same class out of the VM quota and SKU collectors (a bare $_.subscriptionId over a mixed array meant no subscription got quotas), fixed a diagram job wait that never waited, and stopped an unavailable Cost Management API destroying the whole report. New: every run now writes scout-run.log and scout-console.log into its run folder — phases, counts, warnings, and the full error record with script, line and stack trace on failure |
| v2.5.2 (2026-07-25) | Determinism — a whole report category could silently vanish from a run. A job-wait race meant a still-NotStarted job was never waited on, then harvested and destroyed empty, so Compute.json came back 5,158 bytes on one run and 470 on the next. Both the wait loop and the batch filter now treat every non-terminal state as pending, a dropped category now warns instead of failing silently, and a machine without Excel gets a plain explanation rather than a raw COM 0x80040154 error |
| v2.5.1 (2026-07-25) | Seven live-run fixes — a full inventory run could not complete against a real tenant; extraction and processing succeeded, then the reporting layer threw after every worksheet had been built. Fixes an uninitialised extraction variable, 41 .IsPresent reads on untyped parameters, Excel styling/tables on empty worksheets, VM property names the collector never emitted, 29 unguarded worksheet dereferences, 10 pivot titles read before assignment, and a Markdown string-interpolation bug. All seven were found by running against live Azure, not by the test suite |
| v2.5.0 (2026-07-25) | One collection pass — a combined inventory + assessment run now queries Azure once instead of twice. The assessment shapes its scalars from the rows the inventory pass already fetched (ConvertFrom-ScoutInventory, -FromInventory); only the Defender for SQL pricing lookup still reaches Resource Graph, because it reads a table inventory does not collect. Assessment-only runs are unchanged |
| v2.4.0 (2026-07-25) | One command — inventory and assessment became modes of Invoke-AzureScout rather than two cmdlets (-Assessment, -CollectOnly, -FromCollect); assessment mode now honours the inventory sign-in parameters; -OutputFormat widened to accept several renderers in one run. A guided setup wizard opens when Invoke-AzureScout is run with no parameters at a terminal, and never fires in CI. Invoke-ScoutAssessment is deprecated for removal in v3.0.0 |
| v2.3.0 (2026-07-25) | Run isolation (each invocation gets its own run folder, -RunName, -Force, Clear-AZSCCacheFolder -OlderThan), the caller's subscription context restored after multi-subscription runs, a post-login management-group probe, Azure DevOps inventory via -IncludeDevOps (five worksheets plus service-connection-to-subscription cross-reference), a composite action.yml for GitHub Actions, and new automation, category-reference, and validation-matrix documentation |
| v2.2.0 (2026-07-24) | Four new report tiers (Word, EChartsDashboard, Pdf, JsonEvidence), Excel visual dashboard tabs, a much richer interactive React report (topology, MG hierarchy, KPI cards, Governance section, drill-downs) + report.pbit generation, new offline analysis (Get-ScoutInventoryDrift, Get-ScoutCostAnomaly, Get-ScoutIacGap), IoT deep coverage (DPS + Digital Twins), tag aggregation, deeper Database/Analytics/IoT rule automation, collector/pipeline resilience, assessment config load/save (Import-ScoutConfig/Export-ScoutConfig), a CI pipeline, a real azure-inventory workflow, and five v1 inventory bug fixes |
| v2.1.0 (2026-07-23) | Native governance collector (Import-Governance, no more AzGovViz dependency by default), unattended one-command pipeline (Invoke-ScoutPipeline), and a React report + cross-run drift tracking (-OutputFormat React, Get-ScoutDrift) |
| v2.0.0 | CAF/WAF Assessment Platform — read-only assessment engine (139 rules across 8 CAF design areas + 5 WAF pillars), ARG collect layer, AzGovViz/Advisor/ARG ingest, ALZ benchmark, tiered reporting (Power BI / HTML / OpenXML PowerPoint / Excel / JSON), per-domain analytics via Invoke-ScoutAssessment. Runtime-verified offline + live tenant. Breaking: findings.json contract; assessment requires PowerShell 7 |
| v1.0.0 | Full rename to AzureScout (AZSC prefix), 154 ARM modules, 17 Entra ID modules, Excel + JSON + Markdown + AsciiDoc output, draw.io diagrams, permission pre-flight, category filtering |