Output Files
Default Output Location
| OS | Base path |
|---|---|
| Windows | C:\AzureScout\ |
| Linux / macOS | $HOME/AzureScout/ |
Override the base with -ReportDir:
Invoke-AzureScout -TenantID '00000000-...' -ReportDir 'D:\Reports' -ReportName 'Q1-Inventory'Run isolation
Every invocation writes to its own run folder underneath the base path. A rerun — or a scan of a second tenant — can never overwrite the previous run's cache or report.
C:\AzureScout\
├── 2026-07-25_101500_12345678\ ← run folder: timestamp + short tenant ID
│ ├── ReportCache\
│ ├── DiagramCache\
│ ├── AzureScout_Report_<timestamp>.json
│ └── assessment-report\
│ ├── report-react.html
│ ├── evidence.json
│ ├── collect.json
│ └── findings.json
└── 2026-07-25_143022_87654321\ ← a different tenant, untouched by the run above
├── ReportCache\
├── DiagramCache\
├── AzureScout_Report_<timestamp>.json
└── assessment-report\
├── report-react.html
├── evidence.json
├── collect.json
└── findings.jsonName the folder yourself with -RunName instead of taking the generated timestamp:
Invoke-AzureScout -TenantID '00000000-...' -RunName 'Production-TenantA'
# → C:\AzureScout\Production-TenantA\Invalid path characters in a -RunName are replaced with -.
Writing in place with -Force
-Force skips the run folder and writes straight into the base path, overwriting whatever was there. This is the pre-2.3.0 behaviour, and it is what you want when a downstream tool expects a fixed path:
Invoke-AzureScout -TenantID '00000000-...' -ReportDir 'D:\Reports' -Force
# → D:\Reports\ReportCache\, inventory JSON, and assessment-report\ with React/evidence filesPruning old runs
Run folders accumulate. Remove the ones older than a given number of days:
# Everything not written to in the last 30 days
Clear-AZSCCacheFolder -OlderThan 30
# Prune a non-default base path
Clear-AZSCCacheFolder -OlderThan 7 -BasePath 'D:\Reports'Automation runs
Inside an Azure Automation sandbox the filesystem is discarded when the job ends, so run isolation has no lasting effect there — blob storage is the durable copy. See Azure Automation Account.
Generated Files
One output contract in every run mode
Inventory-only, assessment-only, and combined runs use the same live formats: React, Json, and JsonEvidence. All selects all three.
The self-contained React report (report-react.html) carries inventory, evidence, and—when selected—assessment findings and the remediation plan. It exports to Markdown, JSON, CSV, PDF/Print, and standalone HTML from the page itself. Word, PDF, Excel, PowerPoint, Power BI, standalone HTML, ECharts dashboard, Markdown-file, AsciiDoc, and governance renderers are on hold (AB#6922) while they are rebuilt to generate from that report. Json and JsonEvidence are live data outputs, not document renderers. See Report tiers and the React report section contract.
| File | Format | Description |
|---|---|---|
assessment-report/report-react.html | React/HTML | The supported self-contained document. Inventory-only runs use a neutral empty-findings envelope and show inventory/audit content; assessment runs add scored findings and remediation content. The console and final result summary print its exact path. |
AzureScout_Report_<timestamp>.json | JSON | The existing AzureScout inventory JSON/schema, selected with Json |
assessment-report/evidence.json | JSON | Resources-only canonical Collect data, including collection provenance and already-collected Entra rows, with no scores, rules, or findings; selected with JsonEvidence |
assessment-report/collect.json | JSON | Internal canonical Collect snapshot used to render the React/evidence outputs without another Azure or Graph query |
assessment-report/findings.json | JSON | Internal scored-findings envelope; neutral and empty for inventory-only runs |
AzureScout_Diagram_<timestamp>.drawio | Draw.io | Network topology diagram (skip with -SkipDiagram) |
scout-run.log | Log | Detailed structured log — DEBUG/VERBOSE extraction and processing subphases, collector/rule/renderer status, row/evidence counts, timings, warnings, and full error detail on failure. Written by default without adding console noise. See Troubleshooting |
scout-console.log | Log | Console transcript for the run. Skipped on hosts without transcription support |
raw-inventory.json | JSON | Everything collected, before any manifest decided what to display (see below) |
collector-rowcounts.json | JSON | What each collector produced, and why it produced nothing (see below) |
collection-health.json | JSON | Upstream dataset availability: Complete, Partial, Not assessed, or Unavailable |
Evidence artifacts
These files exist to make a run auditable. Azure Scout retains raw-inventory.json, collector-rowcounts.json, collection-health.json, every ReportCache JSON file, and the DiagramCache contents after the scan. They remain available for other tools and reporting for as long as the run folder exists. Cleanup is operator-controlled through Clear-AZSCCacheFolder -OlderThan <days>; a successful scan does not delete its own evidence.
raw-inventory.json
AzureScout's Resource Graph pass is unfiltered: it pulls every resource type in the estate. The collector manifests then decide which types reach a worksheet, and historically everything else was discarded without being written anywhere — so a resource type no manifest claims left no trace it had ever been seen. This artifact is written before the processing phase, so it contains rows no report shows.
{
"Schema": "azure-scout/raw-inventory/v1",
"GeneratedAt": "2026-07-31T18:04:14.0000000Z",
"Counts": { "Resources": 4812, "ResourceContainers": 37, "EntraResources": 1204, "...": 0 },
"ResourceTypes": [
{ "Type": "microsoft.compute/virtualmachines", "Rows": 214 },
{ "Type": "microsoft.madeup/thingies", "Rows": 3 }
],
"Resources": [ /* full rows, properties bag intact */ ],
"ResourceContainers": [], "Advisories": [], "Security": [], "Retirements": [],
"EntraResources": [], "Quotas": [], "PolicyAssign": [], "PolicyDef": [], "PolicySetDef": []
}ResourceTypes is the quickest answer to "what did the estate contain that no worksheet showed?" — compare it against the types listed in the category reference.
collector-rowcounts.json
One row per collector, with three verdicts rather than two. Rows: 0 on its own is ambiguous: it can mean the collector is broken, or that the tenant genuinely has none of that resource type. The Verdict field says which.
| Verdict | Meaning |
|---|---|
Rows | The collector ran and produced data |
Empty | The collector ran cleanly and produced nothing — the estate has none of this type |
Failed | The collector threw. Error carries the message, and the empty worksheet is explained |
{
"Schema": "azure-scout/collector-rowcounts/v1",
"GeneratedAt": "2026-07-31T18:04:14.0000000Z",
"Totals": { "Collectors": 236, "WithRows": 118, "Empty": 117, "Failed": 1, "Rows": 6104 },
"Collectors": [
{ "Category": "Compute", "Collector": "VirtualMachine", "Rows": 214, "Verdict": "Rows", "Error": null },
{ "Category": "IoT", "Collector": "IoTCentral", "Rows": 0, "Verdict": "Empty", "Error": null }
]
}Rows are sorted by category then collector, so two runs diff cleanly:
$a = (Get-Content .\run-a\collector-rowcounts.json -Raw | ConvertFrom-Json).Collectors
$b = (Get-Content .\run-b\collector-rowcounts.json -Raw | ConvertFrom-Json).Collectors
Compare-Object $a $b -Property Category, Collector, Rows, VerdictJSON Structure
{
"_metadata": {
"tool": "AzureScout",
"version": "1.0.0",
"tenantId": "...",
"subscriptions": ["..."],
"generatedAt": "2026-02-25T...",
"scope": "All"
},
"arm": {
"compute": { },
"network": { },
"storage": { }
},
"entra": {
"users": [ ],
"groups": [ ],
"appRegistrations": [ ]
},
"advisory": [ ],
"policy": [ ],
"security": [ ],
"quotas": [ ]
}_metadata— Execution context: tool version, tenant, scope, timestamparm— ARM resources grouped by categoryentra— Entra ID objects grouped by typeadvisory/policy/security/quotas— Cross-cutting data collected during the run
Held legacy renderer designs
The legacy Excel renderer is on hold and does not produce a workbook in a live run. Its retained implementation and tests describe these planned tab groups:
- Overview — Tenant metadata, resource summary, execution info
- Cost Management — Reservations, cost recommendations, spend analysis
- Security Overview — Defender secure score, assessments, alerts, policy compliance
- Azure Update Manager Overview — VM/Arc patch compliance, maintenance schedules
- Azure Monitor — Action groups, alert rules, DCRs, workspaces, diagnostic settings
- Resource tabs — One worksheet per ARM resource type (Subscriptions, VMs, Networks, etc.)
- Entra ID tabs — One worksheet per Entra module (Users, Groups, Conditional Access, etc.)
- Azure DevOps tabs — Only with
-IncludeDevOps: ADO Projects, ADO Pipelines, ADO Service Connections, ADO Repositories, ADO Agent Pools. See Azure DevOps
Output Format Control
Use -OutputFormat to select from the three live formats:
# Machine-readable run results only
Invoke-AzureScout -TenantID '00000000-...' -OutputFormat Json
# Self-contained report only
Invoke-AzureScout -TenantID '00000000-...' -OutputFormat React
# All live formats (default): React, Json, JsonEvidence
Invoke-AzureScout -TenantID '00000000-...' -OutputFormat AllLegacy format names may remain accepted for script compatibility, but they are held and do not create those artifacts. Use the React report's export menu for Markdown, JSON, CSV, PDF/Print, and standalone HTML.
Held Power BI renderer design
The Power BI renderer is on hold and is not part of All. The retained implementation is designed to create a PowerBI/ subfolder containing normalized CSV files for Power BI Desktop or Microsoft Fabric after the renderer is rebuilt from the React report model.
Output Structure
PowerBI/
_metadata.csv — Scan metadata (tenant, date, scope, version)
_relationships.json — Star-schema relationship definitions for Power BI data model
Subscriptions.csv — Subscription dimension table (SubscriptionId, SubscriptionName)
Resources_{Module}.csv — One file per ARM inventory module
Entra_{Module}.csv — One file per Entra ID / Identity moduleEvery resource CSV includes _Category and _Module columns for cross-table slicing, plus a Subscription column that links to Subscriptions.csv via the relationships manifest.
Importing into Power BI Desktop
- Open Power BI Desktop → Get Data → Folder
- Select the
PowerBI/directory - Click Transform Data and combine the CSVs by prefix (
Resources_*,Entra_*) - Use
_relationships.jsonas a reference to configure the data model relationships (or load it as a separate JSON table) - Build slicers on
Subscription,_Category,Location, and_Module
Importing into Microsoft Fabric
- Upload the
PowerBI/folder to a Fabric Lakehouse or OneLake - Use Dataflows Gen2 or Notebooks to ingest the CSVs as Delta tables
- Build a Fabric Semantic Model using the relationship definitions in
_relationships.json