Modules/Private/Export-S2DCsvReport.ps1
|
# CSV data exporter — writes flat per-collector CSVs for spreadsheet / Power BI # consumers who prefer tabular data over nested JSON. Writes multiple files: # # <base>-physical-disks.csv # <base>-volumes.csv # <base>-health-checks.csv # <base>-waterfall.csv # # OutputPath acts as a base name; the four suffixes are derived from it. The # function returns an array of all paths actually written so callers can list # them in reports. function Export-S2DCsvReport { param( [Parameter(Mandatory)] [S2DClusterData] $ClusterData, [Parameter(Mandatory)] [string] $OutputPath, [string] $Author = '', [string] $Company = '', [switch] $IncludeNonPoolDisks # ignored — CSV always contains ALL disks with IsPoolMember column ) $dir = Split-Path $OutputPath -Parent if (-not (Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null } $base = [System.IO.Path]::Combine($dir, [System.IO.Path]::GetFileNameWithoutExtension($OutputPath)) $written = @() # Physical disks $diskPath = "$base-physical-disks.csv" @($ClusterData.PhysicalDisks) | ForEach-Object { [PSCustomObject]@{ NodeName = $_.NodeName FriendlyName = $_.FriendlyName SerialNumber = $_.SerialNumber Model = $_.Model MediaType = $_.MediaType BusType = $_.BusType Role = $_.Role Usage = $_.Usage IsPoolMember = $_.IsPoolMember SizeBytes = $_.SizeBytes SizeTiB = if ($_.Size) { $_.Size.TiB } else { 0 } SizeTB = if ($_.Size) { $_.Size.TB } else { 0 } FirmwareVersion = $_.FirmwareVersion HealthStatus = $_.HealthStatus OperationalStatus = $_.OperationalStatus WearPercentage = $_.WearPercentage Temperature = $_.Temperature PowerOnHours = $_.PowerOnHours PhysicalLocation = $_.PhysicalLocation SlotNumber = $_.SlotNumber } } | Export-Csv -Path $diskPath -NoTypeInformation -Encoding UTF8 $written += $diskPath # Volumes $volPath = "$base-volumes.csv" @($ClusterData.Volumes) | ForEach-Object { [PSCustomObject]@{ FriendlyName = $_.FriendlyName FileSystem = $_.FileSystem ResiliencySettingName = $_.ResiliencySettingName NumberOfDataCopies = $_.NumberOfDataCopies PhysicalDiskRedundancy = $_.PhysicalDiskRedundancy ProvisioningType = $_.ProvisioningType SizeTiB = if ($_.Size) { $_.Size.TiB } else { 0 } SizeTB = if ($_.Size) { $_.Size.TB } else { 0 } FootprintOnPoolTiB = if ($_.FootprintOnPool) { $_.FootprintOnPool.TiB } else { 0 } FootprintOnPoolTB = if ($_.FootprintOnPool) { $_.FootprintOnPool.TB } else { 0 } EfficiencyPercent = $_.EfficiencyPercent IsInfrastructureVolume = $_.IsInfrastructureVolume HealthStatus = $_.HealthStatus OperationalStatus = $_.OperationalStatus IsDeduplicationEnabled = $_.IsDeduplicationEnabled ThinGrowthHeadroomTiB = if ($_.ThinGrowthHeadroom) { $_.ThinGrowthHeadroom.TiB } else { '' } ThinGrowthHeadroomTB = if ($_.ThinGrowthHeadroom) { $_.ThinGrowthHeadroom.TB } else { '' } MaxPotentialFootprintTiB = if ($_.MaxPotentialFootprint) { $_.MaxPotentialFootprint.TiB } else { '' } MaxPotentialFootprintTB = if ($_.MaxPotentialFootprint) { $_.MaxPotentialFootprint.TB } else { '' } } } | Export-Csv -Path $volPath -NoTypeInformation -Encoding UTF8 $written += $volPath # Health checks $hcPath = "$base-health-checks.csv" @($ClusterData.HealthChecks) | ForEach-Object { [PSCustomObject]@{ CheckName = $_.CheckName Severity = $_.Severity Status = $_.Status Details = $_.Details Remediation = $_.Remediation } } | Export-Csv -Path $hcPath -NoTypeInformation -Encoding UTF8 $written += $hcPath # Capacity waterfall if ($ClusterData.CapacityWaterfall) { $wfPath = "$base-waterfall.csv" @($ClusterData.CapacityWaterfall.Stages) | ForEach-Object { [PSCustomObject]@{ Stage = $_.Stage Name = $_.Name SizeBytes = if ($_.Size) { $_.Size.Bytes } else { 0 } SizeTiB = if ($_.Size) { $_.Size.TiB } else { 0 } SizeTB = if ($_.Size) { $_.Size.TB } else { 0 } DeltaBytes = if ($_.Delta) { $_.Delta.Bytes } else { 0 } DeltaTiB = if ($_.Delta) { $_.Delta.TiB } else { 0 } Description = $_.Description Status = $_.Status } } | Export-Csv -Path $wfPath -NoTypeInformation -Encoding UTF8 $written += $wfPath } Write-Verbose "CSV reports written: $($written -join ', ')" $written } |