一鍵搞定!自動化壓縮 WSL2 虛擬磁碟,釋放大量硬碟空間
2025-07-06 09:27:45 系統工具

你的 C 槽空間是不是越來越小,檢查後發現一個名為 ext4.vhdx
的檔案佔據了幾十甚至上百 GB?如果你是 Windows Subsystem for Linux (WSL2) 的使用者,這絕對是你我共同的痛點。
WSL2 的虛擬磁碟檔案 ext4.vhdx
有個特性:它會隨著你使用而動態增長,但當你刪除 WSL 內的檔案後,它不會自動縮小。這導致磁碟空間被「名存實亡」的檔案佔據,日積月累下非常可觀。
傳統的解決方法非常繁瑣:
- 手動用管理員權限打開 PowerShell。
- 執行
wsl --shutdown
。 - 想辦法找到那個藏在
AppData
深處、路徑超長的ext4.vhdx
檔案。 - 執行磁碟優化指令。
- 再手動啟動 WSL。
這一連串操作既麻煩又容易出錯。今天,我們就用一個終極 PowerShell 腳本,將這一切流程自動化,真正實現「一鍵瘦身」!
這個腳本有多厲害?
這個腳本整合了我們在解決問題過程中遇到的所有智慧,它能做到:
- 自動關閉與重啟 WSL:你不需要手動執行任何
wsl
指令,腳本會處理好開頭和結尾。 - 智慧尋找 VHDX 路徑:無論你的 WSL 是從 Microsoft Store 安裝,還是手動匯入的,腳本都能透過查詢登錄檔找到它的準確位置,你再也不用去複製那超長的路徑了。
- 兼容 Windows 家用版與專業版:腳本會自動偵測你的 Windows 版本。如果你是專業版,它會使用
Optimize-Vhd
指令;如果你是家用版,它會自動切換到內建的diskpart
工具來完成壓縮,適用性極高! - 清晰回報成果:在執行壓縮前後,腳本會顯示檔案大小,並在最後計算出總共幫你節省了多少硬碟空間,讓你對成果一目了然。
如何使用?
整個過程只需要三個簡單的步驟。
步驟一:建立腳本檔案
首先,在你的電腦上任何你方便的地方,建立一個新的文字檔案,將它命名為 Optimize-WSL.ps1
。然後,將下方的完整程式碼複製並貼到這個檔案中。
# ===================================================================
# 腳本:自動化 WSL2 虛擬磁碟 (VHDX) 壓縮優化與重啟工具
# 注意:請務必以「系統管理員」權限執行此腳本
# ===================================================================
# --- 步驟 1: 設定您要優化的 WSL 發行版名稱 ---
$distroName = "Ubuntu-24.04"
# ==================== 腳本主體,通常無需修改以下內容 ====================
$vhdxPath = $null
# --- 步驟 2: 自動在登錄檔中尋找 VHDX 檔案路徑 ---
Write-Host "步驟 2/8: 正在登錄檔中尋找 '$distroName' 的設定..." -ForegroundColor Yellow
try {
$lxssPath = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Lxss"
$distroKeys = Get-ChildItem -Path $lxssPath
foreach ($distroKey in $distroKeys) {
$properties = Get-ItemProperty -Path $distroKey.PSPath
if ($properties.DistributionName -eq $distroName) {
$basePath = $properties.BasePath
$vhdxPath = Join-Path $basePath "ext4.vhdx"
break
}
}
} catch {
Write-Host "錯誤:查詢登錄檔時發生意外錯誤: $($_.Exception.Message)" -ForegroundColor Red
Read-Host "按 Enter 鍵結束..."; exit
}
# --- 步驟 3: 驗證 VHDX 檔案路徑 ---
Write-Host ""
Write-Host "步驟 3/8: 驗證 VHDX 檔案路徑..." -ForegroundColor Yellow
if (-not (Test-Path $vhdxPath)) {
Write-Host "錯誤:無法找到 '$distroName' 的 VHDX 檔案。" -ForegroundColor Red
Read-Host "按 Enter 鍵結束..."; exit
}
Write-Host "已確認 VHDX 檔案路徑: $vhdxPath" -ForegroundColor Green
# --- 步驟 4: 取得壓縮前的檔案大小 ---
Write-Host ""
Write-Host "步驟 4/8: 正在取得壓縮前的檔案大小..." -ForegroundColor Yellow
$fileInfoBefore = Get-Item -Path $vhdxPath
$sizeBeforeBytes = $fileInfoBefore.Length
$sizeBeforeGB = $sizeBeforeBytes / 1GB
Write-Host "壓縮前大小: $($sizeBeforeGB.ToString("N2")) GB" -ForegroundColor Cyan
# --- 步驟 5: 關閉 WSL2 虛擬機 ---
Write-Host ""
Write-Host "步驟 5/8: 正在關閉所有 WSL2 執行個體..." -ForegroundColor Yellow
wsl.exe --shutdown
Write-Host "WSL2 已成功關閉。" -ForegroundColor Green
# --- 步驟 6: 執行 VHDX 壓縮優化 ---
Write-Host ""
Write-Host "步驟 6/8: 正在執行 VHDX 檔案壓縮優化..." -ForegroundColor Yellow
$optimizeVhdExists = Get-Command Optimize-Vhd -ErrorAction SilentlyContinue
if ($optimizeVhdExists) {
Write-Host "偵測到 Optimize-Vhd 指令,使用 Hyper-V 模式。" -ForegroundColor Cyan
try { Optimize-Vhd -Path $vhdxPath -Mode Full -ErrorAction Stop } catch {
Write-Host "錯誤:VHDX 優化失敗: $($_.Exception.Message)" -ForegroundColor Red
Read-Host "按 Enter 鍵結束..."; exit
}
} else {
Write-Host "未偵測到 Optimize-Vhd,切換至 diskpart 模式 (適用於 Windows 家用版)。" -ForegroundColor Cyan
$scriptContent = @"
select vdisk file="$vhdxPath"
attach vdisk readonly
compact vdisk
detach vdisk
exit
"@
$tempScript = "$env:TEMP\diskpart_script.txt"
try {
Set-Content -Path $tempScript -Value $scriptContent; diskpart /s $tempScript
} catch {
Write-Host "錯誤:使用 diskpart 進行 VHDX 優化時失敗: $($_.Exception.Message)" -ForegroundColor Red
Read-Host "按 Enter 鍵結束..."; exit
} finally {
if (Test-Path $tempScript) { Remove-Item $tempScript }
}
}
# --- 步驟 7: 取得壓縮後的檔案大小並回報成果 ---
Write-Host ""
Write-Host "步驟 7/8: 正在取得壓縮後的檔案大小並計算成果..." -ForegroundColor Yellow
$fileInfoAfter = Get-Item -Path $vhdxPath
$sizeAfterBytes = $fileInfoAfter.Length
$sizeAfterGB = $sizeAfterBytes / 1GB
$savedBytes = $sizeBeforeBytes - $sizeAfterBytes
$savedGB = $savedBytes / 1GB
Write-Host "壓縮後大小: $($sizeAfterGB.ToString("N2")) GB" -ForegroundColor Cyan
if ($savedBytes -gt 0) {
Write-Host "成功節省空間: $($savedGB.ToString("N2")) GB" -ForegroundColor Green
} else {
Write-Host "檔案大小沒有變化。" -ForegroundColor Yellow
}
# --- 步驟 8: 重新啟動 WSL ---
Write-Host ""
Write-Host "步驟 8/8: 正在重新啟動發行版 '$distroName'..." -ForegroundColor Yellow
wsl.exe -d $distroName
# --- 腳本結束 ---
Write-Host ""
Write-Host "所有流程已完成!WSL 應已在新的終端機視窗中啟動。" -ForegroundColor Green
Read-Host "按 Enter 鍵關閉此腳本視窗..."
步驟二:修改你的 WSL 發行版名稱
打開你剛剛建立的 Optimize-WSL.ps1
檔案,找到第一行的程式碼:
$distroName = "Ubuntu-24.04"
這是整個腳本唯一需要你修改的地方。請將 "Ubuntu-24.04"
替換成你自己的 WSL 發行版名稱。
不知道自己的發行版叫什麼名字?很簡單,打開 PowerShell 或 CMD,輸入 wsl -l -v
,然後複製 NAME
欄位下的那個名稱,貼到腳本裡就行了。
步驟三:以系統管理員權限執行
儲存好你的腳本後,在 Optimize-WSL.ps1
檔案上按右鍵,選擇「使用 PowerShell 執行」。
第一次執行可能會遇到的問題 如果你第一次執行時出現錯誤,提示「禁止執行指令碼」,這是因為 PowerShell 的安全原則。請用系統管理員權限打開 PowerShell,執行一次
Set-ExecutionPolicy RemoteSigned
,在確認視窗中輸入Y
按下 Enter,即可一勞永逸地解決這個問題。
執行後,腳本就會開始自動化地完成所有工作,你只需要泡杯咖啡,看著它回報成果就行了!
結語
硬碟空間是開發者寶貴的資源。有了這個自動化腳本,你可以將它放在桌面或任何方便的地方,每隔一段時間就執行一次,輕鬆地為 WSL 進行維護,讓你的硬碟保持在最佳狀態。別再讓那些無用的空間佔據你的硬碟了,馬上動手試試看吧!