From 103afcac1d5abe6f56a622dbf09d3845ccc2e977 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mustafa=20=C3=96ZKAYA?= Date: Sat, 11 Apr 2026 13:25:01 +0300 Subject: [PATCH] =?UTF-8?q?Dosyalar=C4=B1=20"/"=20dizinine=20y=C3=BCkle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 265 ++++++++++++++++++++++++++++++++++++++++++ docker-cleanup.bat | 68 +++++++++++ docker-cleanup.ps1 | 278 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 611 insertions(+) create mode 100644 README.md create mode 100644 docker-cleanup.bat create mode 100644 docker-cleanup.ps1 diff --git a/README.md b/README.md new file mode 100644 index 0000000..77a7f1e --- /dev/null +++ b/README.md @@ -0,0 +1,265 @@ +# Docker Desktop Temizlik & Bakım Aracı + +Windows üzerinde Docker Desktop kullananlar için geliştirilmiş, **tek tıkla çalışan** kapsamlı bir temizlik ve disk kazanım aracıdır. Docker kaynaklarını temizlemenin yanı sıra WSL2 backend'inin kullandığı `.vhdx` sanal disk dosyalarını da sıkıştırarak Windows'a disk alanı iade eder. + +--- + +## Dosya Yapısı + +``` +docker-cleanup/ +├── docker-cleanup.bat ← Çift tıkla başlatıcı (buradan başlayın) +└── docker-cleanup.ps1 ← Ana temizlik scripti (PowerShell) +``` + +İki dosyanın **aynı klasörde** bulunması zorunludur. + +--- + +## Gereksinimler + +| Gereksinim | Açıklama | +|---|---| +| Windows 10/11 | WSL2 destekli | +| Docker Desktop | WSL2 backend aktif | +| PowerShell 5.1+ | Windows ile birlikte gelir | +| Yönetici yetkisi | Yalnızca VHDX shrink adımı için gerekli | + +> Docker temizlik adımları (1-5) normal kullanıcı yetkisiyle çalışır. +> VHDX shrink (adım 6) için Yönetici yetkisi şarttır. + +--- + +## Hızlı Başlangıç + +### Yöntem 1 — Çift Tıkla (Önerilen) + +`docker-cleanup.bat` dosyasına **sağ tıklayın** → **"Yönetici olarak çalıştır"** seçin. + +Açılan menüden istediğiniz modu seçin: + +``` +==================================================== + Docker Desktop - Temizlik, Bakim ve VHDX Shrink +==================================================== + Yetki : YONETICI - VHDX shrink AKTIF +==================================================== + + [1] Standart temizlik + VHDX shrink (7 gunluk filtre) + [2] Hizli temizlik + VHDX shrink (2 gunluk filtre) + [3] Volume dahil tam temizlik (DIKKATLI!) + [4] Sadece goster - dry-run (hicbir sey silinmez) + [5] Cikis +``` + +### Yöntem 2 — PowerShell'den Doğrudan + +```powershell +# Dosyayı önce güven listesine alın (bir kez yeterli) +Unblock-File .\docker-cleanup.ps1 + +# Standart çalıştırma +.\docker-cleanup.ps1 + +# Yönetici PowerShell'inde (VHDX shrink dahil) +.\docker-cleanup.ps1 -Hours 168 +``` + +--- + +## Parametreler + +| Parametre | Tür | Varsayılan | Açıklama | +|---|---|---|---| +| `-Hours` | `int` | `168` | Bu saatten eski kaynakları temizle (168 = 7 gün) | +| `-All` | `switch` | kapalı | Volume temizliğini de dahil et | +| `-DryRun` | `switch` | kapalı | Hiçbir şeyi silme, sadece raporu göster | + +### Parametre Örnekleri + +```powershell +# Son 2 günden eski kaynakları temizle +.\docker-cleanup.ps1 -Hours 48 + +# Volume dahil tam temizlik +.\docker-cleanup.ps1 -All + +# Ne kadar alan kazanılacağını önce gör, hiçbir şeyi silme +.\docker-cleanup.ps1 -DryRun + +# Volume dahil, 3 günlük filtre, dry-run +.\docker-cleanup.ps1 -All -Hours 72 -DryRun +``` + +--- + +## Çalışma Akışı (8 Adım) + +Script çalıştırıldığında aşağıdaki adımları sırayla uygular. + +### Adım 0 — Başlangıç Raporu + +Script başlamadan önce mevcut durumu gösterir: + +- `docker system df` çıktısı (konteyner, imaj, volume, cache boyutları) +- `%LOCALAPPDATA%\Docker\wsl\disk\` altındaki tüm `.vhdx` dosyaları ve boyutları + +### Adım 1 — Konteyner Temizliği + +`exited`, `dead` ve hiç başlatılmamış `created` durumundaki konteynerleri bulur ve kaldırır. `-Hours` filtresine göre yalnızca belirtilen süreden eski olanlar silinir. Çalışan (`running`) konteynerlere dokunulmaz. + +``` +docker container prune --force --filter "until=168h" +``` + +### Adım 2 — İmaj Temizliği + +Hiçbir konteynere bağlı olmayan imajları kaldırır. Hem `dangling` (tag'siz) hem de kullanılmayan tüm imajlar hedeflenir. + +``` +docker image prune -a --force --filter "until=168h" +``` + +> Aktif konteynerlerin kullandığı imajlar korunur. + +### Adım 3 — Build Cache Temizliği + +`docker build` işlemlerinden kalan katman önbelleklerini temizler. Zamanla GB'larca yer kaplayabilir. + +``` +docker builder prune --force --filter "until=168h" +``` + +### Adım 4 — Ağ Temizliği + +Hiçbir konteynere bağlı olmayan özel Docker ağlarını kaldırır. `bridge`, `host` ve `none` gibi yerleşik ağlar korunur. + +``` +docker network prune --force +``` + +### Adım 5 — Volume Temizliği *(opsiyonel, `-All` ile aktif)* + +Yalnızca `-All` parametresiyle çalışır. Herhangi bir konteynere bağlı olmayan volume'ları kaldırır. Çalıştırmadan önce onay ister. + +``` +docker volume prune --force +``` + +> **Uyarı:** Volume'lar veritabanı verileri, yapılandırma dosyaları gibi kalıcı içerik barındırabilir. Bu adımı kullanmadan önce yedek alın. + +### Adım 6 — WSL2 Kapatma + VHDX Shrink *(Yönetici yetkisi gerekir)* + +Bu adım Docker'ın WSL2 backend'inin kullandığı sanal disk dosyalarını (`ext4.vhdx`, `data.vhdx` vb.) sıkıştırarak Windows'a fiziksel disk alanı iade eder. + +**Neden gerekli?** + +`docker system prune` Docker içindeki verileri siler ama `.vhdx` dosyası Windows gözünden küçülmez. VHDX dinamik olarak büyür, ancak içi boşalsa bile Windows'a otomatik yer iade etmez. Bu adım bu sorunu çözer. + +**İşlem sırası:** + +``` +1. wsl --shutdown ← WSL2 ve tüm distro'ları kapat +2. diskpart + select vdisk file="...\ext4.vhdx" + attach vdisk readonly + compact vdisk ← Boş blokları geri ver + detach vdisk +3. Docker Desktop'ı yeniden başlat +``` + +Script her `.vhdx` dosyası için önce/sonra boyutu karşılaştırır ve kazanılan alanı raporlar. + +### Adım 7 — Sonuç Raporu + +Tüm adımlar tamamlandıktan sonra: + +- `docker system df` ile güncel Docker disk kullanımı +- Her `.vhdx` dosyasının yeni boyutu + +--- + +## VHDX Dosyaları Hakkında + +Docker Desktop WSL2 backend kullandığında verilerini şu konumda saklar: + +``` +%LOCALAPPDATA%\Docker\wsl\disk\ + ext4.vhdx ← Ana Docker verisi (imaj katmanları, konteynerler) + docker-desktop-data.vhdx ← Ek veri (yapılandırmaya göre değişir) +``` + +Bu dosyalar büyüdükçe Windows'ta ciddi disk baskısı oluşturur. Docker temizliği + VHDX shrink kombinasyonu uygulandığında **5 GB ile 30 GB arasında** alan kazanımı görülmesi normaldir. + +--- + +## Güvenlik Notları + +### ExecutionPolicy Uyarısı + +Script ilk çalıştırmada PowerShell güvenlik uyarısı gösterebilir. Bunu kalıcı olarak çözmek için: + +```powershell +Unblock-File .\docker-cleanup.ps1 +``` + +`.bat` üzerinden çalıştırıldığında bu adım otomatik olarak atlanır (`-ExecutionPolicy Bypass`). + +### Neye Dokunulmaz + +Script **asla** şunlara dokunmaz: + +- Çalışan (`running`) konteynerler +- Aktif konteynerlerin kullandığı imajlar +- `bridge`, `host`, `none` gibi yerleşik Docker ağları +- `-All` parametresi verilmediği sürece volume'lar +- Docker Desktop yapılandırma dosyaları +- WSL2 distro verileri (yalnızca Docker'ın kendi `.vhdx` dosyaları hedeflenir) + +### Dry-Run Modu + +Emin olmadığınızda her zaman önce dry-run ile başlayın: + +```powershell +.\docker-cleanup.ps1 -DryRun +``` + +Hiçbir silme işlemi yapılmaz; yalnızca ne yapılacağı ekrana yazdırılır. + +--- + +## Sık Karşılaşılan Durumlar + +**Docker Desktop çalışmıyor hatası** + +Script başlangıçta `docker info` komutuyla Docker'ın erişilebilir olup olmadığını kontrol eder. Docker Desktop kapalıysa hata mesajı gösterir ve çıkar. Çözüm: Docker Desktop'ı açın ve birkaç saniye bekleyip tekrar çalıştırın. + +**VHDX shrink adımı atlanıyor** + +Script yönetici yetkisiyle çalışmıyorsa adım 6 otomatik olarak atlanır ve uyarı verilir. Çözüm: `.bat` dosyasına sağ tıklayın → "Yönetici olarak çalıştır". + +**VHDX boyutu değişmedi** + +Dosya zaten optimize durumdaysa `diskpart compact` herhangi bir alan kazanımı sağlamaz ve script bunu raporlar. Bu normal bir durumdur. + +**Volume temizliği sonrası uygulama hatası** + +`-All` ile volume silindikten sonra bazı uygulamalar başlatılamayabilir. Çözüm: İlgili volume'ları yedekleyin veya uygulamayı yeniden yapılandırın. + +--- + +## Önerilen Kullanım Sıklığı + +| Senaryo | Komut | Sıklık | +|---|---|---| +| Günlük geliştirme | Standart (seçenek 1) | Haftada 1 | +| Yoğun build dönemi | `-Hours 48` (seçenek 2) | Günlük | +| Disk dolmak üzere | `-All` (seçenek 3) | Gerektiğinde | +| Yeni başlarken | `-DryRun` (seçenek 4) | İlk kullanımda | + +--- + +## Lisans + +Bu araç [hAtayolu](https://github.com/hatayolu) projesi kapsamında geliştirilmiştir. +Kişisel ve ticari kullanıma serbesttir. diff --git a/docker-cleanup.bat b/docker-cleanup.bat new file mode 100644 index 0000000..09f882e --- /dev/null +++ b/docker-cleanup.bat @@ -0,0 +1,68 @@ +@echo off +:: ============================================================ +:: Docker Desktop - Temizlik, Bakim ve VHDX Shrink Baslatici +:: Bu dosyayla ayni klasorde docker-cleanup.ps1 olmali. +:: VHDX shrink icin "Yonetici olarak calistir" gerekir. +:: ============================================================ +title Docker Temizlik ve Bakim + +:: Yonetici yetkisi kontrolu +net session >nul 2>&1 +if %errorLevel% == 0 ( + set ADMIN_MSG=YONETICI - VHDX shrink AKTIF +) else ( + set ADMIN_MSG=Normal kullanici - VHDX shrink ATLANACAK +) + +cls +echo. +echo ==================================================== +echo Docker Desktop - Temizlik, Bakim ve VHDX Shrink +echo ==================================================== +echo Yetki : %ADMIN_MSG% +echo ==================================================== +echo. +echo [1] Standart temizlik + VHDX shrink (7 gunluk filtre) +echo [2] Hizli temizlik + VHDX shrink (2 gunluk filtre) +echo [3] Volume dahil tam temizlik (DIKKATLI!) +echo [4] Sadece goster - dry-run (hicbir sey silinmez) +echo [5] Cikis +echo. +echo NOT: VHDX shrink icin bu .bat dosyasina sag tiklayip +echo "Yonetici olarak calistir" secmelisiniz. +echo. +set /p secim=" Seciminiz (1-5): " + +if "%secim%"=="1" goto STANDART +if "%secim%"=="2" goto HIZLI +if "%secim%"=="3" goto FULL +if "%secim%"=="4" goto DRYRUN +if "%secim%"=="5" goto CIKIS + +echo Gecersiz secim. +pause +goto :eof + +:STANDART +powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%~dp0docker-cleanup.ps1" -Hours 168 +goto CIKIS + +:HIZLI +powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%~dp0docker-cleanup.ps1" -Hours 48 +goto CIKIS + +:FULL +echo. +echo !! UYARI: Volume temizligi ve VHDX shrink yapilacak! +set /p onay=" Emin misiniz? (E/H): " +if /i "%onay%"=="E" ( + powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%~dp0docker-cleanup.ps1" -All -Hours 168 +) +goto CIKIS + +:DRYRUN +powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%~dp0docker-cleanup.ps1" -DryRun +goto CIKIS + +:CIKIS +exit /b 0 diff --git a/docker-cleanup.ps1 b/docker-cleanup.ps1 new file mode 100644 index 0000000..07b988d --- /dev/null +++ b/docker-cleanup.ps1 @@ -0,0 +1,278 @@ +# ============================================================ +# Docker Desktop (Windows + WSL2) -- Temizlik, Bakim & VHDX Shrink +# Calistirma : Yonetici olarak PowerShell'de: +# .\docker-cleanup.ps1 +# .\docker-cleanup.ps1 -All (volume dahil) +# .\docker-cleanup.ps1 -DryRun (sadece goster) +# .\docker-cleanup.ps1 -Hours 48 (filtre saati) +# NOT: VHDX shrink icin Yonetici (Administrator) yetkisi gerekir. +# ============================================================ + +param( + [switch]$All, + [switch]$DryRun, + [int]$Hours = 168 +) + +# ============================================================ +# YARDIMCI FONKSIYONLAR +# ============================================================ +function Hr { Write-Host ("-" * 56) -ForegroundColor DarkGray } +function Hr2 { Write-Host ("=" * 56) -ForegroundColor DarkGray } +function Step { param($n,$t) Write-Host "`n [$n] $t" -ForegroundColor Cyan } +function Info { param($t) Write-Host " -> $t" -ForegroundColor Yellow } +function Ok { param($t) Write-Host " OK $t" -ForegroundColor Green } +function Warn { param($t) Write-Host " !! $t" -ForegroundColor Red } +function Skip { param($t) Write-Host " -- $t" -ForegroundColor DarkGray } +function Blank { Write-Host "" } + +function Format-Bytes { + param([long]$bytes) + if ($bytes -ge 1GB) { return "{0:N2} GB" -f ($bytes / 1GB) } + if ($bytes -ge 1MB) { return "{0:N2} MB" -f ($bytes / 1MB) } + return "{0:N0} KB" -f ($bytes / 1KB) +} + +function Run-Docker { + param([string]$Cmd) + if ($DryRun) { + Write-Host " [dry-run] docker $Cmd" -ForegroundColor DarkGray + } else { + $result = Invoke-Expression "docker $Cmd" 2>&1 + $result | ForEach-Object { Write-Host " $_" -ForegroundColor Gray } + } +} + +function Count-Lines { + param([string]$Cmd) + $out = Invoke-Expression $Cmd 2>$null + if (-not $out) { return 0 } + return ($out | Where-Object { $_ -ne "" }).Count +} + +# ============================================================ +# ON KONTROLLER +# ============================================================ + +# Yonetici yetkisi var mi? +$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole( + [Security.Principal.WindowsBuiltInRole]::Administrator +) + +# Docker calisiyor mu? +$dockerOk = $false +try { + docker info 2>&1 | Out-Null + $dockerOk = $true +} catch {} + +# ============================================================ +# BASLIK +# ============================================================ +Clear-Host +Hr2 +Write-Host " Docker Desktop - Tam Temizlik, Bakim & VHDX Shrink" -ForegroundColor White -BackgroundColor DarkBlue +Write-Host " Tarih : $(Get-Date -Format 'dd.MM.yyyy HH:mm')" -ForegroundColor Gray +Write-Host " Filtre : Son $Hours saat" -ForegroundColor Gray +Write-Host " Yonetici : $(if ($isAdmin) { 'EVET (VHDX shrink aktif)' } else { 'HAYIR (VHDX shrink atlanacak)' })" -ForegroundColor $(if ($isAdmin) { 'Green' } else { 'Red' }) +if ($DryRun) { Write-Host " MOD : DRY-RUN (hicbir sey degistirilmeyecek)" -ForegroundColor Yellow } +if ($All) { Write-Host " EKSTRA : Volume temizligi aktif" -ForegroundColor Red } +Hr2 + +if (-not $dockerOk) { + Warn "Docker Desktop calisiyor degil veya erisim yok." + Warn "Lutfen Docker Desktop'i acin ve tekrar calistirin." + Blank + Read-Host " Cikis icin Enter" + exit 1 +} + +if (-not $isAdmin) { + Blank + Warn "VHDX shrink icin bu scripti Yonetici olarak calistirin:" + Info "PowerShell'e sag tiklayin -> 'Yonetici olarak calistir'" + Info "Devam edilecek ama VHDX shrink adimi atlanacak..." + Blank +} + +# ============================================================ +# ADIM 0 -- Baslangic disk durumu +# ============================================================ +Step "0" "Baslangic disk kullanimi (Docker)" +docker system df + +# VHDX boyutlari +$vhdxDir = "$env:LOCALAPPDATA\Docker\wsl\disk" +$vhdxFiles = @() +if (Test-Path $vhdxDir) { + $vhdxFiles = Get-ChildItem -Path $vhdxDir -Filter "*.vhdx" -ErrorAction SilentlyContinue + if ($vhdxFiles.Count -gt 0) { + Blank + Info "VHDX dosyalari ($vhdxDir):" + foreach ($f in $vhdxFiles) { + Info (" {0,-35} {1}" -f $f.Name, (Format-Bytes $f.Length)) + } + } +} +Hr + +# ============================================================ +# ADIM 1 -- Konteyner temizligi +# ============================================================ +Step "1" "Durdurulmus konteynerler temizleniyor" + +$stoppedCount = Count-Lines "docker ps -aq --filter status=exited" +$deadCount = Count-Lines "docker ps -aq --filter status=dead" +$createdCount = Count-Lines "docker ps -aq --filter status=created" +$total = $stoppedCount + $deadCount + $createdCount + +Info "Exited : $stoppedCount | Dead : $deadCount | Created : $createdCount | Toplam : $total" + +if ($total -gt 0) { + Run-Docker "container prune --force --filter `"until=${Hours}h`"" + Ok "Konteyner temizligi tamamlandi" +} else { + Ok "Temizlenecek konteyner yok" +} + +# ============================================================ +# ADIM 2 -- Imaj temizligi +# ============================================================ +Step "2" "Kullanilmayan imajlar temizleniyor" +$danglingCount = Count-Lines "docker images -f dangling=true -q" +Info "Dangling imaj: $danglingCount adet" +Run-Docker "image prune -a --force --filter `"until=${Hours}h`"" +Ok "Imaj temizligi tamamlandi" + +# ============================================================ +# ADIM 3 -- Build cache +# ============================================================ +Step "3" "Build cache temizleniyor" +$dfOut = docker system df 2>$null +$cacheLine = $dfOut | Select-String "Build Cache" +Info "Mevcut cache: $cacheLine" +Run-Docker "builder prune --force --filter `"until=${Hours}h`"" +Ok "Build cache temizlendi" + +# ============================================================ +# ADIM 4 -- Ag temizligi +# ============================================================ +Step "4" "Kullanilmayan Docker aglari temizleniyor" +Run-Docker "network prune --force" +Ok "Ag temizligi tamamlandi" + +# ============================================================ +# ADIM 5 -- Volume temizligi (opsiyonel) +# ============================================================ +Step "5" "Volume temizligi" +if ($All) { + Warn "DIKKAT: Kalici veri iceren volume'lar silinebilir!" + $confirm = Read-Host " Devam? (E/H)" + if ($confirm -match "^[Ee]$") { + $volCount = Count-Lines "docker volume ls -f dangling=true -q" + Info "Baglantisiz volume: $volCount adet" + if ($volCount -gt 0) { + Run-Docker "volume prune --force" + Ok "Volume temizligi tamamlandi" + } else { + Ok "Temizlenecek volume yok" + } + } else { + Skip "Volume temizligi kullanici tarafindan atlandi" + } +} else { + Skip "Atlandi. Dahil etmek icin: -All parametresi" +} + +# ============================================================ +# ADIM 6 -- WSL2 kapat + VHDX Shrink +# ============================================================ +Step "6" "WSL2 kapatiliyor + VHDX shrink yapiliyor" + +if (-not $isAdmin) { + Warn "Yonetici yetkisi yok -- VHDX shrink atlaniyor." + Warn "Scripti 'Yonetici olarak calistir' ile tekrar deneyin." +} elseif ($vhdxFiles.Count -eq 0) { + Skip "VHDX dosyasi bulunamadi: $vhdxDir" +} else { + Info "WSL2 durduruluyor (wsl --shutdown)..." + if (-not $DryRun) { + wsl --shutdown + Start-Sleep -Seconds 3 + Ok "WSL2 durduruldu" + } else { + Skip "[dry-run] wsl --shutdown" + } + + foreach ($vhdx in $vhdxFiles) { + $sizeBefore = $vhdx.Length + Info ("Shrink basliyor: {0} ({1})" -f $vhdx.Name, (Format-Bytes $sizeBefore)) + + if (-not $DryRun) { + $diskpartScript = @" +select vdisk file="$($vhdx.FullName)" +attach vdisk readonly +compact vdisk +detach vdisk +exit +"@ + $tmpScript = "$env:TEMP\docker_shrink_$($vhdx.BaseName).txt" + $diskpartScript | Out-File -FilePath $tmpScript -Encoding ascii + + $proc = Start-Process -FilePath "diskpart.exe" ` + -ArgumentList "/s `"$tmpScript`"" ` + -Wait -PassThru -NoNewWindow ` + -RedirectStandardOutput "$env:TEMP\diskpart_out.txt" ` + -RedirectStandardError "$env:TEMP\diskpart_err.txt" + + Remove-Item $tmpScript -ErrorAction SilentlyContinue + + # Boyut degisimini goster + $vhdx.Refresh() + $sizeAfter = $vhdx.Length + $saved = $sizeBefore - $sizeAfter + + if ($saved -gt 0) { + Ok (" {0}: {1} -> {2} (kazanilan: {3})" -f ` + $vhdx.Name, ` + (Format-Bytes $sizeBefore), ` + (Format-Bytes $sizeAfter), ` + (Format-Bytes $saved)) + } else { + Ok (" {0}: Boyut degismedi (zaten optimize)" -f $vhdx.Name) + } + } else { + Skip ("[dry-run] diskpart compact: {0}" -f $vhdx.Name) + } + } + + if (-not $DryRun) { + Info "Docker Desktop yeniden baslatiliyor..." + Start-Process "C:\Program Files\Docker\Docker\Docker Desktop.exe" -ErrorAction SilentlyContinue + Ok "Docker Desktop baslatildi" + } +} + +# ============================================================ +# ADIM 7 -- Sonuc raporu +# ============================================================ +Hr +Step "7" "Sonuc ozeti" +docker system df + +if ($vhdxFiles.Count -gt 0 -and $isAdmin -and -not $DryRun) { + Blank + Info "VHDX guncel boyutlar:" + foreach ($f in $vhdxFiles) { + $f.Refresh() + Info (" {0,-35} {1}" -f $f.Name, (Format-Bytes $f.Length)) + } +} + +Hr2 +Blank +Write-Host " Temizlik ve bakim tamamlandi!" -ForegroundColor Green +if ($DryRun) { Warn "(Dry-run moduydu -- hicbir degisiklik yapilmadi)" } +Blank +Hr2 +Read-Host " Cikis icin Enter"