前置条件
- Windows 10 版本 1903 或更高(Build 18362+)或 Windows 11 任意版本
- VMware 15.5.5 以上版本(如果安装了VMware的话,支持与 WSL2 共存)
通用基本步骤
1. 以管理员身份打开 PowerShell,运行:
powershell
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
2. 重启电脑
powershell
shutdown /r /t 0
3. 重启后运行(WSL2 内核更新):
powershell
wsl --update
4. 设置默认版本:
powershell
wsl --set-default-version 2
5. 升级现有发行版:
powershell
# 先看看你有哪些发行版
wsl --list --verbose
# 然后升级(把 Ubuntu 替换成你实际的发行版名称)
wsl --set-version Ubuntu 2
第 5 步转换需要几分钟,完成后再跑一次 wsl --list --verbose 确认 VERSION 列显示 2 就搞定了。
但是通常可能会存在一些报错,这时候需要直接将报错信息贴给 claude就行。出现如下信息,代表升级成功:
powershell
PS C:\Windows\system32> wsl --list --verbose
NAME STATE VERSION
* Ubuntu-20.04 Stopped 2
一键升级脚本
powershell
#Requires -RunAsAdministrator
<#
.SYNOPSIS
一键将 WSL1 升级为 WSL2(含全部已知坑的修复)
.DESCRIPTION
覆盖的问题:
1. VirtualMachinePlatform / HypervisorPlatform 未启用
2. hypervisorlaunchtype 被 VMware / Android Studio 改为 Off
3. aehd 驱动(Android 模拟器)占用虚拟化硬件
4. vmcompute 服务被禁用(DISABLED)
5. 未安装 WSL2 Linux 内核
.NOTES
运行方式:右键 -> 以管理员身份运行 PowerShell,然后执行:
Set-ExecutionPolicy Bypass -Scope Process -Force
.\Upgrade-WSL2.ps1
#>
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
function Write-Step { param($msg) Write-Host "`n[*] $msg" -ForegroundColor Cyan }
function Write-OK { param($msg) Write-Host " [OK] $msg" -ForegroundColor Green }
function Write-Warn { param($msg) Write-Host " [!!] $msg" -ForegroundColor Yellow }
function Write-Fail { param($msg) Write-Host " [XX] $msg" -ForegroundColor Red }
# ─────────────────────────────────────────────────────────────
# 0. 检查是否需要重启(由上次 dism 操作触发)
# ─────────────────────────────────────────────────────────────
Write-Step "检查是否存在待处理的重启"
$pendingReboot = $false
$regKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending"
if (Test-Path $regKey) { $pendingReboot = $true }
$regKey2 = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager"
$pendingFiles = (Get-ItemProperty $regKey2 -ErrorAction SilentlyContinue).PendingFileRenameOperations
if ($pendingFiles) { $pendingReboot = $true }
if ($pendingReboot) {
Write-Warn "系统有待处理的重启,建议先重启后再运行本脚本,否则功能启用可能不生效。"
$ans = Read-Host " 是否继续?(y/N)"
if ($ans -ne 'y') { exit 0 }
}
# ─────────────────────────────────────────────────────────────
# 1. 启用 Windows 必要功能
# ─────────────────────────────────────────────────────────────
Write-Step "检查并启用虚拟化所需 Windows 功能"
$features = @('VirtualMachinePlatform', 'HypervisorPlatform', 'Microsoft-Windows-Subsystem-Linux')
$needReboot = $false
foreach ($f in $features) {
$info = dism.exe /online /get-featureinfo /featurename:$f 2>&1 | Out-String
if ($info -match 'State : 已启用|State : Enabled') {
Write-OK "$f 已启用"
} else {
Write-Warn "$f 未启用,正在启用..."
dism.exe /online /enable-feature /featurename:$f /all /norestart | Out-Null
Write-OK "$f 已启用(需重启生效)"
$needReboot = $true
}
}
# ─────────────────────────────────────────────────────────────
# 2. 修复 hypervisorlaunchtype(VMware 常把它改成 Off)
# ─────────────────────────────────────────────────────────────
Write-Step "检查 Hypervisor 启动类型"
$bcd = bcdedit /enum `{current`} 2>&1 | Out-String
if ($bcd -match 'hypervisorlaunchtype\s+Off') {
Write-Warn "hypervisorlaunchtype 为 Off(VMware 改动),正在修复..."
bcdedit /set hypervisorlaunchtype auto | Out-Null
Write-OK "已设置为 auto(需重启生效)"
$needReboot = $true
} elseif ($bcd -match 'hypervisorlaunchtype\s+Auto') {
Write-OK "hypervisorlaunchtype 已为 auto"
} else {
Write-Warn "未找到 hypervisorlaunchtype 条目,执行 bcdedit /set hypervisorlaunchtype auto"
bcdedit /set hypervisorlaunchtype auto | Out-Null
Write-OK "已添加 auto 设置(需重启生效)"
$needReboot = $true
}
# ─────────────────────────────────────────────────────────────
# 3. 禁用 aehd(Android 模拟器虚拟化驱动,与 WSL2 冲突)
# ─────────────────────────────────────────────────────────────
Write-Step "检查 aehd 驱动(Android 模拟器 / WSL2 冲突)"
$ahd = sc.exe qc aehd 2>&1 | Out-String
if ($ahd -match 'SYSTEM_START|BOOT_START|AUTO_START') {
Write-Warn "aehd 驱动处于自动启动状态,正在禁用(仅影响 Android 模拟器的 Hypervisor 后端)..."
sc.exe config aehd start= disabled | Out-Null
Write-OK "aehd 已禁用(需重启生效)"
$needReboot = $true
} elseif ($ahd -match 'DISABLED') {
Write-OK "aehd 已是禁用状态"
} else {
Write-OK "未检测到 aehd 驱动,跳过"
}
# ─────────────────────────────────────────────────────────────
# 4. 如需重启,提示后退出
# ─────────────────────────────────────────────────────────────
if ($needReboot) {
Write-Host "`n[!] 上述修改需要重启后生效。" -ForegroundColor Yellow
Write-Host " 重启后请重新以管理员身份运行本脚本以完成后续步骤。" -ForegroundColor Yellow
$ans = Read-Host " 现在立即重启?(y/N)"
if ($ans -eq 'y') { shutdown /r /t 5 }
exit 0
}
# ─────────────────────────────────────────────────────────────
# 5. 更新 WSL2 内核
# ─────────────────────────────────────────────────────────────
Write-Step "更新 WSL2 Linux 内核"
try {
wsl --update 2>&1 | ForEach-Object { Write-Host " $_" }
Write-OK "WSL2 内核已是最新"
} catch {
Write-Warn "wsl --update 失败,请手动前往 https://aka.ms/wsl2kernel 下载安装"
}
# ─────────────────────────────────────────────────────────────
# 6. 修复 vmcompute 服务(被禁用时自动恢复)
# ─────────────────────────────────────────────────────────────
Write-Step "检查并启动 vmcompute 服务"
$svc = sc.exe qc vmcompute 2>&1 | Out-String
if ($svc -match 'DISABLED') {
Write-Warn "vmcompute 服务被禁用,正在恢复为按需启动..."
sc.exe config vmcompute start= demand | Out-Null
Write-OK "vmcompute 已恢复为 demand"
}
# 依赖服务:hvsocketcontrol
$dep = Get-Service hvsocketcontrol -ErrorAction SilentlyContinue
if ($dep -and $dep.Status -ne 'Running') {
Write-Warn "依赖服务 hvsocketcontrol 未运行,正在启动..."
Start-Service hvsocketcontrol -ErrorAction SilentlyContinue
}
# 启动 vmcompute
$vm = Get-Service vmcompute -ErrorAction SilentlyContinue
if ($vm -and $vm.Status -eq 'Running') {
Write-OK "vmcompute 已在运行"
} else {
Write-Warn "vmcompute 未运行,尝试启动..."
sc.exe start vmcompute | Out-Null
Start-Sleep 3
$vm = Get-Service vmcompute
if ($vm.Status -eq 'Running') {
Write-OK "vmcompute 启动成功"
} else {
Write-Fail "vmcompute 启动失败,请检查系统日志:Get-EventLog -LogName System -Source *hyper* -Newest 10"
exit 1
}
}
# ─────────────────────────────────────────────────────────────
# 7. 验证 Hypervisor 确实在运行
# ─────────────────────────────────────────────────────────────
Write-Step "验证 Hypervisor 状态"
$hvPresent = (Get-CimInstance Win32_ComputerSystem).HypervisorPresent
if ($hvPresent) {
Write-OK "HypervisorPresent = True"
} else {
Write-Fail "Hypervisor 未运行,请确认重启后再试"
exit 1
}
# ─────────────────────────────────────────────────────────────
# 8. 设置 WSL2 为默认版本
# ─────────────────────────────────────────────────────────────
Write-Step "设置默认 WSL 版本为 2"
wsl --set-default-version 2 2>&1 | Out-Null
Write-OK "默认版本已设为 2"
# ─────────────────────────────────────────────────────────────
# 9. 升级所有 WSL1 发行版
# ─────────────────────────────────────────────────────────────
Write-Step "检测并升级 WSL1 发行版"
$list = wsl --list --verbose 2>&1 | Select-Object -Skip 1 | Where-Object { $_ -match '\S' }
$upgraded = 0
foreach ($line in $list) {
if ($line -match '^\*?\s+(\S+)\s+\S+\s+(1)\s*$') {
$distro = $Matches[1]
Write-Host " 正在升级 $distro (WSL1 -> WSL2),请稍候..." -ForegroundColor Cyan
wsl --set-version $distro 2
Write-OK "$distro 升级完成"
$upgraded++
}
}
if ($upgraded -eq 0) {
Write-OK "未发现 WSL1 发行版,所有发行版已是 WSL2"
}
# ─────────────────────────────────────────────────────────────
# 10. 最终状态确认
# ─────────────────────────────────────────────────────────────
Write-Step "最终状态"
wsl --list --verbose
Write-Host "`n[完成] WSL2 升级成功!" -ForegroundColor Green