Pipeline Architecture¶
S2DCartographer is built as a sequential pipeline with a shared session cache at its core. Understanding how the pieces fit together helps when using the module programmatically or troubleshooting unexpected results.
Pipeline Overview¶
flowchart TD
A(["Connect-S2DCluster"]) --> B[("Module Session\nS2DSession")]
B --> C["Get-S2DPhysicalDiskInventory"]
B --> D["Get-S2DStoragePoolInfo"]
B --> E["Get-S2DVolumeMap"]
B --> F["Get-S2DCacheTierInfo"]
C --> G[("S2DClusterData")]
D --> G
E --> G
F --> G
G --> H["Get-S2DCapacityWaterfall"]
G --> I["Get-S2DHealthStatus"]
H --> G
I --> G
G --> J["New-S2DReport"]
G --> K["New-S2DDiagram"]
J --> L[/"HTML · Word · PDF · Excel"/]
K --> M[/"SVG Diagrams"/]
N(["Invoke-S2DCartographer"]) -. "orchestrates" .-> A
N -. "orchestrates" .-> C
N -. "orchestrates" .-> D
N -. "orchestrates" .-> E
N -. "orchestrates" .-> F
N -. "orchestrates" .-> H
N -. "orchestrates" .-> I
N -. "orchestrates" .-> J
N -. "orchestrates" .-> K
Module Session (S2DSession)¶
Connect-S2DCluster creates a script-scoped hashtable ($Script:S2DSession) that all other commands read and write:
$Script:S2DSession = @{
ClusterName = 'c01-prd-bal'
ClusterFqdn = 'c01-prd-bal.contoso.com'
Nodes = @('n01','n02','n03','n04')
CimSession = <CimSession>
PSSession = <PSSession>
IsConnected = $true
IsLocal = $false
CollectedData = @{
PhysicalDisks = $null # populated by Get-S2DPhysicalDiskInventory
StoragePool = $null # populated by Get-S2DStoragePoolInfo
Volumes = $null # populated by Get-S2DVolumeMap
CacheTier = $null # populated by Get-S2DCacheTierInfo
CapacityWaterfall = $null # populated by Get-S2DCapacityWaterfall
HealthChecks = $null # populated by Get-S2DHealthStatus
OverallHealth = $null # set by Get-S2DHealthStatus
}
}
Every collector checks CollectedData before querying the cluster. If data is already present, it is returned from cache without a network round-trip. This means calling Get-S2DCapacityWaterfall twice only hits the cluster once.
S2DClusterData Object¶
Invoke-S2DCartographer -PassThru and the individual collectors all build toward the same S2DClusterData object passed to report and diagram generators:
| Property | Type | Source |
|---|---|---|
ClusterName |
string |
Session |
NodeCount |
int |
Session |
PhysicalDisks |
S2DPhysicalDisk[] |
Get-S2DPhysicalDiskInventory |
StoragePool |
S2DStoragePool |
Get-S2DStoragePoolInfo |
Volumes |
S2DVolume[] |
Get-S2DVolumeMap |
CacheTier |
S2DCacheTier |
Get-S2DCacheTierInfo |
CapacityWaterfall |
S2DCapacityWaterfall |
Get-S2DCapacityWaterfall |
HealthChecks |
S2DHealthCheck[] |
Get-S2DHealthStatus |
OverallHealth |
string |
Get-S2DHealthStatus |
CollectedAt |
datetime |
Orchestrator |
Collector Call Order¶
Invoke-S2DCartographer calls collectors in dependency order:
Get-S2DPhysicalDiskInventory— no dependenciesGet-S2DStoragePoolInfo— no dependenciesGet-S2DVolumeMap— no dependenciesGet-S2DCacheTierInfo— no dependenciesGet-S2DCapacityWaterfall— depends on 1, 2, 3Get-S2DHealthStatus— depends on 1, 2, 3, 4, 5
When called individually, each collector auto-invokes its prerequisites if their results are not already cached.
CIM vs PS Sessions¶
S2DCartographer uses two session types in parallel:
| Session | Used For |
|---|---|
CimSession |
Storage queries (Get-PhysicalDisk, Get-StoragePool, Get-VirtualDisk, etc.) |
PSSession |
Node-level queries that require per-node execution (disk inventory loop, reliability counters) |
Both are established by Connect-S2DCluster and closed by Disconnect-S2DCluster. If you pass an existing CimSession, no PSSession is created — node-level queries fall back to per-node Invoke-Command using the CIM session's credentials.
Using the Pipeline Manually¶
You do not need Invoke-S2DCartographer — all commands are composable:
Connect-S2DCluster -ClusterName "c01-prd-bal" -Credential $cred
$disks = Get-S2DPhysicalDiskInventory
$pool = Get-S2DStoragePoolInfo
$vols = Get-S2DVolumeMap
$wf = Get-S2DCapacityWaterfall
$health = Get-S2DHealthStatus
# Build the data object manually
$data = [S2DClusterData]::new()
$data.ClusterName = 'c01-prd-bal'
$data.PhysicalDisks = $disks
$data.StoragePool = $pool
$data.Volumes = $vols
$data.CapacityWaterfall = $wf
$data.HealthChecks = $health
New-S2DReport -InputObject $data -Format Html -OutputDirectory "C:\Reports\"
New-S2DDiagram -InputObject $data -DiagramType All -OutputDirectory "C:\Reports\"
Disconnect-S2DCluster