Public/New-MgkHtmlReport.ps1
|
function New-MgkHtmlReport { <# .SYNOPSIS Renders objects into a styled HTML report. .DESCRIPTION Generic object-table renderer with MSP-report styling: title, run timestamp, summary line, and severity-aware row colouring — any input object with a Severity property of Critical/Warning/Error gets a coloured row; objects with Success=$false are highlighted too. All values are HTML-encoded. .PARAMETER InputObject Objects to render (pipeline-friendly). Property names become columns, taken from the first object. .PARAMETER Title Report heading. .PARAMETER OutFile Destination HTML path. The rendered path is also returned. .EXAMPLE $sweepResults | New-MgkHtmlReport -Title 'Fleet license check' -OutFile report.html #> [CmdletBinding(SupportsShouldProcess)] [OutputType([string])] param( [Parameter(Mandatory, ValueFromPipeline)][object[]]$InputObject, [Parameter(Mandatory)][string]$Title, [Parameter(Mandatory)][string]$OutFile ) begin { $items = [System.Collections.Generic.List[object]]::new() } process { $items.AddRange(@($InputObject)) } end { if ($items.Count -eq 0) { throw 'No input objects to render.' } if (-not $PSCmdlet.ShouldProcess($OutFile, 'Write HTML report')) { return } $encode = { param($v) [System.Web.HttpUtility]::HtmlEncode("$v") } $columns = $items[0].PSObject.Properties.Name $rows = foreach ($item in $items) { $cls = '' if ($item.PSObject.Properties['Severity']) { $cls = switch ("$($item.Severity)") { 'Critical' { 'crit' } 'Error' { 'crit' } 'Warning' { 'warn' } default { '' } } } elseif ($item.PSObject.Properties['Success'] -and -not $item.Success) { $cls = 'crit' } $cells = ($columns | ForEach-Object { "<td>$(& $encode $item.$_)</td>" }) -join '' "<tr class='$cls'>$cells</tr>" } $flagged = @($rows | Where-Object { $_ -match "class='(crit|warn)'" }).Count @" <!DOCTYPE html><html><head><meta charset='utf-8'><title>$(& $encode $Title)</title><style> body{font-family:Segoe UI,sans-serif;margin:2rem;color:#222} h1{margin-bottom:.2rem} .meta{color:#777;margin-bottom:1.2rem} table{border-collapse:collapse;width:100%}th,td{padding:.45rem .7rem;border:1px solid #ddd;text-align:left;font-size:.9rem} th{background:#2c3e50;color:#fff} tr.crit td{background:#fdecea}tr.warn td{background:#fef5e7} </style></head><body> <h1>$(& $encode $Title)</h1> <p class='meta'>Generated $(Get-Date -Format 'yyyy-MM-dd HH:mm') · $($items.Count) rows · $flagged flagged</p> <table><tr>$(($columns | ForEach-Object { "<th>$(& $encode $_)</th>" }) -join '')</tr> $($rows -join "`n") </table></body></html> "@ | Set-Content -Path $OutFile -Encoding utf8 (Resolve-Path $OutFile).Path } } |