PowerShell Remoting es una de las funcionalidades más potentes del conjunto de herramientas de administración de Windows. Te permite ejecutar comandos, correr scripts y gestionar configuraciones en máquinas remotas — una a la vez o en cientos simultáneamente. En su núcleo, PowerShell Remoting se apoya en Windows Remote Management (WinRM), la implementación de Microsoft del protocolo WS-Management. En esta guía, aprenderás cómo habilitar y configurar WinRM, usar los cmdlets principales de remoting, gestionar credenciales de forma segura, manejar escenarios entre dominios y aprovechar el remoting basado en SSH para la administración multiplataforma.
Requisitos Previos
Antes de comenzar a configurar PowerShell Remoting, asegúrate de tener lo siguiente:
- Windows Server 2016 o posterior (o Windows 10/11 Pro/Enterprise para máquinas cliente)
- PowerShell 5.1 o posterior instalado (se recomienda PowerShell 7+ para remoting basado en SSH)
- Privilegios administrativos tanto en la máquina cliente como en las remotas
- Conectividad de red en el puerto 5985 (HTTP) o 5986 (HTTPS) entre cliente y servidor
- Dominio de Active Directory (recomendado pero no requerido — las configuraciones de grupo de trabajo se cubren más adelante)
- Familiaridad básica con cmdlets de PowerShell y configuración del firewall de Windows
Habilitación y Configuración de WinRM
WinRM está instalado por defecto en los sistemas Windows modernos, pero el servicio típicamente no está en ejecución y las reglas de firewall no están habilitadas en los sistemas operativos cliente. En las ediciones de Windows Server a partir de 2012, WinRM está habilitado por defecto, pero aun así debes verificar la configuración.
Habilitar PSRemoting
La forma más rápida de habilitar todo a la vez es el cmdlet Enable-PSRemoting:
# Ejecutar en una sesión elevada de PowerShell en la máquina remota
Enable-PSRemoting -Force
Este único comando realiza varias acciones: inicia el servicio WinRM, lo configura para inicio automático, crea un listener HTTP en el puerto 5985, añade excepciones al Firewall de Windows y registra las configuraciones de sesión predeterminadas de PowerShell.
Verificar que WinRM Está Escuchando
Después de habilitar, confirma que el servicio está ejecutándose y los listeners están activos:
# Verificar estado del servicio
Get-Service WinRM
# Listar listeners activos
Get-WSManInstance -ResourceURI winrm/config/listener -Enumerate
# Prueba rápida de conectividad desde el cliente
Test-WSMan -ComputerName SERVIDOR01
Configurar TrustedHosts
En un entorno de dominio, Kerberos gestiona la autenticación de forma transparente. En escenarios de grupo de trabajo o entre dominios, necesitas configurar TrustedHosts en la máquina cliente:
# Agregar un solo host
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "SERVIDOR01"
# Agregar múltiples hosts (separados por comas)
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "SERVIDOR01,SERVIDOR02,192.168.1.50"
# Confiar en todos los hosts (NO recomendado para producción)
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "*"
# Ver los TrustedHosts actuales
Get-Item WSMan:\localhost\Client\TrustedHosts
Configurar Transporte HTTPS
Para entornos de producción, especialmente a través de redes no confiables, el transporte HTTPS cifra toda la sesión WinRM:
# En el servidor remoto: crear un certificado autofirmado
$cert = New-SelfSignedCertificate -DnsName "SERVIDOR01.contoso.com" `
-CertStoreLocation Cert:\LocalMachine\My -NotAfter (Get-Date).AddYears(5)
# Crear un listener HTTPS usando la huella digital del certificado
New-WSManInstance -ResourceURI winrm/config/listener `
-SelectorSet @{Address="*"; Transport="HTTPS"} `
-ValueSet @{CertificateThumbprint=$cert.Thumbprint}
# Agregar regla de firewall para HTTPS
New-NetFirewallRule -DisplayName "WinRM HTTPS" -Direction Inbound `
-LocalPort 5986 -Protocol TCP -Action Allow
Configurar mediante Directiva de Grupo
Para un despliegue a nivel de dominio, utiliza la Directiva de Grupo para habilitar WinRM a gran escala:
- Navega a Configuración del equipo → Plantillas administrativas → Componentes de Windows → Administración remota de Windows → Servicio WinRM
- Habilita Permitir la administración remota del servidor a través de WinRM
- Establece el filtro IPv4/IPv6 a
*o subredes específicas - Configura Shell remoto de Windows → Permitir el acceso a Shell remoto como Habilitado
Uso de Invoke-Command y Enter-PSSession
PowerShell proporciona dos cmdlets principales para la ejecución remota, cada uno adaptado a diferentes flujos de trabajo.
Invoke-Command — Ejecución por Lotes en Paralelo
Invoke-Command envía un bloque de script a uno o más equipos y los ejecuta en paralelo por defecto (hasta 32 conexiones simultáneas):
# Ejecutar un comando en un solo host remoto
Invoke-Command -ComputerName SERVIDOR01 -ScriptBlock {
Get-Process | Sort-Object CPU -Descending | Select-Object -First 10
}
# Ejecutar contra múltiples servidores simultáneamente
$servidores = @("SERVIDOR01", "SERVIDOR02", "SERVIDOR03", "SERVIDOR04")
Invoke-Command -ComputerName $servidores -ScriptBlock {
Get-Service -Name "W3SVC" | Select-Object Status, MachineName
}
# Limitar la concurrencia para entornos grandes
Invoke-Command -ComputerName $servidores -ScriptBlock {
Restart-Service -Name "Spooler" -Force
} -ThrottleLimit 10
# Ejecutar un archivo de script local en máquinas remotas
Invoke-Command -ComputerName $servidores -FilePath "C:\Scripts\Audit-Security.ps1"
Enter-PSSession — Remoting Interactivo
Enter-PSSession es ideal para resolución de problemas ad-hoc donde necesitas un shell interactivo:
# Iniciar una sesión interactiva
Enter-PSSession -ComputerName SERVIDOR01 -Credential (Get-Credential)
# Ahora estás en SERVIDOR01 — ejecuta comandos como si fuera local
[SERVIDOR01]: PS C:\> Get-EventLog -LogName System -Newest 20
[SERVIDOR01]: PS C:\> Get-Disk | Format-Table
[SERVIDOR01]: PS C:\> Exit-PSSession
Sesiones Persistentes (PSSessions)
Para conexiones repetidas, crea una sesión persistente para evitar la sobrecarga de establecer una nueva conexión cada vez:
# Crear sesiones persistentes
$sesiones = New-PSSession -ComputerName SERVIDOR01, SERVIDOR02, SERVIDOR03
# Reutilizar la sesión en múltiples comandos
Invoke-Command -Session $sesiones -ScriptBlock { Get-HotFix | Select-Object -Last 5 }
Invoke-Command -Session $sesiones -ScriptBlock { Get-WindowsFeature | Where-Object Installed }
# Copiar archivos a través de una sesión
Copy-Item -Path "C:\Deploy\app.zip" -Destination "C:\Install\" -ToSession $sesiones[0]
# Limpiar cuando termines
Remove-PSSession $sesiones
Gestión de Credenciales y Seguridad
El manejo adecuado de credenciales es crucial para el remoting seguro a gran escala.
Uso de Get-Credential y PSCredential
# Solicitud interactiva
$cred = Get-Credential -UserName "CONTOSO\admin" -Message "Ingresa la contraseña de administrador remoto"
# Credencial programática (para automatización — protege la fuente de la contraseña)
$securePass = ConvertTo-SecureString "P@ssw0rd!" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential("CONTOSO\admin", $securePass)
Almacenamiento Seguro de Credenciales
Nunca escribas contraseñas directamente en los scripts. Utiliza uno de estos enfoques:
# Exportar credencial cifrada a archivo (específica de usuario+máquina)
Get-Credential | Export-Clixml -Path "$HOME\cred.xml"
# Importar en otra sesión (mismo usuario, misma máquina únicamente)
$cred = Import-Clixml -Path "$HOME\cred.xml"
# Usar el Administrador de Credenciales de Windows mediante el módulo CredentialManager
Install-Module -Name CredentialManager -Force
New-StoredCredential -Target "WinRM-Admin" -UserName "CONTOSO\admin" `
-Password "P@ssw0rd!" -Persist LocalMachine
$cred = Get-StoredCredential -Target "WinRM-Admin"
CredSSP para Escenarios de Doble Salto
Cuando un comando remoto necesita acceder a un segundo recurso (el problema del “doble salto”), configura la delegación CredSSP:
# En el cliente: habilitar el rol de cliente CredSSP
Enable-WSManCredSSP -Role Client -DelegateComputer "SERVIDOR01.contoso.com"
# En el servidor: habilitar el rol de servidor CredSSP
Enable-WSManCredSSP -Role Server
# Conectar usando autenticación CredSSP
Invoke-Command -ComputerName SERVIDOR01 -Credential $cred `
-Authentication CredSSP -ScriptBlock {
# Ahora puede acceder a recursos de red como carpetas compartidas
Get-ChildItem "\\FILESERVER\Share$"
}
Advertencia: CredSSP envía las credenciales al servidor remoto. Úsalo solo con máquinas de confianza y preferiblemente a través de HTTPS.
Just Enough Administration (JEA)
Para remoting con privilegios mínimos, configura endpoints JEA que restrinjan lo que los usuarios pueden hacer:
# Crear un archivo de capacidad de rol
New-PSRoleCapabilityFile -Path "C:\JEA\HelpDeskRole.psrc" `
-VisibleCmdlets @("Restart-Service", "Get-Service", "Get-Process") `
-VisibleFunctions @("Get-HotFix")
# Crear configuración de sesión
New-PSSessionConfigurationFile -Path "C:\JEA\HelpDesk.pssc" `
-SessionType RestrictedRemoteServer `
-RunAsVirtualAccount `
-RoleDefinitions @{ "CONTOSO\HelpDesk" = @{ RoleCapabilities = "HelpDeskRole" } }
# Registrar el endpoint
Register-PSSessionConfiguration -Name "HelpDesk" -Path "C:\JEA\HelpDesk.pssc"
Remoting Basado en SSH para Multiplataforma
A partir de PowerShell 7, puedes usar SSH como capa de transporte en lugar de WinRM. Esto es especialmente útil para administrar máquinas Linux y macOS junto con servidores Windows.
Instalar y Configurar OpenSSH
# En Windows: instalar el servidor OpenSSH
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Start-Service sshd
Set-Service sshd -StartupType Automatic
# Configurar el subsistema SSH para PowerShell en sshd_config
# Agrega esta línea a C:\ProgramData\ssh\sshd_config:
# Subsystem powershell c:/progra~1/powershell/7/pwsh.exe -sshs -NoLogo -NoProfile
Restart-Service sshd
En Linux, agrega el subsistema de PowerShell a /etc/ssh/sshd_config:
# Instalar PowerShell en Ubuntu
sudo apt-get update && sudo apt-get install -y powershell
# Agregar subsistema a sshd_config
echo "Subsystem powershell /usr/bin/pwsh -sshs -NoLogo -NoProfile" | sudo tee -a /etc/ssh/sshd_config
sudo systemctl restart sshd
Uso del Remoting Basado en SSH
# Sesión interactiva sobre SSH
Enter-PSSession -HostName servidor-linux01 -UserName admin -SSHTransport
# Ejecutar comandos en Linux desde Windows
Invoke-Command -HostName servidor-linux01 -UserName admin -ScriptBlock {
uname -a
df -h
systemctl status nginx
}
# Apuntar a sistemas operativos mixtos
$sesionWindows = New-PSSession -ComputerName WIN-SRV01 -Credential $cred
$sesionLinux = New-PSSession -HostName LINUX-SRV01 -UserName admin -SSHTransport
Invoke-Command -Session $sesionWindows, $sesionLinux -ScriptBlock {
if ($IsLinux) { cat /etc/os-release } else { Get-ComputerInfo | Select-Object OsName }
}
Comparativa: WinRM vs Remoting Basado en SSH vs OpenSSH en Windows
| Característica | WinRM (HTTP/HTTPS) | Remoting Basado en SSH (PS7) | OpenSSH en Windows |
|---|---|---|---|
| Protocolo | WS-Management | SSH | SSH |
| Puertos predeterminados | 5985 / 5986 | 22 | 22 |
| Autenticación | Kerberos, NTLM, CredSSP | Claves SSH, contraseña | Claves SSH, contraseña |
| Multiplataforma | Solo Windows | Windows, Linux, macOS | Solo Windows (servidor) |
| Versión de PowerShell | 5.1+ | 7.0+ requerido | Cualquiera (solo shell SSH) |
| Cifrado | HTTPS o a nivel de mensaje | Siempre cifrado | Siempre cifrado |
| Doble salto | CredSSP o delegación Kerberos | Reenvío de agente SSH | Reenvío de agente SSH |
| Integración con dominio | AD/Kerberos nativo | Gestión manual de claves | Gestión manual de claves |
| Gestión por GPO | Soporte completo | Limitado | Limitado |
| Ideal para | Entornos solo Windows | Entornos con SO mixto | Admins Linux gestionando Windows |
Escenario del Mundo Real
Imagina que eres un administrador de sistemas gestionando más de 50 servidores Windows en tres entornos — Desarrollo, Staging y Producción — además de un puñado de máquinas Linux ejecutando proxies inversos Nginx. Así es como estructurarías tu flujo de trabajo con PowerShell Remoting:
# Definir grupos de servidores
$servidoresDev = Get-Content "C:\ListasServidores\dev.txt"
$servidoresStaging = Get-Content "C:\ListasServidores\staging.txt"
$servidoresProd = Get-Content "C:\ListasServidores\prod.txt"
# Crear sesiones persistentes con credenciales almacenadas
$cred = Import-Clixml "$HOME\admin-cred.xml"
$sesionesDev = New-PSSession -ComputerName $servidoresDev -Credential $cred
$sesionesStaging = New-PSSession -ComputerName $servidoresStaging -Credential $cred
# Verificación de salud matutina en todos los servidores de desarrollo
$reporteSalud = Invoke-Command -Session $sesionesDev -ScriptBlock {
[PSCustomObject]@{
Servidor = $env:COMPUTERNAME
Uptime = (Get-CimInstance Win32_OperatingSystem).LastBootUpTime
CPUPorcent = (Get-CimInstance Win32_Processor).LoadPercentage
LibreGB = [math]::Round((Get-CimInstance Win32_LogicalDisk -Filter "DeviceID='C:'").FreeSpace / 1GB, 2)
Servicios = (Get-Service | Where-Object { $_.StartType -eq "Automatic" -and $_.Status -ne "Running" }).Count
}
}
$reporteSalud | Format-Table Servidor, Uptime, CPUPorcent, LibreGB, Servicios -AutoSize
# Desplegar un hotfix a staging con concurrencia limitada
Invoke-Command -Session $sesionesStaging -ThrottleLimit 5 -ScriptBlock {
Start-Process msiexec.exe -ArgumentList "/i C:\Deploy\hotfix-kb123.msi /quiet" -Wait
Write-Output "$env:COMPUTERNAME — Hotfix instalado"
}
# Verificar proxies Linux sobre SSH
$sesionesLinux = New-PSSession -HostName "proxy01","proxy02" -UserName admin -SSHTransport
Invoke-Command -Session $sesionesLinux -ScriptBlock {
systemctl is-active nginx
curl -s -o /dev/null -w "%{http_code}" http://localhost
}
Este patrón mantiene las sesiones abiertas durante la duración de tu trabajo, minimiza la sobrecarga de autenticación y te permite apuntar a grupos de entornos específicos con ejecución limitada.
Errores Comunes y Casos Especiales
- Bloqueo de firewall: WinRM usa el puerto 5985 (HTTP) y 5986 (HTTPS). Si el remoting falla silenciosamente, verifica tanto el Firewall de Windows como cualquier firewall de red entre cliente y servidor.
- Reinicio de TrustedHosts: Establecer TrustedHosts con
Set-Itemreemplaza toda la lista. Usa-Concatenatepara agregar:Set-Item WSMan:\localhost\Client\TrustedHosts -Value "NUEVOSERVIDOR" -Concatenate. - MaxMemoryPerShellMB: El límite predeterminado (1024 MB) puede causar que las sesiones se caigan durante operaciones intensivas en memoria. Auméntalo con
Set-Item WSMan:\localhost\Shell\MaxMemoryPerShellMB 2048. - Fallo de doble salto: Acceder a recursos de red desde una sesión remota falla por defecto. Usa CredSSP, delegación restringida de Kerberos o delegación restringida basada en recursos para resolver esto.
- Límites de sesión: WinRM tiene un límite predeterminado de 25 shells concurrentes por usuario. En entornos grandes, incrementa
MaxShellsPerUseren la configuración de WinRM. - Desfase de zona horaria: Las marcas de tiempo devueltas desde sesiones remotas usan la zona horaria del servidor remoto. Usa
[DateTime]::UtcNowpara consistencia en entornos multi-región. - Ruta del subsistema SSH: En Windows, la ruta del subsistema en
sshd_configdebe usar el formato de nombre corto 8.3 (progra~1) o la ruta completa sin espacios. - Límites de serialización: Los objetos devueltos desde sesiones remotas están deserializados — pierden sus métodos. Lo que regresa es una instantánea, no un objeto vivo. Planifica tus bloques de script para extraer los datos que necesitas en el lado remoto.
- Discrepancia de versión de PowerShell: Si la máquina remota ejecuta PowerShell 5.1 y el cliente ejecuta PowerShell 7, no todos los cmdlets estarán disponibles. Prueba con
-ConfigurationName PowerShell.7para endpoints de PS7.
Resumen
- Enable-PSRemoting es el comando integral para configurar WinRM en cualquier máquina Windows.
- TrustedHosts debe configurarse en el cliente para conexiones de grupo de trabajo o entre dominios.
- El transporte HTTPS debe usarse en producción para cifrar el tráfico de remoting de extremo a extremo.
- Invoke-Command es la herramienta principal para ejecución paralela en múltiples servidores; Enter-PSSession es ideal para resolución de problemas interactiva.
- La gestión de credenciales debe usar Export-Clixml, el Administrador de Credenciales o un almacén de secretos — nunca contraseñas escritas directamente en código.
- CredSSP o la delegación restringida de Kerberos resuelve el problema del doble salto.
- El remoting basado en SSH en PowerShell 7+ habilita la gestión multiplataforma de Linux y macOS desde los mismos scripts.
- Los endpoints JEA proporcionan remoting con privilegios mínimos para administración delegada.
- Ten cuidado con los límites de sesión, el comportamiento de serialización y las reglas de firewall a medida que tu entorno crece.