安装方式
手动下载安装
下载 ZIP 后解压到技能目录即可安装。若在桌面客户端 WebView中直接下载出现异常,本站会改为提示页 + 原始链接,请按页内说明操作。
下载 ZIP (oss-superpowers-lab-windows-vm-v1.0.0.zip)触发指令
/windows-vm
跨平台安装指引
该技能声明兼容以下 1 个平台,将 ZIP 解压到对应目录即可被识别。
unzip oss-superpowers-lab-windows-vm-v1.0.0.zip -d ~/.claude/skills/
mkdir -p 创建;启用 Skill 后请重启对应 Agent 让配置生效。
使用指南
无图形界面 Windows 11 虚拟机
通过 dockur/windows 在 Docker 中运行带 KVM 加速的 Windows 11 虚拟机。仅通过 SSH 访问,无需 RDP 或本地图形界面。
主机环境要求
- 已安装 Docker
- KVM:宿主机需有
/dev/kvm(可用ls /dev/kvm检查) sshpass(示例:sudo apt install sshpass)imagemagick(可选,用于截屏排查:sudo apt install imagemagick)
配置说明
| 项目 | 说明 |
|------|------|
| 容器名 | windows11 |
| 虚拟机目录 | $HOME/windows-vm/ |
| storage/ | 虚拟磁盘(由 dockur 管理,重建容器时可能被清空) |
| iso/win11x64.iso | 缓存的 Windows 安装镜像(约 7.3GB,可长期保留) |
| oem/install.bat | 安装后脚本(用于安装 OpenSSH Server) |
| 账号 | 默认 user / password(可按镜像文档修改) |
| SSH | 127.0.0.1:2222(仅本机) |
| RDP | 127.0.0.1:3389(备用) |
| Web 控制台 | 127.0.0.1:8006(浏览器里 VNC,调试用) |
| 资源示例 | 8GB 内存、4 核、64GB 磁盘 |
常用操作
create — 首次创建或完整重建
- 创建目录:
mkdir -p "$HOME/windows-vm/oem" "$HOME/windows-vm/storage" "$HOME/windows-vm/iso"
-
在
$HOME/windows-vm/oem/install.bat中配置 OpenSSH 安装逻辑(与官方仓库示例一致)。 -
若重建虚拟机,先停容器并删除旧盘:
docker stop windows11 && docker rm windows11
rm -f "$HOME/windows-vm/storage/data.img"
-
已有缓存 ISO(
$HOME/windows-vm/iso/win11x64.iso)时,挂载为/boot.iso启动容器;首次无 ISO 时不要挂/boot.iso,并设置VERSION="win11"由容器拉取。安装完成后请尽快把 ISO 复制到iso/目录,避免重建时重复下载。 -
安装与首次开机约 20–30 分钟。可用
docker logs -f windows11或浏览器打开http://localhost:8006查看进度。 -
检查 SSH 是否就绪:
sshpass -p 'password' ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 -p 2222 user@localhost "whoami"
start / stop / restart
docker start windows11
docker stop windows11
docker restart windows11
status — 查看状态
docker ps -f name=windows11 --format "table {{.Status}}\t{{.Ports}}"
docker logs windows11 2>&1 | tail -5
ssh — 登录虚拟机
ssh -p 2222 user@localhost
重要提示
--cap-add NET_ADMIN:端口转发依赖,缺省可能导致转发静默失败。--device /dev/kvm:硬件加速所需。- ISO 缓存:
/storage在部分重建场景会被 dockur 清空,请把长期保存的 ISO 放在iso/并挂载为/boot.iso。 - 端口均绑定 127.0.0.1,不对局域网暴露。
- 重建后 SSH 主机密钥会变,需执行:
ssh-keygen -f ~/.ssh/known_hosts -R '[localhost]:2222'。
与 Claude Code / Node 相关
在 VM 内安装 Node、全局包时,注意 系统 PATH、PowerShell 执行策略 以及 通过 SSH 执行复杂 PowerShell 时的引号转义。长脚本建议用 stdin 管道 喂给 powershell -Command -,减少嵌套引号错误;单行命令注意对 $、" 的 SSH 与远程双层转义。具体 docker run 参数、卷挂载与环境变量以 dockur/windows README 为准。
# Headless Windows 11 VM
Manage a headless Windows 11 VM running via [dockur/windows](https://github.com/dockur/windows) in Docker with KVM acceleration. The VM is accessible via SSH only — no RDP or GUI required.
## Host prerequisites
- Docker
- KVM support (`/dev/kvm` must exist — check with `ls /dev/kvm`)
- `sshpass` (`sudo apt install sshpass`)
- `imagemagick` (optional, for screenshot debugging: `sudo apt install imagemagick`)
## Configuration
- **Container name**: `windows11`
- **VM directory**: `$HOME/windows-vm/`
- `storage/` — VM disk image (managed by dockur, wiped on recreate)
- `iso/win11x64.iso` — cached Windows ISO (7.3GB, persists across recreates)
- `oem/install.bat` — post-install script (installs OpenSSH Server)
- **Credentials**: user / password
- **SSH**: `localhost:2222` (bound to 127.0.0.1 only)
- **RDP**: `localhost:3389` (bound to 127.0.0.1 only, fallback)
- **Web console**: `localhost:8006` (VNC in browser, for debugging)
- **Resources**: 8GB RAM, 4 CPU cores, 64GB disk
## Actions
### create — First-time setup or full recreate
1. Ensure directories exist:
```bash
mkdir -p "$HOME/windows-vm/oem" "$HOME/windows-vm/storage" "$HOME/windows-vm/iso"
```
2. Ensure `$HOME/windows-vm/oem/install.bat` exists with OpenSSH setup:
```bat
@echo off
echo Installing OpenSSH Server...
powershell -Command "Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0" 2>nul
powershell -Command "Get-WindowsCapability -Online -Name OpenSSH.Server* | Add-WindowsCapability -Online" 2>nul
dism /Online /Add-Capability /CapabilityName:OpenSSH.Server~~~~0.0.1.0 2>nul
powershell -Command "Start-Service sshd" 2>nul
powershell -Command "Set-Service -Name sshd -StartupType Automatic"
powershell -Command "New-ItemProperty -Path 'HKLM:\SOFTWARE\OpenSSH' -Name DefaultShell -Value 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' -PropertyType String -Force"
powershell -Command "New-NetFirewallRule -Name 'OpenSSH-Server' -DisplayName 'OpenSSH Server' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22"
powershell -Command "Get-Service sshd" 2>nul
echo Done.
```
3. If recreating, remove the old container and disk:
```bash
docker stop windows11 && docker rm windows11
rm -f "$HOME/windows-vm/storage/data.img"
```
4. Launch the container. There are two cases:
**If cached ISO exists** (`$HOME/windows-vm/iso/win11x64.iso`):
```bash
docker run -d \
--name windows11 \
-p 127.0.0.1:3389:3389 \
-p 127.0.0.1:2222:22 \
-p 127.0.0.1:8006:8006 \
-e RAM_SIZE="8G" \
-e CPU_CORES="4" \
-e DISK_SIZE="64G" \
-e USERNAME="user" \
-e PASSWORD="password" \
--cap-add NET_ADMIN \
--device /dev/kvm \
-v "$HOME/windows-vm/storage:/storage" \
-v "$HOME/windows-vm/oem:/oem" \
-v "$HOME/windows-vm/iso/win11x64.iso:/boot.iso" \
dockurr/windows
```
**First time (no cached ISO)** — omit the `/boot.iso` mount and add `VERSION`:
```bash
docker run -d \
--name windows11 \
-p 127.0.0.1:3389:3389 \
-p 127.0.0.1:2222:22 \
-p 127.0.0.1:8006:8006 \
-e RAM_SIZE="8G" \
-e CPU_CORES="4" \
-e DISK_SIZE="64G" \
-e VERSION="win11" \
-e USERNAME="user" \
-e PASSWORD="password" \
--cap-add NET_ADMIN \
--device /dev/kvm \
-v "$HOME/windows-vm/storage:/storage" \
-v "$HOME/windows-vm/oem:/oem" \
dockurr/windows
```
After the ISO downloads and Windows boots, **immediately** copy the ISO out before
the container is ever stopped (dockur wipes `/storage` on recreate):
```bash
cp "$HOME/windows-vm/storage/win11x64.iso" "$HOME/windows-vm/iso/win11x64.iso"
```
5. Wait for Windows install + OpenSSH setup to complete. This takes **20-30 minutes** for a
fresh install (the OEM install.bat runs at the end of Windows OOBE and downloads OpenSSH
from Microsoft, which is slow). Monitor with:
```bash
docker logs -f windows11
```
You can also watch the VM screen via the web console at `http://localhost:8006`.
To check if SSH is up:
```bash
sshpass -p 'password' ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 -p 2222 user@localhost "whoami"
```
6. Once SSH is responding, install Node.js and Claude Code by piping a setup script via stdin
(avoids PowerShell escaping hell over SSH):
```bash
cat << 'PS' | sshpass -p 'password' ssh -o StrictHostKeyChecking=no -p 2222 user@localhost "powershell -ExecutionPolicy Bypass -Command -"
# Download and install Node.js silently
Invoke-WebRequest -Uri 'https://nodejs.org/dist/v22.14.0/node-v22.14.0-x64.msi' -OutFile 'C:\Users\user\node-install.msi'
Start-Process msiexec.exe -ArgumentList '/i C:\Users\user\node-install.msi /qn /norestart' -Wait -Verb RunAs
Write-Host "Node.js installed"
# Install Claude Code globally
& 'C:\Program Files\nodejs\npm.cmd' install -g @anthropic-ai/claude-code
Write-Host "Claude Code installed"
# Add npm global bin to SYSTEM PATH (user PATH is not read by sshd)
$systemPath = [Environment]::GetEnvironmentVariable('Path', 'Machine')
$additions = @()
if ($systemPath -notlike '*AppData*npm*') { $additions += 'C:\Users\user\AppData\Roaming\npm' }
if ($systemPath -notlike '*Git\cmd*') { $additions += 'C:\Program Files\Git\cmd' }
if ($additions.Count -gt 0) {
[Environment]::SetEnvironmentVariable('Path', $systemPath + ';' + ($additions -join ';'), 'Machine')
Write-Host "Added to system PATH: $($additions -join ', ')"
}
# Set execution policy machine-wide (required for claude.ps1)
Set-ExecutionPolicy RemoteSigned -Scope LocalMachine -Force -ErrorAction SilentlyContinue
# Create system-wide PowerShell profile that rebuilds PATH from registry on login.
# Without this, interactive SSH sessions don't pick up the full system PATH.
$profileDir = Split-Path $PROFILE.AllUsersAllHosts
if (-not (Test-Path $profileDir)) { New-Item -ItemType Directory -Path $profileDir -Force }
@'
$machinePath = [Environment]::GetEnvironmentVariable('Path', 'Machine')
$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
$env:Path = "$machinePath;$userPath"
'@ | Set-Content -Path $PROFILE.AllUsersAllHosts -Force
Write-Host "PowerShell profile created"
# Restart sshd so it picks up the new PATH
Restart-Service sshd -Force
PS
```
Note: the connection will drop when sshd restarts — that's expected.
7. Clear the stale host key (new VM = new host key) and verify:
```bash
ssh-keygen -f ~/.ssh/known_hosts -R '[localhost]:2222'
sshpass -p 'password' ssh -o StrictHostKeyChecking=no -p 2222 user@localhost "claude --version"
```
### start — Start a stopped VM
```bash
docker start windows11
```
### stop — Stop the VM
```bash
docker stop windows11
```
### restart — Restart the VM
```bash
docker restart windows11
```
### status — Check VM status
```bash
docker ps -f name=windows11 --format "table {{.Status}}\t{{.Ports}}"
docker logs windows11 2>&1 | tail -5
```
### ssh — Connect to the VM
```bash
ssh -p 2222 user@localhost
```
### screenshot — See what's on the VM screen (for debugging)
```bash
docker exec windows11 bash -c "echo 'screendump /tmp/screen.ppm' | nc -w 2 localhost 7100" > /dev/null 2>&1
sleep 1
docker cp windows11:/tmp/screen.ppm /tmp/screen.ppm
convert /tmp/screen.ppm /tmp/screen.png
```
## Important Notes
- **ISO caching**: The `/storage` volume is managed by dockur and gets wiped on recreate. Store the ISO separately in `$HOME/windows-vm/iso/` and mount it as `/boot.iso` to skip the 7.3GB download.
- **`--cap-add NET_ADMIN`** is required for port forwarding to work. Without it, QEMU falls back to user-mode networking and port forwarding silently fails.
- **`--device /dev/kvm`** is required for hardware acceleration.
- **Boot time**: Fresh install takes 20-30 min (Windows install + OpenSSH download from Microsoft). Subsequent boots from existing `data.img` are fast (~2 min).
- Ports are bound to `127.0.0.1` only — not exposed to the network.
- Do NOT use `-e VERSION="win11"` when mounting `/boot.iso` — the version is auto-detected from the ISO.
## Post-install gotchas
- **Node.js is not pre-installed** — the Claude Code install script (`irm https://claude.ai/install.ps1 | iex`) will report success but `claude` won't work without Node. Install Node.js via MSI first.
- **npm global bin not in PATH** — Node's MSI adds `C:\Program Files\nodejs` to PATH but not `C:\Users\user\AppData\Roaming\npm` (where `npm install -g` puts binaries). Must add it to the **system** PATH (not user PATH) because OpenSSH's sshd only reads system PATH. After changing system PATH, restart sshd.
- **PowerShell execution policy** — Default policy is `Restricted`, which blocks `claude.ps1`. Must set to `RemoteSigned` at **LocalMachine** scope (not CurrentUser) for it to take effect in SSH sessions.
- **Escaping hell** — Running PowerShell commands over SSH with nested quotes is unreliable. Pipe scripts via stdin using `powershell -ExecutionPolicy Bypass -Command -` instead.
- **Interactive SSH sessions don't get full PATH** — Windows OpenSSH sshd doesn't properly propagate the system PATH to interactive PowerShell sessions. Fix: create a system-wide PowerShell profile (`$PROFILE.AllUsersAllHosts`) that rebuilds `$env:Path` from the registry on every login.
- **winget may not work** — The Microsoft Store certificate can fail in a VM. Use direct MSI/installer downloads instead.
- **Host key changes** — Each recreated VM gets new SSH host keys. Run `ssh-keygen -R '[localhost]:2222'` to clear the old one.