diff --git a/cleanup-windows.bat b/cleanup-windows.bat index f83aea4..702728e 100644 --- a/cleanup-windows.bat +++ b/cleanup-windows.bat @@ -1,7 +1,7 @@ @echo off -REM ════════════════════════════════════════════════════════════════ -REM ARIA — Cleanup-Wrapper fuer Windows -REM ════════════════════════════════════════════════════════════════ +REM ================================================================ +REM ARIA - Cleanup-Wrapper fuer Windows +REM ================================================================ REM Ruft cleanup-windows.ps1 mit ExecutionPolicy Bypass auf. REM Funktioniert auch wenn Windows .ps1 direkt nicht startet. REM @@ -11,6 +11,6 @@ REM cleanup-windows.bat stefan -SkipPrune REM REM Doppelklick funktioniert NICHT (braucht Username als Param). REM Per Konsole aufrufen. -REM ════════════════════════════════════════════════════════════════ +REM ================================================================ powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%~dp0cleanup-windows.ps1" %* diff --git a/cleanup-windows.ps1 b/cleanup-windows.ps1 index 281c16c..d2b3f3c 100644 --- a/cleanup-windows.ps1 +++ b/cleanup-windows.ps1 @@ -1,6 +1,6 @@ -# ════════════════════════════════════════════════════════════════ -# ARIA — Windows / WSL2 / Docker Desktop VHDX Cleanup -# ════════════════════════════════════════════════════════════════ +# ================================================================ +# ARIA - Windows / WSL2 / Docker Desktop VHDX Cleanup +# ================================================================ # # Findet alle WSL2 + Docker Desktop ext4.vhdx Files unter # C:\Users\\AppData\Local\... und kompaktiert sie via diskpart. @@ -8,10 +8,11 @@ # Containern geloescht hast (z.B. nach `docker system prune`), # der aber von der VHDX bisher nicht freigegeben wurde. # -# Nutzung (PowerShell als ADMIN): +# Nutzung (PowerShell als ADMIN, oder via cleanup-windows.bat): # .\cleanup-windows.ps1 stefan # .\cleanup-windows.ps1 -User stefan # .\cleanup-windows.ps1 -User stefan -SkipPrune # nur compacten +# .\cleanup-windows.ps1 -User stefan -PruneOnly # nur prune # # Was passiert: # 1. Erst (optional): docker system prune + builder prune in WSL2 @@ -19,7 +20,11 @@ # 3. Alle gefundenen .vhdx Files mit diskpart compact vdisk shrinken # # Hinweis: diskpart braucht KEINE Hyper-V Tools (anders als Optimize-VHD). -# ════════════════════════════════════════════════════════════════ +# +# ASCII-only damit Windows-PowerShell 5.1 das File ohne BOM korrekt +# parsen kann (UTF-8-Sonderzeichen wuerden sonst als Windows-1252 +# fehlinterpretiert). +# ================================================================ [CmdletBinding()] param( @@ -27,27 +32,27 @@ param( HelpMessage="Dein Windows-Benutzername (z.B. stefan)")] [string]$User, - [Parameter(HelpMessage="Docker prune ueberspringen — nur compacten")] + [Parameter(HelpMessage="Docker prune ueberspringen - nur compacten")] [switch]$SkipPrune, [Parameter(HelpMessage="Docker prune NUR machen, dann beenden")] [switch]$PruneOnly ) -# Defensive: Process-Scope ExecutionPolicy auf Bypass — verhindert dass +# Defensive: Process-Scope ExecutionPolicy auf Bypass - verhindert dass # Untersaetze (z.B. Module) blockiert werden. Harmless wenn Parent schon # Bypass aufgerufen hat. try { Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass -Force | Out-Null } catch {} # Admin-Check + Self-Elevation -# Wenn nicht als Admin gestartet → einmal neu starten als Admin, mit +# Wenn nicht als Admin gestartet -> einmal neu starten als Admin, mit # ExecutionPolicy Bypass + den Original-Argumenten. User muss nur einmal # UAC-Prompt bestaetigen. $isAdmin = ([Security.Principal.WindowsPrincipal] ` [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole( [Security.Principal.WindowsBuiltInRole]::Administrator) if (-not $isAdmin) { - Write-Host "→ Starte neu als Administrator (mit ExecutionPolicy Bypass)..." -ForegroundColor Yellow + Write-Host "-> Starte neu als Administrator (mit ExecutionPolicy Bypass)..." -ForegroundColor Yellow $myPath = $MyInvocation.MyCommand.Path $forwardArgs = @("-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "`"$myPath`"") if ($User) { $forwardArgs += @("-User", $User) } @@ -56,8 +61,8 @@ if (-not $isAdmin) { try { Start-Process powershell.exe -Verb RunAs -ArgumentList $forwardArgs } catch { - Write-Host "❌ UAC-Elevation abgebrochen oder fehlgeschlagen." -ForegroundColor Red - Write-Host " Rechtsklick auf PowerShell → 'Als Administrator ausfuehren'" -ForegroundColor Yellow + Write-Host "[FAIL] UAC-Elevation abgebrochen oder fehlgeschlagen." -ForegroundColor Red + Write-Host " Rechtsklick auf PowerShell -> 'Als Administrator ausfuehren'" -ForegroundColor Yellow exit 1 } exit 0 @@ -65,17 +70,17 @@ if (-not $isAdmin) { $basePath = "C:\Users\$User\AppData\Local" if (-not (Test-Path $basePath)) { - Write-Host "❌ Pfad existiert nicht: $basePath" -ForegroundColor Red - Write-Host " Pruefe den Benutzernamen." -ForegroundColor Yellow + Write-Host "[FAIL] Pfad existiert nicht: $basePath" -ForegroundColor Red + Write-Host " Pruefe den Benutzernamen." -ForegroundColor Yellow exit 1 } -Write-Host "════════════════════════════════════════════════════════════" -ForegroundColor Cyan +Write-Host "================================================================" -ForegroundColor Cyan Write-Host " ARIA Cleanup fuer User: $User" -ForegroundColor Cyan -Write-Host "════════════════════════════════════════════════════════════" -ForegroundColor Cyan +Write-Host "================================================================" -ForegroundColor Cyan Write-Host "" -# ── 1. Docker prune (in WSL2) ────────────────────────────────── +# -- 1. Docker prune (in WSL2) ----------------------------------- if (-not $SkipPrune) { Write-Host "[1/3] Docker Cleanup in WSL2..." -ForegroundColor Yellow Write-Host " docker system prune -a --volumes -f" -ForegroundColor Gray @@ -83,26 +88,26 @@ if (-not $SkipPrune) { Write-Host "" try { wsl -e bash -c "docker system prune -a --volumes -f && docker builder prune -a -f" - Write-Host " ✅ fertig" -ForegroundColor Green + Write-Host " [OK] fertig" -ForegroundColor Green } catch { - Write-Host " ⚠️ Docker prune fehlgeschlagen (vielleicht laeuft Docker Desktop nicht?)" -ForegroundColor Yellow - Write-Host " $_" -ForegroundColor Gray + Write-Host " [WARN] Docker prune fehlgeschlagen (vielleicht laeuft Docker Desktop nicht?)" -ForegroundColor Yellow + Write-Host " $_" -ForegroundColor Gray } Write-Host "" if ($PruneOnly) { - Write-Host "─PruneOnly gesetzt — fertig." -ForegroundColor Cyan + Write-Host "PruneOnly gesetzt - fertig." -ForegroundColor Cyan exit 0 } } -# ── 2. WSL2 shutdown ────────────────────────────────────────── +# -- 2. WSL2 shutdown -------------------------------------------- Write-Host "[2/3] WSL2 herunterfahren..." -ForegroundColor Yellow wsl --shutdown Start-Sleep -Seconds 3 -Write-Host " ✅ fertig" -ForegroundColor Green +Write-Host " [OK] fertig" -ForegroundColor Green Write-Host "" -# ── 3. VHDX-Files finden + compacten ────────────────────────── +# -- 3. VHDX-Files finden + compacten ---------------------------- Write-Host "[3/3] VHDX-Files suchen + compacten..." -ForegroundColor Yellow Write-Host "" @@ -126,7 +131,7 @@ Write-Host "" $totalBefore = ($vhdxFiles | Measure-Object Length -Sum).Sum foreach ($f in $vhdxFiles) { - Write-Host "→ Compact: $($f.FullName)" -ForegroundColor White + Write-Host "-> Compact: $($f.FullName)" -ForegroundColor White $sizeBefore = [math]::Round($f.Length / 1GB, 2) # Temporaeres diskpart-Script schreiben @@ -141,26 +146,26 @@ exit try { $output = & diskpart /s $tmp 2>&1 - # Datei neu lesen — Length ist gecacht + # Datei neu lesen - Length ist gecacht $newFile = Get-Item $f.FullName $sizeAfter = [math]::Round($newFile.Length / 1GB, 2) $saved = [math]::Round($sizeBefore - $sizeAfter, 2) if ($saved -gt 0) { - Write-Host (" ✅ {0} GB → {1} GB (gespart: {2} GB)" -f $sizeBefore, $sizeAfter, $saved) -ForegroundColor Green + Write-Host (" [OK] {0} GB -> {1} GB (gespart: {2} GB)" -f $sizeBefore, $sizeAfter, $saved) -ForegroundColor Green } else { - Write-Host (" ─ {0} GB → {1} GB (nichts zu holen — File war schon optimal)" -f $sizeBefore, $sizeAfter) -ForegroundColor DarkGray + Write-Host (" -- {0} GB -> {1} GB (nichts zu holen - File war schon optimal)" -f $sizeBefore, $sizeAfter) -ForegroundColor DarkGray } } catch { - Write-Host " ❌ Fehler: $_" -ForegroundColor Red - Write-Host " diskpart-Output:" -ForegroundColor DarkGray - $output | ForEach-Object { Write-Host " $_" -ForegroundColor DarkGray } + Write-Host " [FAIL] Fehler: $_" -ForegroundColor Red + Write-Host " diskpart-Output:" -ForegroundColor DarkGray + $output | ForEach-Object { Write-Host " $_" -ForegroundColor DarkGray } } finally { Remove-Item $tmp -ErrorAction SilentlyContinue } Write-Host "" } -# ── Zusammenfassung ───────────────────────────────────────── +# -- Zusammenfassung --------------------------------------------- $vhdxFilesAfter = @() $vhdxFilesAfter += Get-ChildItem -Path "$basePath\Docker" -Recurse -Filter "*.vhdx" -ErrorAction SilentlyContinue $vhdxFilesAfter += Get-ChildItem -Path "$basePath\Packages" -Recurse -Filter "ext4.vhdx" -ErrorAction SilentlyContinue @@ -169,11 +174,11 @@ $totalAfter = ($vhdxFilesAfter | Measure-Object Length -Sum).Sum $savedTotal = [math]::Round(($totalBefore - $totalAfter) / 1GB, 2) -Write-Host "════════════════════════════════════════════════════════════" -ForegroundColor Cyan -Write-Host (" Gesamt: {0} GB → {1} GB (gespart: {2} GB)" -f ` +Write-Host "================================================================" -ForegroundColor Cyan +Write-Host (" Gesamt: {0} GB -> {1} GB (gespart: {2} GB)" -f ` [math]::Round($totalBefore / 1GB, 2), [math]::Round($totalAfter / 1GB, 2), $savedTotal) -ForegroundColor Cyan -Write-Host "════════════════════════════════════════════════════════════" -ForegroundColor Cyan +Write-Host "================================================================" -ForegroundColor Cyan Write-Host "" Write-Host "Fertig. Docker Desktop / WSL2 starten ja von alleine wieder beim naechsten Aufruf." -ForegroundColor Green