Private/Console/Write-ReconnaissanceReport.ps1
|
# PSGuerrilla - Jim Tyler, Microsoft MVP - CC BY 4.0 # https://github.com/jimrtyler/PSGuerrilla | https://creativecommons.org/licenses/by/4.0/ # AI/LLM use: see AI-USAGE.md for required attribution function Write-ReconnaissanceReport { [CmdletBinding()] param( [Parameter(Mandatory)] [int]$OverallScore, [Parameter(Mandatory)] [string]$ScoreLabel, [Parameter(Mandatory)] [hashtable]$CategoryScores, [Parameter(Mandatory)] [int]$TotalChecks, [int]$PassCount = 0, [int]$FailCount = 0, [int]$WarnCount = 0, [int]$SkipCount = 0, [int]$CriticalCount = 0, [int]$HighCount = 0, [int]$MediumCount = 0, [int]$LowCount = 0, [PSCustomObject[]]$TopFindings = @(), [string]$DomainName = '' ) Write-Host '' # Header Write-SpectrePanel -Content @( 'R E C O N N A I S S A N C E R E P O R T' 'Active Directory Security Audit' ) -BorderColor 'Olive' -ContentColor 'Olive' -Width 64 Write-Host '' # Domain info if ($DomainName) { Write-GuerrillaText ' Domain: ' -Color Dim -NoNewline Write-GuerrillaText $DomainName -Color Parchment Write-Host '' } # Overall score $scoreColor = if ($OverallScore -ge 90) { 'Sage' } elseif ($OverallScore -ge 75) { 'Olive' } elseif ($OverallScore -ge 60) { 'Gold' } elseif ($OverallScore -ge 40) { 'Amber' } else { 'DeepOrange' } Write-GuerrillaText ' AD Health Score: ' -Color Dim -NoNewline Write-GuerrillaText "$OverallScore / 100" -Color $scoreColor -NoNewline Write-GuerrillaText " [ $ScoreLabel ]" -Color $scoreColor Write-Host '' # Summary stats Write-SpectreBarChart -Items @( @{ Label = 'Passed'; Value = $PassCount; Color = 'Sage' } @{ Label = 'Failed'; Value = $FailCount; Color = 'DeepOrange' } @{ Label = 'Warnings'; Value = $WarnCount; Color = 'Gold' } @{ Label = 'Skipped'; Value = $SkipCount; Color = 'Dim' } ) -Title "Summary ($TotalChecks checks evaluated):" Write-Host '' # Severity breakdown if ($CriticalCount -gt 0 -or $HighCount -gt 0 -or $MediumCount -gt 0 -or $LowCount -gt 0) { $severityItems = @() if ($CriticalCount -gt 0) { $severityItems += @{ Label = 'CRITICAL'; Value = $CriticalCount; Color = 'DeepOrange' } } if ($HighCount -gt 0) { $severityItems += @{ Label = 'HIGH'; Value = $HighCount; Color = 'Amber' } } if ($MediumCount -gt 0) { $severityItems += @{ Label = 'MEDIUM'; Value = $MediumCount; Color = 'Gold' } } if ($LowCount -gt 0) { $severityItems += @{ Label = 'LOW'; Value = $LowCount; Color = 'Sage' } } Write-SpectreBarChart -Items $severityItems -Title 'Findings by severity:' Write-Host '' } # Category scores $catItems = @() foreach ($cat in ($CategoryScores.GetEnumerator() | Sort-Object { $_.Value.Score })) { $catColor = if ($cat.Value.Score -ge 90) { 'Sage' } elseif ($cat.Value.Score -ge 75) { 'Olive' } elseif ($cat.Value.Score -ge 60) { 'Gold' } elseif ($cat.Value.Score -ge 40) { 'Amber' } else { 'DeepOrange' } $catItems += @{ Label = "$($cat.Key) (P:$($cat.Value.Pass) F:$($cat.Value.Fail) W:$($cat.Value.Warn))"; Value = $cat.Value.Score; Color = $catColor } } if ($catItems.Count -gt 0) { Write-SpectreBarChart -Items $catItems -Title 'Category scores:' Write-Host '' } # Top critical/high findings $critical = @($TopFindings | Where-Object { $_.Status -eq 'FAIL' -and $_.Severity -in @('Critical', 'High') } | Select-Object -First 15) if ($critical.Count -gt 0) { $findingRows = @() $findingColors = @() foreach ($f in $critical) { $sevColor = if ($f.Severity -eq 'Critical') { 'DeepOrange' } else { 'Amber' } $currentVal = if ($f.CurrentValue) { $f.CurrentValue } else { '' } $findingRows += , @($f.Severity.ToUpper(), $f.CheckId, $f.CheckName, $currentVal) $findingColors += $sevColor } Write-SpectreTable -Title 'Priority findings' ` -Columns @( @{ Name = 'Severity'; Color = 'DeepOrange' } @{ Name = 'Check ID'; Color = 'Dim' } @{ Name = 'Finding'; Color = 'Olive' } @{ Name = 'Current Value'; Color = 'Dim' } ) -Rows $findingRows -RowColors $findingColors Write-Host '' } Write-GuerrillaText ' ─────────────────────────────────────────────────────────────' -Color Dim Write-GuerrillaText ' PSGuerrilla AD Reconnaissance complete.' -Color Olive Write-Host '' } |