param( [ValidateSet("Preview","Fix")] [string]$Mode="Preview", [switch]$VerboseLog ) 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 $logsDir = Join-Path $registry "logs"; if(!(Test-Path $logsDir)){ New-Item -ItemType Directory -Force -Path $logsDir|Out-Null } $ts = Get-Date -Format "yyyyMMdd_HHmmss" $log = Join-Path $logsDir ("run_ps_sanitize_"+$ts+".txt") function Log([string]$m){ Add-Content -LiteralPath $log -Value $m -Encoding UTF8; Write-Host $m } $targets = Get-ChildItem -LiteralPath (Join-Path $registry "scripts") -Filter "*.ps1" -File -EA SilentlyContinue | Sort-Object FullName $badText = @( ) $mapPairs = @( 0x2018,0x0027, 0x2019,0x0027, 0x201C,0x0022, 0x201D,0x0022, 0x00A0,0x0020, 0x2013,0x002D, 0x2014,0x002D, 0x2026,0x002E # ellipsis -> '.' ) Log ("SANITIZE SCRIPTS - "+(Get-Date -Format s)+" - Mode="+$Mode) foreach($fi in $targets){ $p=$fi.FullName try{ $raw = Get-Content -LiteralPath $p -Raw -Encoding UTF8 $orig=$raw # 1) remplacements unicode -> ASCII basique $chars=$raw.ToCharArray() $changed=$false for($i=0;$i -lt $chars.Length;$i++){ $c=[int]$chars[$i] for($j=0;$j -lt $mapPairs.Length;$j+=2){ if($c -eq $mapPairs[$j]){ $chars[$i] = [char]$mapPairs[$j+1] $changed=$true break } } } if($changed){ $raw = -join $chars } # 2) normaliser fins de ligne $raw = $raw -replace "`r`n","`n" $raw = $raw -replace "`r","`n" $raw = [string]::Join("`r`n",($raw -split "`n")) # 3) supprimer lignes clairement issues d'un collage d'erreur $lines = $raw -split "`r`n" $keep=@() foreach($ln in $lines){ $sus=$false foreach($pat in $badText){ if($ln -like "*$pat*"){ $sus=$true; break } } if(-not $sus){ $keep += $ln } } $fixed = [string]::Join("`r`n",$keep) # 4) parse test $errs=@() [void][System.Management.Automation.PSParser]::Tokenize($fixed,[ref]$errs) if($Mode -eq "Preview"){ $msg = if($errs.Count -gt 0){"PREVIEW :: FAIL tokens="+$errs.Count}else{"PREVIEW :: OK"} Log ($p+" :: "+$msg) continue } # Mode Fix $bak=$p+'.bak_'+(Get-Date -Format "yyyyMMdd_HHmmss") Copy-Item -LiteralPath $p -Destination $bak -Force [IO.File]::WriteAllText($p,$fixed,[Text.UTF8Encoding]::new($false)) $errs2=@() [void][System.Management.Automation.PSParser]::Tokenize((Get-Content -LiteralPath $p -Raw -Encoding UTF8),[ref]$errs2) if($errs2.Count -gt 0){ # quarantine $bad=$p+'.bad_'+(Get-Date -Format "yyyyMMdd_HHmmss") Rename-Item -LiteralPath $p -NewName (Split-Path -Leaf $bad) -Force Log ("[QUARANTINE] "+$p+" -> "+$bad+" (parse errors persistants: "+$errs2.Count+")") } else { Log ("[FIXED] "+$p) } } catch { Log ("[ERR] "+$p+" :: "+$_.Exception.Message) } } Write-Host ("Log -> "+$log)