Cluster Snapshot JSON Schema¶
The .json file written to every per-run folder by Invoke-S2DCartographer (and by New-S2DReport -Format Json) is a structured snapshot of the collected cluster data. The schema is a stable API — downstream tools can depend on the shape of this file.
- File name:
S2DCartographer_<ClusterName>_<yyyyMMdd-HHmm>.json - Encoding: UTF-8
- Pretty-printed: yes (for git-diff friendliness)
- Canonical sample:
samples/cluster-snapshot.json
Versioning¶
The top-level SchemaVersion field is SemVer-ish:
- Minor bumps (e.g.,
1.0→1.1) — additive changes only (new optional fields) - Major bumps (e.g.,
1.x→2.0) — rename, removal, or meaning change of an existing field
Downstream tools should read SchemaVersion, tolerate minor bumps, and fail fast on major bumps with a clear message.
Current version: 1.0
Top-level shape¶
{
"SchemaVersion": "1.0",
"Generated": { ... },
"Cluster": { ... },
"OverallHealth": "Healthy | Warning | Critical | Fail | Unknown",
"PhysicalDisks": [ ... ],
"StoragePool": { ... },
"Volumes": [ ... ],
"CacheTier": { ... },
"CapacityWaterfall": { ... },
"HealthChecks": [ ... ]
}
Generated¶
Metadata about the run that produced this snapshot.
| Field | Type | Description |
|---|---|---|
Timestamp |
string (ISO 8601 UTC) | When the JSON was written |
ModuleVersion |
string | S2DCartographer module version that produced the file |
Author |
string | Passed via -Author on the run (may be empty) |
Company |
string | Passed via -Company on the run (may be empty) |
Cluster¶
Cluster metadata and node list.
| Field | Type | Description |
|---|---|---|
Name |
string | Cluster name as returned by the cluster itself |
Fqdn |
string | Resolved FQDN used for the CIM session |
NodeCount |
int | Number of cluster nodes |
Nodes |
array of string | Short node names |
CollectedAt |
string (ISO 8601 UTC) | When collection started |
OverallHealth¶
Rolled-up health status computed from HealthChecks[]. One of:
Healthy— every check passedWarning— at least one non-critical check failedCritical/Fail— at least one critical check failedUnknown— checks were skipped (-SkipHealthChecks)
PhysicalDisks[]¶
One entry per physical disk visible to any cluster node. Every disk is included, including boot drives and SAN-presented LUNs — use IsPoolMember to filter if you only want S2D pool members.
| Field | Type | Description |
|---|---|---|
NodeName |
string | Node where the disk is enumerated |
DiskNumber |
int | Windows disk number |
UniqueId |
string | Disk unique ID |
FriendlyName |
string | Human-friendly disk name |
SerialNumber |
string | Manufacturer serial |
Model |
string | Model string |
MediaType |
string | NVMe / SSD / HDD / Unspecified |
BusType |
string | NVMe / SAS / SATA / FC / etc. |
FirmwareVersion |
string | Firmware string |
Manufacturer |
string | Vendor name |
Role |
string | Cache / Capacity / Unknown (Unknown means not a pool member) |
Usage |
string | Windows disk usage: Auto-Select / Journal / ManualSelect / HotSpare |
CanPool |
bool | Windows reports that this disk could be added to a pool |
IsPoolMember |
bool | Whether the disk is a member of the S2D storage pool. Filter on this to exclude boot drives / SAN LUNs. |
HealthStatus |
string | Healthy / Warning / Unhealthy / Unknown |
OperationalStatus |
string | Windows operational status |
PhysicalLocation |
string | Enclosure / slot description |
SlotNumber |
int | Physical slot number |
Size |
S2DCapacity |
Disk capacity |
SizeBytes |
int64 | Convenience — flat bytes |
Temperature |
int | Celsius (if reported) |
WearPercentage |
int | SSD wear % (NVMe / SSD only) |
PowerOnHours |
int | Cumulative power-on hours |
ReadErrors / WriteErrors |
int | Counters |
ReadLatency / WriteLatency |
int | Milliseconds |
StoragePool¶
Properties of the single S2D storage pool.
| Field | Type | Description |
|---|---|---|
FriendlyName |
string | Pool name |
HealthStatus |
string | Healthy / Warning / Unhealthy |
OperationalStatus |
string | Windows operational status |
IsReadOnly |
bool | |
TotalSize |
S2DCapacity |
Full pool capacity |
AllocatedSize |
S2DCapacity |
Consumed by volumes |
RemainingSize |
S2DCapacity |
Free pool space |
ProvisionedSize |
S2DCapacity |
Logical sum of volume sizes (thin-provisioning visible here) |
OvercommitRatio |
double | ProvisionedSize / TotalSize |
FaultDomainAwareness |
string | StorageScaleUnit / Rack / etc. |
ResiliencySettings |
array | Per-setting resiliency definitions |
StorageTiers |
array | Pool tier definitions |
Volumes[]¶
One entry per volume in the pool.
| Field | Type | Description |
|---|---|---|
FriendlyName |
string | Volume name |
FileSystem |
string | ReFS / NTFS / CSVFS_ReFS |
ResiliencySettingName |
string | Mirror / Parity / Mirror-Accelerated Parity |
NumberOfDataCopies |
int | 2 / 3 for two-way / three-way mirror |
PhysicalDiskRedundancy |
int | Failures the volume can survive |
ProvisioningType |
string | Thin / Fixed |
Size |
S2DCapacity |
Volume size presented to VMs |
FootprintOnPool |
S2DCapacity |
Actual pool consumption (size × resiliency multiplier) |
AllocatedSize |
S2DCapacity |
Data written |
EfficiencyPercent |
double | Size / FootprintOnPool × 100 |
OvercommitRatio |
double | For thin volumes |
IsInfrastructureVolume |
bool | Azure Local management-plane volume |
IsDeduplicationEnabled |
bool | |
HealthStatus / OperationalStatus |
string |
CacheTier¶
| Field | Type | Description |
|---|---|---|
CacheMode |
string | ReadWrite / ReadOnly / Disabled |
IsAllFlash |
bool | All-flash cluster detection |
SoftwareCacheEnabled |
bool | S2D software write-back cache enabled |
CacheDiskCount |
int | Number of cache drives across all nodes |
CacheDiskModel |
string | Cache drive model |
CacheDiskSize |
S2DCapacity |
Per-drive size |
CacheToCapacityRatio |
double | Ratio of cache bytes to capacity bytes |
CacheState |
string | Active / Degraded / Disabled |
WriteCacheSizeBytes |
int64 | Bytes per capacity drive reserved for cache |
CapacityWaterfall¶
The 7-stage capacity accounting model.
| Field | Type | Description |
|---|---|---|
Stages |
array of S2DWaterfallStage |
Ordered array, 8 entries |
RawCapacity |
S2DCapacity |
Stage 1 |
UsableCapacity |
S2DCapacity |
Stage 7 (pipeline terminus) |
ReserveRecommended |
S2DCapacity |
Best-practice reserve |
ReserveActual |
S2DCapacity |
Actual free pool space |
ReserveStatus |
string | Adequate / Warning / Critical |
IsOvercommitted |
bool | Pool is overcommitted |
OvercommitRatio |
double | Overcommit ratio |
NodeCount |
int | Nodes used in the calculation |
BlendedEfficiencyPercent |
double | Weighted resiliency efficiency across volumes |
Stages[] entry (S2DWaterfallStage)¶
| Field | Type | Description |
|---|---|---|
Stage |
int | 1–8 |
Name |
string | Stage name |
Size |
S2DCapacity |
Remaining capacity at this stage |
Delta |
S2DCapacity |
Reduction from previous stage |
Description |
string | Human-readable description |
Status |
string | OK / Warn / Fail |
HealthChecks[]¶
One entry per check (10 at time of writing).
| Field | Type | Description |
|---|---|---|
CheckName |
string | Stable identifier (e.g., ReserveAdequacy, DiskSymmetry, NVMeWear) |
Severity |
string | Info / Warning / Critical |
Status |
string | Pass / Warn / Fail |
Details |
string | Human-readable detail text |
Remediation |
string | Suggested fix |
S2DCapacity¶
Every size field in the schema is an S2DCapacity object with both binary and decimal units. Downstream consumers never have to convert.
{
"Bytes": 3840000000000,
"TiB": 3.49,
"TB": 3.84,
"GiB": 3576.28,
"GB": 3840.0,
"Display": "3.49 TiB (3.84 TB)"
}
Consuming the snapshot¶
PowerShell¶
$snap = Get-Content ./S2DCartographer_*.json -Raw | ConvertFrom-Json
$snap.PhysicalDisks | Where-Object IsPoolMember | Measure-Object -Property SizeBytes -Sum
$snap.HealthChecks | Where-Object Status -ne 'Pass'
jq¶
jq '.PhysicalDisks | map(select(.IsPoolMember)) | length' snapshot.json
jq '.CapacityWaterfall.UsableCapacity.TiB' snapshot.json
jq '.HealthChecks[] | select(.Status != "Pass") | {CheckName, Status, Details}' snapshot.json
Python¶
import json
with open('snapshot.json') as f:
snap = json.load(f)
pool_disks = [d for d in snap['PhysicalDisks'] if d.get('IsPoolMember')]
print(f"{len(pool_disks)} pool-member disks totaling {snap['CapacityWaterfall']['RawCapacity']['TB']} TB raw")
Stability guarantees¶
- Field names — stable within a major SchemaVersion
- Field types — stable within a major SchemaVersion
- Field presence — required fields listed above are always present. Optional fields (e.g., OEM enrichment fields added by future features) will be documented separately and absent when not applicable.
- Array ordering —
CapacityWaterfall.Stages[]is always ordered 1→8. Other arrays (disks, volumes, nodes, health checks) have no guaranteed order — sort by a stable field if ordering matters.
Related¶
reports.md— All supported output formatscollectors/physical-disks.md—IsPoolMemberand what counts as a pool diskcapacity-math.md— How the waterfall stages are computed