Skip to content

Output Files

Default Output Location

OSBase path
WindowsC:\AzureScout\
Linux / macOS$HOME/AzureScout/

Override the base with -ReportDir:

powershell
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.json

Name the folder yourself with -RunName instead of taking the generated timestamp:

powershell
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:

powershell
Invoke-AzureScout -TenantID '00000000-...' -ReportDir 'D:\Reports' -Force
# → D:\Reports\ReportCache\, inventory JSON, and assessment-report\ with React/evidence files

Pruning old runs

Run folders accumulate. Remove the ones older than a given number of days:

powershell
# 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.

FileFormatDescription
assessment-report/report-react.htmlReact/HTMLThe 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>.jsonJSONThe existing AzureScout inventory JSON/schema, selected with Json
assessment-report/evidence.jsonJSONResources-only canonical Collect data, including collection provenance and already-collected Entra rows, with no scores, rules, or findings; selected with JsonEvidence
assessment-report/collect.jsonJSONInternal canonical Collect snapshot used to render the React/evidence outputs without another Azure or Graph query
assessment-report/findings.jsonJSONInternal scored-findings envelope; neutral and empty for inventory-only runs
AzureScout_Diagram_<timestamp>.drawioDraw.ioNetwork topology diagram (skip with -SkipDiagram)
scout-run.logLogDetailed 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.logLogConsole transcript for the run. Skipped on hosts without transcription support
raw-inventory.jsonJSONEverything collected, before any manifest decided what to display (see below)
collector-rowcounts.jsonJSONWhat each collector produced, and why it produced nothing (see below)
collection-health.jsonJSONUpstream 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.

json
{
  "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.

VerdictMeaning
RowsThe collector ran and produced data
EmptyThe collector ran cleanly and produced nothing — the estate has none of this type
FailedThe collector threw. Error carries the message, and the empty worksheet is explained
json
{
  "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:

powershell
$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, Verdict

JSON Structure

json
{
  "_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, timestamp
  • arm — ARM resources grouped by category
  • entra — Entra ID objects grouped by type
  • advisory / 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:

  1. Overview — Tenant metadata, resource summary, execution info
  2. Cost Management — Reservations, cost recommendations, spend analysis
  3. Security Overview — Defender secure score, assessments, alerts, policy compliance
  4. Azure Update Manager Overview — VM/Arc patch compliance, maintenance schedules
  5. Azure Monitor — Action groups, alert rules, DCRs, workspaces, diagnostic settings
  6. Resource tabs — One worksheet per ARM resource type (Subscriptions, VMs, Networks, etc.)
  7. Entra ID tabs — One worksheet per Entra module (Users, Groups, Conditional Access, etc.)
  8. 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:

powershell
# 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 All

Legacy 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 module

Every 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

  1. Open Power BI Desktop → Get DataFolder
  2. Select the PowerBI/ directory
  3. Click Transform Data and combine the CSVs by prefix (Resources_*, Entra_*)
  4. Use _relationships.json as a reference to configure the data model relationships (or load it as a separate JSON table)
  5. Build slicers on Subscription, _Category, Location, and _Module

Importing into Microsoft Fabric

  1. Upload the PowerBI/ folder to a Fabric Lakehouse or OneLake
  2. Use Dataflows Gen2 or Notebooks to ingest the CSVs as Delta tables
  3. Build a Fabric Semantic Model using the relationship definitions in _relationships.json

Released under the MIT License.