harper-winrm. Administrar Windows desde Claude Code

Administrar Windows desde Linux siempre ha sido incómodo: RDP para operaciones gráficas, PSExec para scripts remotos, soluciones parcheadas. WinRM es el protocolo nativo de Microsoft para gestión remota — y harper-winrm lo conecta directamente a Claude Code.
El contenido de este artículo tiene fines educativos. Las técnicas descritas están pensadas para su uso en sistemas propios o con autorización. El autor no asume responsabilidad por usos que contravengan la legislación aplicable.
Este es el cuarto artículo de la serie MCP en el homelab.
🔧 Instalación
pip install pywinrm urllib3⚙️ Configurar WinRM en Windows
Ejecuta esto como Administrador en la máquina Windows que vas a administrar.
Opción A — HTTPS (recomendada)
# Crear certificado autofirmado válido 5 años
$cert = New-SelfSignedCertificate `
-DnsName $env:COMPUTERNAME `
-CertStoreLocation "Cert:\LocalMachine\My" `
-NotAfter (Get-Date).AddYears(5)
# Crear listener HTTPS en el puerto estándar 5986
New-Item -Path WSMan:\Localhost\Listener `
-Transport HTTPS `
-Address * `
-CertificateThumbPrint $cert.Thumbprint `
-Force
# Abrir puerto en el firewall
New-NetFirewallRule `
-DisplayName "WinRM HTTPS" `
-Direction Inbound `
-Protocol TCP `
-LocalPort 5986 `
-Action Allow
# Habilitar autenticación básica
winrm set winrm/config/service/auth '@{Basic="true"}'
Write-Host "Thumbprint: $($cert.Thumbprint)"Opción B — HTTP (solo red local de confianza)
Enable-PSRemoting -Force
winrm set winrm/config/client/auth '@{Basic="true"}'
winrm set winrm/config/service/auth '@{Basic="true"}'
winrm set winrm/config/service '@{AllowUnencrypted="true"}'⚙️ Configurar el servidor MCP
Fichero de credenciales
Las credenciales se almacenan en ~/.claude/winrm_hosts.json (fuera del repo, con permisos 600):
cp winrm_hosts.example.json ~/.claude/winrm_hosts.json
chmod 600 ~/.claude/winrm_hosts.json{
"hosts": {
"mi-windows": {
"host": "192.168.1.50",
"port": 5986,
"username": "Administrador",
"password": "tu-contraseña",
"transport": "ntlm",
"server_cert_validation": "ignore"
}
}
}Añadir a Claude Code
{
"mcpServers": {
"harper-winrm": {
"type": "stdio",
"command": "python3",
"args": ["/ruta/a/harper-mcps/mcp_winrm_server.py"],
"env": {}
}
}
}🛠️ Herramientas disponibles
winrm_run_ps
Ejecuta un comando PowerShell en la máquina Windows y devuelve el resultado.
¿Cuánta RAM libre tiene mi-windows?
→ winrm_run_ps("mi-windows", "Get-CimInstance Win32_OperatingSystem | Select FreePhysicalMemory")
winrm_read_file
Lee un fichero de la máquina Windows.
Lee C:\Windows\System32\drivers\etc\hosts de mi-windows
→ winrm_read_file("mi-windows", "C:\\Windows\\System32\\drivers\\etc\\hosts")
winrm_write_file
Escribe un fichero en la máquina Windows.
winrm_install
Instala software mediante winget. Recibe el ID del paquete y lo instala sin interacción.
Instala VLC en mi-windows
→ winrm_install("mi-windows", "VideoLAN.VLC")
winrm_check
Verifica la conectividad WinRM con el host. Útil para diagnosticar problemas de configuración.
winrm_list_hosts
Lista todos los hosts Windows configurados en winrm_hosts.json.
💬 Ejemplo de sesión real
Tú: Dime qué actualizaciones de Windows están pendientes en mi-windows.
Claude: [winrm_run_ps("mi-windows", "Get-WindowsUpdate")]
→ 3 actualizaciones pendientes: KB5034441, KB5034843, KB5035942
Tú: Instala las actualizaciones.
Claude: [winrm_run_ps("mi-windows", "Install-WindowsUpdate -AcceptAll -AutoReboot")]
→ Instalando... reinicio programado.
Tú: Cuando arranque, instala también Firefox.
Claude: [winrm_install("mi-windows", "Mozilla.Firefox")]
→ Firefox instalado correctamente.
Todo desde la terminal de Linux. Sin abrir RDP. Sin ratón.
📚 La serie
- Parte 1 — Introducción y visión general
- Parte 2 — harper-obsidian: tu vault desde el chat
- Parte 3 — harper-ssh: SSH y nmap sin salir de Claude
- [Parte 4 — harper-winrm] ← estás aquí
- Parte 5 — harper-osint: investigación de fuentes abiertas
