Skip to content
Development
Skill

/windows-vm

Create, manage, or connect to a headless Windows 11 VM running in Docker with SSH access. Use when the user wants to spin up, stop, restart, or SSH into a Windows VM.

From plugin
superpowers-lab
4294 skills
Install
$ npx -y skills add obra/superpowers-lab --skill windows-vm --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/windows-vm

Context preview

The summary Claude sees to decide when to auto-load this skill.

Create, manage, or connect to a headless Windows 11 VM running in Docker with SSH access. Use when the user wants to spin up, stop, restart, or SSH into a Windows VM.

SKILL.md

windows-vm.SKILL.md
name: windows-vm
description: Create, manage, or connect to a headless Windows 11 VM running in Docker with SSH access. Use when the user wants to spin up, stop, restart, or SSH into a Windows VM.
argument-hint: "[create|start|stop|restart|ssh|status]"
allowed-tools: Bash, Read, Write

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:

   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:

   @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:

   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`):

   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`:

   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):

   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:

   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:

   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):

   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 -Sc
Read more
Ships withsuperpowers-lab

Experimental skills for Claude Code Superpowers - new techniques and tools under active development.

Get the whole plugin
Stats
429
Stars
35
Forks
Maintained
Maintenance
Shell
Language
MIT
License
3mo ago
Last commit
11mo ago
Created

Repo: obra/superpowers-lab

Other skills on superpowers-lab.