# kb_bootpack_acceptance_v1.1.ps1 # PowerShell 5.1 only, UTF-8 with BOM, ASCII-safe comments. # Read-only acceptance checker for BootPack BUG_KB_JSON_POINTER. # Prints metrics only (no writes). # Usage: # powershell -NoProfile -ExecutionPolicy Bypass -File .\kb_bootpack_acceptance_v1.1.ps1 -BootPackPath "\\DS-918\...\bootpack\bootpack.txt" param( [Parameter(Mandatory=$true)] [string]$BootPackPath ) function Normalize-Lines { param([string]$Text) if($null -eq $Text){ return @() } $lines = $Text -split "(`r`n|`n|`r)" if($lines.Length -gt 0){ $first = $lines[0] if($null -ne $first -and $first.Length -gt 0){ $bom = [char]0xFEFF if($first[0] -eq $bom){ $lines[0] = $first.Substring(1) } } } return ,$lines } function Find-Pointer { param([string[]]$Lines) $idx = -1 for($i=0; $i -lt $Lines.Length; $i++){ $t = $Lines[$i] if($null -ne $t){ $t = $t.Trim() } else { $t = "" } if($t.ToUpper() -eq "[BUG_KB_JSON_POINTER]"){ $idx = $i; break } } if($idx -lt 0){ return $null } $path = $null $sha = $null $entriesNote = $null for($j=$idx+1; $j -lt $Lines.Length; $j++){ $line = $Lines[$j] if($null -eq $line){ $line = "" } $probe = $line.Trim() if($probe -like "[[]*[]]*"){ break } $eq = $line.IndexOf("=") if($eq -gt 0){ $k = $line.Substring(0, $eq).Trim() $v = $line.Substring($eq+1) # keep internal spaces if($k -ieq "Path"){ $path = $v } elseif($k -ieq "SHA256"){ $sha = $v.Trim() } elseif($k -ieq "Entries"){ $v2 = $v.Trim() [int]$tmp = 0 if([int]::TryParse($v2, [ref]$tmp)){ $entriesNote = $tmp } } } } return @{ Path=$path; SHA256=$sha; Entries=$entriesNote } } function Test-PathVariants { param([string]$RawPath) $result = @{ Raw=$false; Dequoted=$false; Long=$false; Used=$null } $pRaw = $RawPath $pDeq = $RawPath if($null -ne $pDeq){ $pDeq = $pDeq.Trim() if(($pDeq.StartsWith('"')) -and ($pDeq.EndsWith('"'))){ $pDeq = $pDeq.Substring(1, $pDeq.Length-2) } } if($null -ne $pRaw){ if(Test-Path -LiteralPath $pRaw){ $result.Raw = $true; if($null -eq $result.Used){ $result.Used = $pRaw } } } if(!$result.Raw -and $null -ne $pDeq){ if(Test-Path -LiteralPath $pDeq){ $result.Dequoted = $true; if($null -eq $result.Used){ $result.Used = $pDeq } } } if(($null -ne $pDeq) -and ($pDeq.StartsWith("\\")) -and ($pDeq.Length -ge 3)){ $rest = $pDeq.Substring(2) $pLong = "\\?\UNC\" + $rest if(Test-Path -LiteralPath $pLong){ $result.Long = $true; if($null -eq $result.Used){ $result.Used = $pLong } } } return $result } function Read-KbObject { param([string]$KbPath) $raw = Get-Content -LiteralPath $KbPath -Raw if($null -eq $raw){ throw "KB read returned null" } $cut = $raw $footerMarker = "--- DOC-VERSION-FOOTER ---" $idx = $raw.IndexOf($footerMarker) if($idx -ge 0){ $cut = $raw.Substring(0, $idx) } else { $lastBrace = $raw.LastIndexOf("}") if($lastBrace -gt 0){ $cut = $raw.Substring(0, $lastBrace+1) } } $obj = ConvertFrom-Json -InputObject $cut if($null -eq $obj){ throw "KB JSON parse resulted in null" } return $obj } # ---- MAIN ---- $bootText = Get-Content -LiteralPath $BootPackPath -Raw $lines = Normalize-Lines -Text $bootText $ptr = Find-Pointer -Lines $lines $ptrPath = $null; $ptrSha = $null; $ptrEntriesNote = $null if($null -ne $ptr){ $ptrPath = $ptr.Path; $ptrSha = $ptr.SHA256; $ptrEntriesNote = $ptr.Entries } $tp = Test-PathVariants -RawPath $ptrPath $ptrExists = $false $kbPathUsed = $null if($tp.Raw -or $tp.Dequoted -or $tp.Long){ $ptrExists = $true; $kbPathUsed = $tp.Used } $kbSha = "" $jsonEntries = 0 $blocking = 0 if($ptrExists){ try { $kbSha = (Get-FileHash -LiteralPath $kbPathUsed -Algorithm SHA256).Hash.ToUpperInvariant() } catch { $kbSha = "" } try { $kb = Read-KbObject -KbPath $kbPathUsed if($null -ne $kb.entries){ $jsonEntries = @($kb.entries).Count $blocking = @($kb.entries | Where-Object { $_.blocking -eq $true }).Count } } catch { $jsonEntries = 0; $blocking = 0 } } $ptrShaMatch = $false if(($null -ne $ptrSha) -and ($ptrSha.Trim().Length -gt 0) -and ($kbSha.Length -gt 0)){ $ptrShaMatch = ($kbSha -ieq $ptrSha.Trim()) } Write-Host ("entries={0}|blocking={1}|ptr_exists={2}|ptr_sha_match={3}|ptr_entries_note={4}|json_entries={5}" -f $jsonEntries, $blocking, $ptrExists, $ptrShaMatch, ($ptrEntriesNote -as [int]), $jsonEntries)