??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 bases $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" { return 0 } "WARN_NO_ALIAS" { return 1 } "OK_QUAR_EXISTS" { return 2 } "OK" { return 3 } default { return 4 } } } # Build alias map: base -> alias files that reference it $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 { $m2=[regex]::Match($raw,'scripts\\\([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 } } } # Build base set: critical + (optionally) all discovered $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 each base $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) } $qCount = (Get-ChildItem -LiteralPath $dirScripts -Filter ($base+".ps1.bad_*") -File -EA SilentlyContinue | Measure-Object).Count $aliasList = $null if($aliasMap.ContainsKey($base)){ $aliasList = $aliasMap[$base] } $status="OK" if(-not $best){ $status="FAIL_NO_ACTIVE" } elseif(-not $aliasList){ 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 = if($best){ $best.Name } else { "" } LatestVersion = if($best){ (Get-Version $best.Name).ToString() } else { "" } AliasFound = if($aliasList){ "Yes" } else { "No" } AliasCount = if($aliasList){ ($aliasList.Count) } else { 0 } QuarantineCount = $qCount Status = $status IsCritical = ($critical -contains $base) } } # Order: critical first, then severity, then name $rows = $rows | Sort-Object @{Expression={ if($_.IsCritical){0}else{1} }}, @{Expression={ Sev $_.Status }}, @{Expression={$_.Base}} # Write 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) # Console issues summary $issues = $rows | Where-Object { $_.Status -like "FAIL*" -or $_.Status -like "WARN*" } if($issues -and $issues.Count -gt 0){ 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) } }