# kb_inbox_sweep_v1.0.ps1 - D?place les AUTO_*.txt de updates\inbox\kb vers updates\archive\kb\YYYY\MM # PS 5.1-safe, UTF-8 sans BOM, CRLF, non interactif par d?faut (Preview) ; utiliser -Move pour appliquer. param( [Parameter(Mandatory=$true)][string]$Root, [switch]$Move, [switch]$NoPrompt ) try{ [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding($false) }catch{} function Exists([string]$p){ return (-not [string]::IsNullOrWhiteSpace($p)) -and (Test-Path -LiteralPath $p) } function Sha256([string]$p){ try{ return (Get-FileHash -LiteralPath $p -Algorithm SHA256).Hash.ToUpperInvariant() }catch{ return '' } } $inbox = Join-Path $Root 'updates\inbox\kb' $archR = Join-Path $Root 'updates\archive\kb' if(-not (Exists $inbox)){ Write-Host ("[INFO] inbox introuvable: {0}" -f $inbox); exit 0 } $files = Get-ChildItem -LiteralPath $inbox -Filter 'AUTO_*.txt' -ErrorAction SilentlyContinue $count = @($files).Count Write-Host ("== KB INBOX SWEEP v1.0 == Inbox={0} Count={1}" -f $inbox,$count) if($count -eq 0){ Write-Host "[INFO] Rien a deplacer."; exit 0 } $plan = @() foreach($f in $files){ $sha = Sha256 $f.FullName $y = (Get-Date).ToString('yyyy'); $m=(Get-Date).ToString('MM') $destDir = Join-Path (Join-Path $archR $y) $m $nameNoExt = [IO.Path]::GetFileNameWithoutExtension($f.Name) $destName = ("{0}__sha_{1}.txt" -f $nameNoExt, ($sha.Substring(0,8))) $destPath = Join-Path $destDir $destName $plan += [pscustomobject]@{ Src=$f.FullName; Dest=$destPath; Sha=$sha; Size=$f.Length } } # Preview foreach($p in $plan){ Write-Host ("MOVE -> {0} -> {1} (sha={2} size={3})" -f $p.Src,$p.Dest,$p.Sha,$p.Size) } if(-not $Move){ Write-Host "[PREVIEW] Utilise -Move pour appliquer." exit 0 } if(-not $NoPrompt){ $resp = Read-Host "Confirmer le deplacement ? (O/N)" if($resp -notmatch '^[OoYy]'){ Write-Host "[ABORT] no move."; exit 0 } } # Apply foreach($p in $plan){ $d = [IO.Path]::GetDirectoryName($p.Dest) if(-not (Test-Path -LiteralPath $d)){ New-Item -ItemType Directory -Force -Path $d | Out-Null } # Eviter collision $dest = $p.Dest $idx = 1 while(Test-Path -LiteralPath $dest){ $dest = $p.Dest.Replace('.txt', ("_{0}.txt" -f $idx)) $idx++ } try{ Move-Item -LiteralPath $p.Src -Destination $dest -Force Write-Host ("[OK] {0} -> {1}" -f $p.Src,$dest) }catch{ Write-Host ("[ERR] move failed: {0} -> {1} : {2}" -f $p.Src,$dest,$_.Exception.Message) exit 3 } } # Log try{ $logDir = $archR if(-not (Test-Path -LiteralPath $logDir)){ New-Item -ItemType Directory -Force -Path $logDir | Out-Null } $log = Join-Path $logDir 'inbox_sweep_log.txt' $lines = @() $ts = [DateTime]::Now.ToString('s') foreach($p in $plan){ $lines += ("{0} MOVE {1} -> {2} sha={3} size={4}" -f $ts,$p.Src,$p.Dest,$p.Sha,$p.Size) } $enc = New-Object System.Text.UTF8Encoding($false) $content = ($lines -join "`r`n") + "`r`n" [IO.File]::AppendAllText($log,$content,$enc) }catch{} Write-Host "[DONE] inbox sweep." exit 0