Public/Export-InfraPulseComparison.ps1
|
function Export-InfraPulseComparison { <# .SYNOPSIS Exports InfraPulse comparisons to HTML, JSON, or CSV. .DESCRIPTION Collects InfraPulse.Comparison objects from the pipeline and writes a self-contained HTML change report, a structured JSON array, or a flattened CSV dataset with one row per classified change. .PARAMETER InputObject One or more InfraPulse.Comparison objects produced by Compare-InfraPulseReport. .PARAMETER Path Destination file path. .PARAMETER Format Html, Json, or Csv. When omitted, the format is inferred from the file extension and defaults to Html. .PARAMETER Title Title used in the HTML report. .PARAMETER Force Overwrites an existing file. .PARAMETER PassThru Returns the created file. .EXAMPLE Compare-InfraPulseReport $before $after | Export-InfraPulseComparison -Path .\evidence\change-report.html -Force .EXAMPLE $comparison | Export-InfraPulseComparison -Path .\evidence\change.csv -Format Csv -Force #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Low')] param( [Parameter(Mandatory, ValueFromPipeline)] [ValidateNotNull()] [object]$InputObject, [Parameter(Mandatory, Position = 0)] [ValidateNotNullOrEmpty()] [string]$Path, [ValidateSet('Html', 'Json', 'Csv')] [string]$Format, [ValidateNotNullOrEmpty()] [string]$Title = 'Infrastructure Change Report', [switch]$Force, [switch]$PassThru ) begin { $comparisons = New-Object System.Collections.Generic.List[object] } process { if ($null -eq $InputObject.PSObject.Properties['Changes'] -or $null -eq $InputObject.PSObject.Properties['HasRegressions']) { throw 'InputObject is not an InfraPulse comparison.' } [void]$comparisons.Add($InputObject) } end { if ($comparisons.Count -eq 0) { throw 'No InfraPulse comparisons were supplied.' } $comparisonArray = @($comparisons.ToArray()) $resolvedPath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Path) if (-not $PSBoundParameters.ContainsKey('Format')) { switch ([System.IO.Path]::GetExtension($resolvedPath).ToLowerInvariant()) { '.json' { $Format = 'Json' } '.csv' { $Format = 'Csv' } default { $Format = 'Html' } } } if ((Test-Path -LiteralPath $resolvedPath) -and -not $Force) { throw "File already exists: '$resolvedPath'. Use -Force to overwrite it." } $parent = Split-Path -Path $resolvedPath -Parent if (-not (Test-Path -LiteralPath $parent)) { $null = New-Item -Path $parent -ItemType Directory -Force } if (-not $PSCmdlet.ShouldProcess($resolvedPath, "Export InfraPulse $Format comparison")) { return } switch ($Format) { 'Html' { $content = ConvertTo-InfraPulseComparisonHtmlReport -Comparisons $comparisonArray -Title $Title } 'Json' { $content = ConvertTo-Json -InputObject (ConvertTo-InfraPulseSerializableValue -Value $comparisonArray) -Depth 12 } 'Csv' { $rows = foreach ($comparison in $comparisonArray) { foreach ($change in @($comparison.Changes)) { [pscustomobject][ordered]@{ ComputerName = [string]$comparison.ComputerName ChangeType = [string]$change.ChangeType CheckName = [string]$change.CheckName Category = [string]$change.Category Target = [string]$change.Target ReferenceStatus = [string]$change.ReferenceStatus DifferenceStatus = [string]$change.DifferenceStatus ReferenceObservedValue = [string]$change.ReferenceObservedValue DifferenceObservedValue = [string]$change.DifferenceObservedValue ReferenceMessage = [string]$change.ReferenceMessage DifferenceMessage = [string]$change.DifferenceMessage EvidenceChanged = [string]$change.EvidenceChanged } } } $content = @($rows | ConvertTo-Csv -NoTypeInformation) -join [Environment]::NewLine } } Write-InfraPulseUtf8File -Path $resolvedPath -Content $content if ($PassThru) { return Get-Item -LiteralPath $resolvedPath } } } |