# kb_quicklog_and_sync_v1.3.ps1 # Purpose: Collect sizes, SHA, entries, mojibake counters; PREVIEW = no write, EXECUTE = append one line to logs\registry_activity.log. # PS 5.1-safe, no ternary, UTF-8 BOM. [CmdletBinding()] param( [switch]$Preview, [switch]$Execute, [string]$Root = "\\DS-918\chatgpt\ChatGPT-Gouvernance-Projets\_registry" ) function Ensure-Dir([string]$Path){ if(-not (Test-Path -LiteralPath $Path)){ New-Item -ItemType Directory -Force -Path $Path | Out-Null } } function Read-JsonSansFooter([string]$Path){ $sr = New-Object IO.StreamReader($Path) try{ $L = New-Object 'System.Collections.Generic.List[string]' while(-not $sr.EndOfStream){ $line = $sr.ReadLine() if($line -match '^\s*---\s*DOC-VERSION-FOOTER'){ break } $L.Add($line) | Out-Null } ($L -join "`n") } finally { $sr.Dispose() } } function Get-FileSHA256([string]$Path){ if(-not(Test-Path -LiteralPath $Path)){ return "" } $sha=[Security.Cryptography.SHA256]::Create() $fs=[IO.File]::OpenRead($Path) try{ -join ($sha.ComputeHash($fs) | ForEach-Object { $_.ToString("x2") }) } finally { $fs.Dispose(); $sha.Dispose() } } $start = Get-Date $BugKbDir = Join-Path $Root "bug_kb" $BootDir = Join-Path $Root "bootpack" $LogsDir = Join-Path $Root "logs" Ensure-Dir $BugKbDir; Ensure-Dir $BootDir; Ensure-Dir $LogsDir $KbPath = Join-Path $BugKbDir "BUG_KB.json.txt" $BootPaste = Join-Path $BootDir "bootpack_paste.txt" $BootTxt = Join-Path $BootDir "bootpack.txt" $LogFile = Join-Path $LogsDir "registry_activity.log" # ---- KB ---- $kbSize = 0; $kbSha = ""; $kbEntries = -1; $kbMojibake = -1 if(Test-Path -LiteralPath $KbPath){ $kbSize = (Get-Item -LiteralPath $KbPath).Length $kbSha = Get-FileSHA256 $KbPath $raw = Read-JsonSansFooter $KbPath try { $obj = $raw | ConvertFrom-Json -ErrorAction Stop $kbEntries = 0 if($obj -and ($obj.PSObject.Properties.Name -contains 'entries') -and $obj.entries){ try { $kbEntries = $obj.entries.Count } catch { $kbEntries = 0 } } } catch { $kbEntries = -1 } $kbMojibake = ([regex]::Matches($raw,'�|�|’|“|�|?|@\{')).Count } # ---- PASTE ---- $pasteSize = 0; $pasteSha = "" if(Test-Path -LiteralPath $BootPaste){ $pasteSize = (Get-Item -LiteralPath $BootPaste).Length $pasteSha = Get-FileSHA256 $BootPaste } # ---- BOOT ---- $bootSize = 0; $bootSha = "" if(Test-Path -LiteralPath $BootTxt){ $bootSize = (Get-Item -LiteralPath $BootTxt).Length $bootSha = Get-FileSHA256 $BootTxt } $durationMs = [int]((Get-Date) - $start).TotalMilliseconds # ---- PREVIEW ---- if($Preview -or (-not $Execute)){ Write-Host "== PREVIEW :: QUICKLOG v1.3 ==" Write-Host ("Root : {0}" -f $Root) Write-Host ("KB : size={0:n0} sha={1} entries={2} mojibake={3}" -f $kbSize,$kbSha,$kbEntries,$kbMojibake) Write-Host ("PASTE : size={0:n0} sha={1}" -f $pasteSize,$pasteSha) Write-Host ("BOOT : size={0:n0} sha={1}" -f $bootSize,$bootSha) Write-Host ("Duration(ms) : {0}" -f $durationMs) Write-Host "No write performed (Preview)." exit 0 } # ---- EXECUTE ---- $line = "{0} action=quicklog root=""{1}"" kb_size={2} kb_sha={3} kb_entries={4} kb_mojibake={5} paste_size={6} paste_sha={7} boot_size={8} boot_sha={9} duration_ms={10}" ` -f ((Get-Date).ToString("yyyy-MM-ddTHH:mm:ssK")), $Root, $kbSize, $kbSha, $kbEntries, $kbMojibake, $pasteSize, $pasteSha, $bootSize, $bootSha, $durationMs $utf8 = New-Object Text.UTF8Encoding($true) $sw = New-Object IO.StreamWriter($LogFile, $true, $utf8) try { $sw.WriteLine($line) } finally { $sw.Dispose() } Write-Host "[OK] quicklog ecrit -> $LogFile" Write-Host $line