param([switch]$Full) try { [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding } catch {} $here = $PSScriptRoot; if(-not $here){ $here = Split-Path -Parent $MyInvocation.MyCommand.Path } $registry = Split-Path -Parent $here $dirScripts = Join-Path $registry "scripts" $dirBin = Join-Path $registry "bin" $dirReports = Join-Path $registry "reports" if(!(Test-Path $dirReports)){ New-Item -ItemType Directory -Force -Path $dirReports | Out-Null } $ts = Get-Date -Format "yyyyMMdd_HHmmss" $report = Join-Path $dirReports ("scripts_baseline_dashboard_"+$ts+".txt") $critical = @( "gov_profile_launcher","rebuild_bootpack_full_hub","rebuild_bootpack_full_seedbox", "writer_posthook_runner","text_encoding_guard","ps_script_linter","safe_write_text", "write_devlock_debugkit_rule","project_profile_echo","encoding_policy_resolver","view_utf8", "run_encoding_maintenance","ps_scripts_sanitize_and_quarantine","gov_pipeline_guard", "kb_guard_validator","kb_emit_bootpack_dual","export_bootpack_txt","fix_manifest_sha","kb_quicklog_and_sync" ) function Get-Version([string]$name){ $m=[regex]::Match($name,'_v([0-9]+(?:\.[0-9]+)*)\.ps1$') if($m.Success){ try { return [version]$m.Groups[1].Value } catch { return [version]"0.0" } } return [version]"0.0" } function Sev([string]$status){ switch($status){ "FAIL_NO_ACTIVE" {0} "WARN_NO_ALIAS" {1} "OK_QUAR_EXISTS" {2} "OK" {3} default {4} } } # Alias mapping $aliasFiles = @() $aliasFiles += Get-ChildItem -LiteralPath $dirBin -Filter "*_latest.cmd" -File -EA SilentlyContinue $aliasFiles += Get-ChildItem -LiteralPath $dirScripts -Filter "*_latest.cmd" -File -EA SilentlyContinue $aliasMap = @{} foreach($a in $aliasFiles){ $raw = Get-Content -LiteralPath $a.FullName -Raw -Encoding UTF8 $m = [regex]::Match($raw,'-Base\s+"([^"]+)"') if($m.Success){ $b=$m.Groups[1].Value if(-not $aliasMap.ContainsKey($b)){ $aliasMap[$b]=@() } $aliasMap[$b]+=$a.FullName } else { # support backslash or slash $m2=[regex]::Match($raw,'scripts[\\/]{1}([A-Za-z0-9_\-]+)_v[0-9.]+\.ps1') if($m2.Success){ $b=$m2.Groups[1].Value if(-not $aliasMap.ContainsKey($b)){ $aliasMap[$b]=@() } $aliasMap[$b]+=$a.FullName } } } # Base set $allBases = New-Object System.Collections.Generic.HashSet[string] foreach($b in $critical){ [void]$allBases.Add($b) } if($Full){ $all = Get-ChildItem -LiteralPath $dirScripts -Filter "*_v*.ps1" -File -EA SilentlyContinue | ForEach-Object { $_.BaseName -replace "_v[0-9.]+$","" } | Sort-Object -Unique foreach($b in $all){ [void]$allBases.Add($b) } } # Inspect $rows = @() foreach($base in $allBases){ $pattern = $base + "_v*.ps1" $cands = Get-ChildItem -LiteralPath $dirScripts -Filter $pattern -File -EA SilentlyContinue $best = $null if($cands){ $best = ($cands | Sort-Object @{Expression={ Get-Version $_.Name };Descending=$true}, @{Expression={$_.LastWriteTime};Descending=$true} | Select-Object -First 1) } $latestName=""; $latestVersion="" if($best){ $latestName=$best.Name; $latestVersion=(Get-Version $best.Name).ToString() } $qCount = (Get-ChildItem -LiteralPath $dirScripts -Filter ($base+".ps1.bad_*") -File -EA SilentlyContinue | Measure-Object).Count $aliasFound="No"; $aliasCount=0 if($aliasMap.ContainsKey($base)){ $aliasFound="Yes" $aliasCount=$aliasMap[$base].Count } $status="OK" if(-not $best){ $status="FAIL_NO_ACTIVE" } elseif($aliasFound -eq "No"){ if($critical -contains $base){ $status="WARN_NO_ALIAS"} else { $status="INFO_NO_ALIAS" } } if($qCount -gt 0 -and $status -eq "OK"){ $status="OK_QUAR_EXISTS" } $rows += [PSCustomObject]@{ Base=$base LatestPS1=$latestName LatestVersion=$latestVersion AliasFound=$aliasFound AliasCount=$aliasCount QuarantineCount=$qCount Status=$status IsCritical=($critical -contains $base) } } $rows = $rows | Sort-Object @{Expression={ if($_.IsCritical){0}else{1} }}, @{Expression={ Sev $_.Status }}, @{Expression={$_.Base}} # Report "=== SCRIPTS BASELINE DASHBOARD === " + (Get-Date -Format s) | Out-File -LiteralPath $report -Encoding UTF8 "Root = "+$registry | Out-File -LiteralPath $report -Append -Encoding UTF8 "" | Out-File -LiteralPath $report -Append -Encoding UTF8 ("{0,-34} {1,-34} {2,-8} {3,-5} {4,-5} {5,-4} {6}" -f "Base","LatestPS1","Version","Alias","Alias#","Qbad","Status") | Out-File -LiteralPath $report -Append -Encoding UTF8 $rows | ForEach-Object { ("{0,-34} {1,-34} {2,-8} {3,-5} {4,-5} {5,-4} {6}" -f $_.Base, $_.LatestPS1, $_.LatestVersion, $_.AliasFound, $_.AliasCount, $_.QuarantineCount, $_.Status) | Out-File -LiteralPath $report -Append -Encoding UTF8 } Write-Host ("Report -> "+$report) $issues = $rows | Where-Object { $_.Status -like "FAIL*" -or $_.Status -like "WARN*" } if($issues){ Write-Host ""; Write-Host "Issues:"; foreach($r in $issues){ Write-Host (" - {0} :: {1} (alias={2}, qbad={3})" -f $r.Base,$r.Status,$r.AliasFound,$r.QuarantineCount) } }