Introducción a PowerShell Remoting (WinRM) — Administración masiva de varios equipos Windows
· Actualizado el: · Go Komura · PowerShell, Windows, WinRM, Administración remota, Automatización, Mejora operativa, Seguridad, Scripts
«Después de aplicar Windows Update, comprueba que los 20 servidores han arrancado correctamente» o «necesito que revises cómo está ese valor de configuración en los equipos de todas las sucursales» ── ¿no está atendiendo este tipo de peticiones iniciando sesión de una en una por Escritorio remoto en cada equipo? Aunque cada equipo lleve solo 3 minutos, con 20 servidores ya son una hora. El ser humano se cansa a mitad de camino y se le escapan comprobaciones.
PowerShell Remoting es el mecanismo que convierte esa «misma tarea en varios equipos» en una sola orden. Windows incorpora de serie WinRM, la base para la administración remota, y en Windows Server viene habilitada de forma predeterminada. Es decir, en la mayoría de los entornos se puede empezar a usar hoy mismo sin instalar software adicional. Y sin embargo es habitual oír comentarios como «da un poco de miedo» o «lo intenté en un grupo de trabajo, no conseguí conectar y lo dejé».
Este artículo, dirigido al personal de sistemas y a los responsables de operaciones de pequeñas y medianas empresas, repasa el funcionamiento de Remoting (qué se ejecuta, en qué puerto y quién puede conectarse), la ejecución masiva con Invoke-Command, las diferencias entre un entorno de dominio y uno de grupo de trabajo, trampas conocidas como el problema del second hop, la manera de diagnosticar cuando «no conecta», y finalmente un uso seguro que empieza siempre por operaciones de solo lectura.
Entorno de referencia
- Equipo que recibe la conexión: en Windows Server 2012 y versiones posteriores, PowerShell Remoting está habilitado de forma predeterminada.1 En las versiones cliente de Windows, el servicio WinRM está deshabilitado de forma predeterminada, por lo que es necesario habilitarlo con Enable-PSRemoting.1
- Equipo que se conecta: los ejemplos de comandos de este artículo usan únicamente cmdlets que existen tanto en Windows PowerShell 5.1 como en PowerShell 7. No obstante, los cmdlets relacionados con WS-Management, como la unidad
WSMan:oTest-WSMan, solo están disponibles en PowerShell sobre Windows (en PowerShell para Linux o macOS se usa el Remoting basado en SSH descrito en el capítulo 6).2 - Permisos: cualquier cambio de configuración en el lado remoto (Enable-PSRemoting, TrustedHosts, agentes de escucha) requiere una sesión de PowerShell iniciada como administrador.1
- Red: se tratan tanto los entornos de dominio como los de grupo de trabajo. Las diferencias se resumen en el capítulo 3.
1. Conclusión en primer lugar
- PowerShell Remoting funciona sobre WinRM (la implementación de WS-Management) y utiliza de forma predeterminada los puertos HTTP 5985 / HTTPS 5986. Incluso por HTTP, el contenido de la comunicación se cifra a nivel de mensaje según el protocolo de autenticación.3
- De forma predeterminada, solo pueden conectarse los miembros del grupo Administrators del lado remoto, y la sesión se ejecuta en el contexto del usuario que se conectó. No es cierto que «al habilitar Remoting, cualquiera pueda entrar».3
- Lo que hace Enable-PSRemoting está claramente definido. Inicia el servicio WinRM y automatiza su arranque, crea el agente de escucha, agrega la excepción de firewall y habilita la configuración de sesión. Está habilitado de forma predeterminada en Windows Server, y hay que habilitarlo manualmente en Windows cliente.43
- Un entorno de dominio funciona directamente con Kerberos; un grupo de trabajo necesita NTLM + TrustedHosts + credenciales explícitas. TrustedHosts no es una configuración de «confiar en el otro equipo», sino una «lista que renuncia a verificar su identidad», así que hay que reducirla al mínimo.53
- Para la ejecución masiva se usa Invoke-Command, para el modo interactivo Enter-PSSession, y si se va a usar varias veces manteniendo el estado, New-PSSession. Invoke-Command procesa, de forma predeterminada, hasta 32 equipos en paralelo.67
- Lo que se recibe desde el lado remoto son objetos deserializados, que no tienen métodos. Las operaciones deben completarse dentro del ScriptBlock (en el lado remoto), y en el equipo local solo se hace la recopilación de los resultados.87
- No se puede acceder a un servidor más allá del destino de conexión (problema del second hop). No se trata de un defecto, sino de la consecuencia de un diseño seguro que no envía las credenciales al lado remoto. Existen varias soluciones, que se eligen según los requisitos.9
- Con PowerShell 7 también se puede usar Remoting basado en SSH. Es una opción cuando hace falta administrar Linux de forma conjunta, o en entornos donde no se quiere abrir WinRM.2
2. Funcionamiento ── quién entra y cómo, sobre WinRM
La base de PowerShell Remoting es WinRM (Windows Remote Management). WinRM es la implementación de Microsoft del protocolo estándar WS-Management, y PowerShell Remoting usa WinRM para hacer llegar los comandos a PowerShell en el equipo remoto.3 La comunicación utiliza, de forma predeterminada, el puerto HTTP 5985 y el puerto HTTPS 5986.35
Es habitual preocuparse pensando «¿no va en texto plano por HTTP?», pero una vez completada la autenticación inicial, WinRM cifra la comunicación. Con HTTPS se usa TLS; con HTTP se aplica el cifrado a nivel de mensaje negociado por el protocolo de autenticación (con Kerberos, en entornos actuales, AES-256).3 Además, de forma predeterminada solo pueden conectarse los miembros del grupo Administrators del lado remoto, y como la sesión se ejecuta en el contexto del usuario conectado, el control de acceso a archivos y al registro se aplica con normalidad.3
La preparación del lado receptor se hace con Enable-PSRemoting. Lo que hace este cmdlet está documentado oficialmente: internamente ejecuta Set-WSManQuickConfig y realiza (1) el inicio del servicio WinRM, (2) la configuración automática del tipo de inicio, (3) la creación de un agente de escucha que acepta solicitudes en cualquier dirección IP, (4) la habilitación de la excepción de firewall para el tráfico de WS-Management y (5) la creación y habilitación de la configuración de sesión (endpoint) junto con el permiso de acceso remoto, para finalmente reiniciar el servicio WinRM.4
# Se ejecuta una sola vez, en el equipo que "recibe" la conexión, desde PowerShell con permisos de administrador
# (En Windows Server suele no ser necesario porque ya está habilitado de forma predeterminada. Es necesario en Windows cliente)
Enable-PSRemoting
# Comprobación de conectividad desde el equipo que "se conecta" ── si esto funciona, la base de Remoting está lista
Test-WSMan -ComputerName sv-app01
Hay dos particularidades que suelen sorprender si no se conocen de antemano. La primera es el firewall. En las versiones de servidor de Windows, Enable-PSRemoting crea también una regla para la red pública que permite el tráfico «solo desde la misma subred», pero en las versiones cliente, si el perfil de red es público, la propia habilitación falla con un error (un problema clásico al conectar un equipo de pruebas al Wi-Fi de la oficina). En ese caso hay que agregar -SkipNetworkProfileCheck o cambiar el perfil a privado.4
La segunda es la relación entre la versión de PowerShell y el endpoint. Enable-PSRemoting configura el endpoint «correspondiente a la versión de PowerShell con la que se ejecutó». Si se ejecuta desde PowerShell 7, no afecta al endpoint de Windows PowerShell 5.1, y viceversa.4 Además, aunque se conecte desde PowerShell 7, de forma predeterminada se utiliza el endpoint existente de Windows PowerShell 5.1 (Microsoft.PowerShell)10, por lo que es bastante habitual encontrarse con que «en el equipo local se usa la versión 7, pero en el lado remoto en realidad se está ejecutando la 5.1». Conviene acostumbrarse a comprobarlo mostrando $PSVersionTable en el lado remoto.
3. Dominio y grupo de trabajo ── aquí está la barrera de la autenticación
El mayor obstáculo al empezar con Remoting no es la sintaxis de los comandos, sino la autenticación. Lo que hay que preparar depende del entorno.
| Elemento | Entorno de dominio | Entorno de grupo de trabajo |
|---|---|---|
| Protocolo de autenticación | Kerberos (con autenticación mutua)5 | NTLM (sin verificación de identidad del servidor)5 |
| Configuración adicional | En principio no hace falta; se conecta directamente por el nombre del equipo | Es necesario registrarlo en TrustedHosts en el lado que se conecta5 |
| Credenciales | Se usan directamente las del usuario con la sesión iniciada | Lo habitual es indicarlas explícitamente con -Credential |
| Especificar por dirección IP | Requiere registro en TrustedHosts o HTTPS11 | Igual que a la izquierda |
En un entorno de dominio funciona la autenticación mutua de Kerberos (tanto el cliente como el servidor se verifican entre sí), de modo que Invoke-Command -ComputerName sv-app01 { ... } funciona tal cual. En un grupo de trabajo no se puede usar Kerberos5, así que hay que registrar el destino en TrustedHosts en el lado que se conecta.
# Se ejecuta en el equipo "que se conecta", desde PowerShell iniciado como administrador (solo necesario en grupo de trabajo)
# Modificar TrustedHosts también requiere permisos de administrador. El valor existente se sobrescribe, así que primero se comprueba el valor actual
Get-Item WSMan:\localhost\Client\TrustedHosts
# Se agregan solo los nombres de host estrictamente necesarios. Sin -Concatenate se borran los registros existentes. Evite permitir todo con '*'
Set-Item WSMan:\localhost\Client\TrustedHosts -Value 'sv-app01,sv-app02' -Concatenate
# Prueba de conexión indicando las credenciales de forma explícita
$cred = Get-Credential sv-app01\Administrator
Invoke-Command -ComputerName sv-app01 -Credential $cred -ScriptBlock { hostname }
Aquí es importante entender qué significa realmente TrustedHosts. La documentación oficial indica explícitamente que «un equipo incluido en TrustedHosts no se autentica, y es posible que el cliente le envíe las credenciales de todos modos».5 Es decir, más que una «lista de equipos de confianza», se trata de una «lista que suprime la advertencia de que no se puede verificar la identidad del servidor».3 En un entorno donde el DNS o el ARP han sido manipulados, existe el riesgo de entregar credenciales de administrador a un servidor falso. Por eso conviene evitar los registros con comodines y limitarse a un número mínimo de nombres de host o direcciones IP fijas. En entornos de grupo de trabajo o DMZ de uso serio, el criterio práctico es que resulta mejor preparar un certificado y configurar un agente de escucha HTTPS (5986).3
Dicho esto, en cuanto empiece a escribir en texto plano dentro de un script las credenciales obtenidas con Get-Credential, es una señal de alerta. Las prácticas recomendadas para almacenar y pasar credenciales se resumen en el artículo publicado simultáneamente «Cómo manejar credenciales de forma segura en PowerShell».
En los grupos de trabajo hay otro detalle que se pasa por alto fácilmente: si a la cuenta del equipo de destino no se le ha configurado ninguna contraseña (contraseña en blanco), no se pueden ejecutar comandos remotos.1
3.1. Configurar un agente de escucha HTTPS (5986)
Si se va a usar de forma habitual en un grupo de trabajo o en una DMZ, en lugar de conformarse con TrustedHosts conviene levantar un agente de escucha HTTPS. El esquema general del procedimiento es el siguiente.12
- Preparar un certificado de autenticación de servidor. Los requisitos son: «ser un certificado de autenticación de servidor del equipo local», «que el CN (o el nombre alternativo del firmante) coincida con el nombre de host» y «que esté dentro del período de validez, no esté revocado y no sea autofirmado». Si existe una CA interna, puede solicitarse desde el registro web en
https://<servidor de la entidad certificadora>/certsrv. - Colocar el certificado en el almacén Personal del equipo local. Para comprobarlo, use el complemento de certificados (agregue «Certificados» en MMC y, en el asistente, seleccione «Cuenta de equipo»): Certificados (equipo local) > Personal > Certificados.
-
Crear el agente de escucha HTTPS. La forma más rápida es esta línea:
winrm quickconfig -transport:httpsSi hay varios certificados y quiere indicar explícitamente cuál usar, también puede crearlo desde PowerShell especificando la huella digital (puede consultarla con
Get-ChildItem Cert:\LocalMachine\My):New-Item -Path WSMan:\localhost\Listener -Address * -Transport HTTPS -CertificateThumbPrint 'huella digital del certificado' -Force - Permitir en el firewall el tráfico entrante por TCP 5986. La regla que crea Enable-PSRemoting es para HTTP (5985), así que para HTTPS hay que agregarla aparte.
-
Comprobar que el agente de escucha se ha creado.
winrm enumerate winrm/config/listener
En el lado que se conecta basta con agregar -UseSSL.
Invoke-Command -ComputerName sv-app01.example.local -UseSSL -Credential $cred -ScriptBlock { hostname }
Si el certificado no cumple los requisitos, al crear el agente de escucha aparece el error «Cannot create a WinRM listener on HTTPS because this machine does not have an appropriate certificate. (código de error -2144108267 / 0x80338115)». En ese caso, revise en orden la fecha de caducidad del certificado, si el emisor para coincide con el nombre de host, si el uso mejorado de claves incluye «Autenticación de servidor» y si la ruta de certificación es válida.12
4. Invoke-Command ── la forma básica de «hacer lo mismo en 20 equipos»
El protagonista de Remoting es Invoke-Command. Se pasan varios equipos en -ComputerName y se escribe en -ScriptBlock «lo que se va a hacer en remoto».6 La regla de oro de un uso seguro es empezar siempre con un inventario de solo lectura.
$servers = 'sv-app01', 'sv-app02', 'sv-db01'
# Comprobación del estado tras aplicar parches ── es solo lectura, así que se puede ejecutar sin preocupación
$result = Invoke-Command -ComputerName $servers -ScriptBlock {
# El contenido de este bloque se ejecuta en el "lado remoto"
$os = Get-CimInstance Win32_OperatingSystem
[PSCustomObject]@{
LastBoot = $os.LastBootUpTime # Si ya se completó el reinicio
SpoolerRun = (Get-Service -Name Spooler).Status # Estado del servicio necesario para el negocio
FreeGB = [math]::Round((Get-PSDrive C).Free / 1GB, 1)
}
}
# PSComputerName indica a qué servidor pertenece cada resultado
$result | Sort-Object PSComputerName |
Select-Object PSComputerName, LastBoot, SpoolerRun, FreeGB |
Export-Csv -Path .\patch-check.csv -NoTypeInformation -Encoding UTF8
Las conexiones a cada servidor se procesan en paralelo, y el número de ejecuciones simultáneas predeterminado (ThrottleLimit) es 32.7 Los resultados llegan mezclados en el orden en que se reciben, así que, como en el ejemplo anterior, hay que reordenarlos usando la propiedad PSComputerName que se agrega automáticamente.8
4.1. Cómo pasar variables ── $using: y -ArgumentList
Como el ScriptBlock se ejecuta en remoto, las variables locales no son visibles tal cual. Hay dos formas de introducir valores.13
$threshold = (Get-Date).AddDays(-30)
# Método 1: $using: ── incrusta en el lado remoto una "copia del valor" de la variable del lado que llama
Invoke-Command -ComputerName $servers -ScriptBlock {
(Get-ChildItem 'D:\AppLogs' -Filter *.log |
Where-Object LastWriteTime -lt $using:threshold).Count
}
# Método 2: -ArgumentList ── se recibe mediante param en el ScriptBlock (más legible cuando hay muchos argumentos)
Invoke-Command -ComputerName $servers -ScriptBlock {
param($limit)
(Get-ChildItem 'D:\AppLogs' -Filter *.log |
Where-Object LastWriteTime -lt $limit).Count
} -ArgumentList $threshold
El valor que se pasa con $using: es una copia independiente en el lado remoto. Aunque se modifique en el lado remoto, la variable local no cambia.13
4.2. Lo que se recibe es una «instantánea» ── objetos deserializados
Esto es lo primero que suele desconcertar de los resultados de Remoting. Un objeto .NET vivo no puede cruzar la red, así que la salida remota se serializa a XML (CLIXML) para enviarse, y en el equipo local se reconstruye como un objeto deserializado. Se trata de una instantánea de las propiedades en el momento de la ejecución, y no tiene métodos.87
Por ejemplo, no se puede recibir el resultado de Get-Service en el equipo local e invocar .Stop() sobre él. Si se quiere detener el servicio, hay que ejecutar Stop-Service dentro del ScriptBlock; es decir, la forma correcta consiste en separar los roles: la operación se completa por completo en el lado remoto, y lo único que se lleva de vuelta al equipo local son los datos para el informe. El procesamiento local, como seleccionar propiedades, dar formato o exportar a CSV, se puede hacer con la misma sensación que en un uso habitual de PowerShell (para las operaciones básicas al respecto, consulte «Fundamentos de los comandos de PowerShell»).
5. Enter-PSSession y New-PSSession ── modo interactivo y reutilización
Cuando se quiere investigar un solo equipo de forma interactiva, se usa Enter-PSSession. El símbolo del sistema cambia a [sv-app01]: PS> y los comandos que se escriben se ejecutan en remoto. Se sale con exit.11 A diferencia del Escritorio remoto, no se trae la pantalla, pero para algo como «revisar un registro» o «comprobar una configuración» resulta más rápido; y, al igual que antes, para conectarse también hace falta ser miembro del grupo Administrators.11
Por otro lado, cada vez que se llama a Invoke-Command con -ComputerName, se establece y se cierra la conexión en cada ejecución.14 En trabajos de investigación en los que se envían comandos repetidamente al mismo grupo de servidores, resulta más rápido crear una sesión persistente con New-PSSession y reutilizarla, y además las variables y el estado del lado remoto se mantienen entre comandos.1415
# Se establece la sesión una sola vez y se reutiliza a través de la variable $s
$s = New-PSSession -ComputerName $servers
try {
# Primera vez: se crea en el lado remoto una variable llamada $hotfix
Invoke-Command -Session $s { $hotfix = Get-HotFix | Sort-Object InstalledOn -Descending }
# Segunda vez: se puede usar tal cual la variable creada en el comando anterior (la sesión mantiene el estado)
Invoke-Command -Session $s { $hotfix | Select-Object -First 5 }
}
finally {
# Se libera siempre, incluso si hay un error o una interrupción a mitad de camino (libera los recursos del lado remoto)
Remove-PSSession $s
}
6. Trampas habituales ── el second hop y la alternativa SSH
6.1. El problema del second hop (doble salto)
Este es el obstáculo más conocido en la práctica. Se entra por Remoting desde el equipo local (A) al servidor B, y al intentar leer \\fs01\share (servidor C) desde dentro de B, se obtiene acceso denegado. La autenticación Kerberos/NTLM predeterminada es un método seguro que no envía las credenciales en sí mismas a B, así que B no puede autenticarse ante C en representación del usuario.39
Existen varias soluciones, y la documentación oficial las organiza en orden de recomendación.9 A continuación se enumeran las principales.
- Pasar las credenciales de forma explícita dentro del ScriptBlock ── no requiere cambios de configuración en el servidor y es la opción más sencilla. Se pasan las credenciales al Invoke-Command interior mediante
$using:cred.9 Sin embargo, dado que el objeto de credenciales se transfiere a la sesión del servidor intermedio (B), si B estuviera comprometido, las credenciales entregadas también podrían usarse; por eso esta opción se debe limitar a los casos en los que se confía plenamente en B, y además la cuenta que se pasa debe ser una cuenta dedicada con los permisos mínimos necesarios en el lado de C. - Delegación restringida de Kerberos basada en recursos ── un método que no almacena credenciales y se configura en el lado del recurso de acceso (C) para «aceptar la delegación desde B». Se puede configurar sin permisos de administrador de dominio y es una opción con buen equilibrio entre seguridad y facilidad de configuración.9
- JEA (Just Enough Administration) ── un mecanismo de PowerShell que restringe los permisos preparando un endpoint dedicado que solo permite «los comandos necesarios para esa tarea concreta». Configurándolo con una cuenta virtual, el usuario puede conectarse con credenciales que no son de administrador y ejecutar únicamente los comandos administrativos autorizados.16 En el contexto del second hop, en lugar de repartir credenciales de administrador al servidor intermedio (B), se crea una ventanilla que solo puede ejecutar las tareas rutinarias que incluyen el acceso a C.9
- CredSSP ── las credenciales se almacenan en caché en el servidor remoto, por lo que, si ese servidor se ve comprometido, las credenciales se roban junto con él. Está deshabilitado de forma predeterminada, y su habilitación debe limitarse a los entornos más fiables.9
# La solución más sencilla: pasar las credenciales con $using:cred al Invoke-Command interior
# Al servidor exterior (sv-app01) se conecta con las credenciales propias, y lo que se pasa
# al interior es únicamente una cuenta dedicada con los permisos mínimos necesarios en fs01
# (no se reparten credenciales de administrador)
#
# [Requisito previo] La llamada interior es "una nueva conexión de Remoting de sv-app01 a fs01", así que hace falta:
# 1. Que WinRM (5985/5986) sea alcanzable desde sv-app01 hacia fs01
# 2. En grupo de trabajo o con IP, que fs01 ya esté registrado en TrustedHosts en el lado de sv-app01
# 3. Que $cred sea una cuenta válida en fs01 (una cuenta de dominio, o una cuenta local de fs01)
# Si se copia y pega sin comprobar esto, es habitual que "funcione en el equipo local pero falle desde el servidor intermedio"
$cred = Get-Credential CONTOSO\svc-fileread
Invoke-Command -ComputerName sv-app01 -ScriptBlock {
Invoke-Command -ComputerName fs01 -Credential $using:cred -ScriptBlock { hostname }
}
Antes que nada, la solución más económica es plantearse si, en lugar de «leer los archivos de C pasando por B», no se puede diseñar el flujo para ejecutar Invoke-Command directamente contra C desde el equipo local.
6.2. Con PowerShell 7 también se puede optar por Remoting basado en SSH
A partir de PowerShell 6.0 se puede usar Remoting conectando por SSH en lugar de WinRM. Se han agregado a Invoke-Command, Enter-PSSession y New-PSSession los conjuntos de parámetros -HostName, -UserName y -KeyFilePath para SSH, lo que permite administrar tanto Windows como Linux.2 En el destino hace falta un servidor SSH y el subsistema SSH de PowerShell configurado, y por ahora no se admiten funciones como la configuración de endpoints o JEA propias de WinRM.2 Conviene tenerlo presente como opción en entornos con servidores Linux mezclados, o cuando se quiera unificar la operación con autenticación por clave. Windows PowerShell 5.1 no tiene esta función, así que si se necesita, puede ser un motivo para migrar (para una visión general de las diferencias, consulte el artículo publicado simultáneamente «Diferencias entre Windows PowerShell 5.1 y PowerShell 7»).
Por cierto, una sesión de Remoting no crea una sesión de escritorio como el RDP. La diferencia entre lo que significa «ejecutarse en remoto» en uno y otro caso se explica en «Cómo entender la separación de sesiones en Windows».
7. Cómo diagnosticar cuando no hay conexión
La mayoría de los principiantes abandonan Remoting porque «no consigue conectar». Y el origen del fallo puede estar en cualquier punto: el servicio, el agente de escucha, el firewall, la autenticación o los permisos. Si se van descartando causas de arriba abajo, no hay lugar para la confusión.
7.1. Orden de diagnóstico
- Comprobar la conectividad. Primero, desde el lado que se conecta, ejecute
Test-WSMan -ComputerName sv-app01. Si esto funciona, el servicio WinRM, el agente de escucha y el firewall están operativos (aunque puedan quedar problemas de autenticación o permisos). Si no funciona, continúe con los siguientes puntos. - Comprobar si el servicio WinRM está en ejecución en el lado remoto. En las versiones de servidor el tipo de inicio es automático, pero en las versiones cliente de Windows el servicio WinRM está deshabilitado de forma predeterminada.1 Compruébelo con
Get-Service WinRMy, si hace falta, ejecuteEnable-PSRemoting(que configura de una vez el inicio del servicio, el arranque automático, el agente de escucha, la excepción de firewall y la configuración de sesión).4 -
Comprobar si el agente de escucha está a la espera. Ejecute lo siguiente en el lado remoto y verifique que
ListeningOnno esté vacío. Si está vacío, lo habitual es que se trate de un error de configuración en entornos donde el agente de escucha se distribuye por directiva de grupo.1Get-WSManInstance winrm/config/listener -Enumerate - Revisar el perfil de red. En las versiones cliente, si la red es pública, la propia ejecución de
Enable-PSRemotingfalla con «Unable to check the status of the firewall». Cambie el perfil a privado o agregue-SkipNetworkProfileCheck.1 - Revisar las reglas de firewall. Incluso en versiones de servidor, con el perfil público la regla queda como «solo se permite desde la misma subred». Si se va a entrar desde otra subred, hay que revisar la regla (compruebe el nombre de la regla con
Get-NetFirewallRuleantes de modificarla; el nombre varía según la versión de Windows).1 - Comprobar si se cumplen las condiciones del método de autenticación. En grupo de trabajo, sin unirse a un dominio o al especificar por dirección IP, no se puede usar Kerberos y se pasa a NTLM, por lo que son obligatorios el registro en TrustedHosts (o HTTPS) y la indicación explícita de
-Credential. No se puede usar una cuenta de destino con la contraseña en blanco.1 - Comprobar si se dispone de permisos para conectarse. Solo los miembros del grupo Administrators del lado remoto pueden conectarse al endpoint predeterminado. Los usuarios de otro dominio o las cuentas locales reciben, de forma predeterminada, un token de usuario estándar, por lo que no pueden actuar como administradores (si es necesario, existe
LocalAccountTokenFilterPolicy, pero es una configuración que deshabilita la restricción remota del UAC para todos los usuarios, así que hay que entender bien su impacto antes de usarla).1 - Comprobar la versión de PowerShell del endpoint. Si se conecta pero se indica que «ese cmdlet no existe», como se explicó en el capítulo 2, es posible que haya entrado en el endpoint de Windows PowerShell 5.1. Compruébelo con
Invoke-Command -ComputerName sv-app01 { $PSVersionTable.PSVersion }y, si hace falta, indíquelo explícitamente con-ConfigurationName.10
7.2. Cómo interpretar los mensajes de error más habituales
Los mensajes de error son bastante estandarizados, así que, más que memorizarlos, resulta práctico asociar «si aparece este texto, revise aquí».1
| Mensaje de error (extracto) | Causa habitual | Dónde revisar primero |
|---|---|---|
Access is denied. You need to run this cmdlet from an elevated process. |
La PowerShell local no tiene permisos de administrador | Vuelva a abrirla con «Ejecutar como administrador» |
ACCESS IS DENIED |
Remoting deshabilitado en el destino / el usuario que se conecta no es Administrators / restricción de token de un administrador de otro dominio o local | Ejecute Enable-PSRemoting en el destino, indique un administrador con -Credential y, si hace falta, revise los permisos de la configuración de sesión o LocalAccountTokenFilterPolicy |
The connection to the remote host was refused. Verify that the WS-Management service is running on the remote host and configured to listen for requests on the correct port and HTTP URL. |
El servicio WinRM está detenido, no hay agente de escucha, o el puerto es incorrecto | Get-Service WinRM, enumerar el agente de escucha, revisar la configuración del puerto |
The client cannot connect to the destination specified in the request. Verify that the service on the destination is running and is accepting requests. |
El ListeningOn del agente de escucha está vacío (error de directiva) o influencia de un proxy | Enumerar el agente de escucha, revisar la configuración de proxy de New-PSSessionOption |
The WinRM client cannot process the request. If the authentication scheme is different from Kerberos, or if the client computer is not joined to a domain, then HTTPS transport must be used or the destination machine must be added to the TrustedHosts configuration setting. |
Grupo de trabajo, sin unirse a un dominio, o especificación por dirección IP | Registro en TrustedHosts + -Credential, o la configuración HTTPS del apartado 3.1 |
Unable to check the status of the firewall(al ejecutar Enable-PSRemoting) |
Red pública en una versión cliente | Cambiar el perfil a privado, o usar -SkipNetworkProfileCheck |
The WS-Management service cannot complete the operation within the time specified in OperationTimeout. |
El proceso tarda demasiado, o el equipo remoto tiene una carga alta | Ampliarlo con New-PSSessionOption -OperationTimeout |
The total data received from the remote client exceeded allowed maximum. |
Los datos devueltos son demasiado grandes | Agregue y filtre los datos dentro del ScriptBlock antes de devolverlos; ajuste la cuota si hace falta |
La clave del diagnóstico es ir determinando, uno por uno, si el problema está «en el equipo local, en la ruta de red o en el equipo remoto». Si Test-WSMan funciona o no, permite descartar la ruta y el servicio del lado remoto; los errores que aparecen después de que funcione se centran en la autenticación y los permisos. Con este planteamiento en dos etapas, se evita andar cambiando configuraciones sin saber cuál es la causa.
8. Reglas prácticas de uso (tabla de decisión)
| Punto a decidir | Opciones | Criterio de decisión |
|---|---|---|
| Investigar un equipo de forma interactiva | RDP / Enter-PSSession | RDP si hace falta pantalla; Enter-PSSession es más ligero si basta con comandos11 |
| Aplicar el mismo proceso a varios equipos | Trabajo manual equipo por equipo / Invoke-Command | Con más de 3 equipos, use Invoke-Command; en paralelo hasta 32 equipos de forma predeterminada67 |
| Enviar comandos repetidamente | Conectar cada vez con -ComputerName / Reutilizar New-PSSession | Reutilice la sesión si va a ir y venir interactivamente durante la investigación; libérela con Remove-PSSession al terminar14 |
| Autenticación en grupo de trabajo | TrustedHosts (HTTP) / Agente de escucha HTTPS | Para uso puntual, TrustedHosts mínimo; para uso habitual, configure HTTPS (procedimiento en el apartado 3.1)5312 |
| Solución al second hop | Pasar las credenciales de forma explícita / delegación basada en recursos / CredSSP | Primero, el paso explícito, que no requiere cambios de configuración; si es permanente, la delegación basada en recursos. CredSSP es el último recurso9 |
| Primer comando a ejecutar | De cambio / De lectura | Empiece siempre por un inventario con comandos Get. Los comandos de cambio, ensáyelos primero con comandos compatibles con -WhatIf antes de ejecutarlos de verdad |
Conviene subrayar la última fila. Invoke-Command es, al mismo tiempo, «el comando que arregla 20 equipos en un instante» y «el comando que rompe 20 equipos en un instante». Por suerte, muchos cmdlets de cambio, como Stop-Service o Set-ItemProperty, son compatibles con -WhatIf, y se pueden usar tal cual dentro del ScriptBlock. Si convierte en costumbre probar cualquier script nuevo primero en un solo equipo, después en todos con -WhatIf, y solo al final ejecutarlo de verdad, la tasa de incidentes baja de forma notable.
9. Resumen
- Remoting funciona sobre WinRM (WS-Management), y los puertos predeterminados son HTTP 5985 y HTTPS 5986. De forma predeterminada solo pueden conectarse los miembros del grupo Administrators del lado remoto, y la comunicación se cifra tras la autenticación.
- Enable-PSRemoting inicia el servicio WinRM, crea el agente de escucha, habilita la excepción de firewall y activa la configuración de sesión. Tenga en cuenta que el endpoint que se configura corresponde a la versión de PowerShell con la que se ejecutó.
- En un dominio funciona directamente con Kerberos; en un grupo de trabajo hacen falta TrustedHosts y credenciales explícitas. Como TrustedHosts es una lista que renuncia a la verificación de identidad, manténgala al mínimo.
- Para la ejecución masiva, Invoke-Command (32 en paralelo de forma predeterminada); para el modo interactivo, Enter-PSSession; y si hay que mantener el estado, reutilizar New-PSSession. Como los resultados son objetos deserializados sin métodos, las operaciones deben completarse en el lado remoto.
- No se puede llegar más allá del destino de conexión (second hop). Considere primero el paso explícito de credenciales, y para un uso permanente, la delegación restringida de Kerberos basada en recursos.
- Cuando «no conecta», use Test-WSMan para descartar la ruta y el servicio remoto, y luego céntrese en la autenticación (TrustedHosts, credenciales) y los permisos (Administrators). Los mensajes de error más habituales y dónde revisarlos se resumen en la tabla del capítulo 7.
- La operación debe empezar siempre por lo de solo lectura. Los cambios, en tres etapas: un equipo → -WhatIf → ejecución real. Para un ejemplo concreto aplicado al inventario de un servidor de archivos, consulte el artículo publicado simultáneamente «PowerShell para hacer inventario de un servidor de archivos».
Artículos relacionados
- Fundamentos de los comandos de PowerShell — las operaciones que hay que aprender primero y su uso seguro
- Recetario práctico de comandos de PowerShell — ampliando las pequeñas funciones que se usan a diario
- Cómo hacer inventario de un servidor de archivos con PowerShell — análisis de capacidad y auditoría de permisos (ACL)
- Cómo manejar credenciales de forma segura en PowerShell
- Cómo entender la separación de sesiones en Windows — Session 0, RDP y ejecución simultánea multiusuario
- Cómo manejar correctamente los tokens de suplantación en Windows — préstamo de permisos por hilo y cómo revertirlo de forma segura
Áreas de consultoría relacionadas
KomuraSoft LLC se ocupa de diseñar mecanismos de administración masiva de servidores y clientes con PowerShell, del diseño y la revisión de scripts operativos que incorporan Remoting, y de investigar problemas relacionados con WinRM y la autenticación, como «no conecta» o «falla la autenticación solo en un entorno concreto».
- Consultoría técnica y revisión de diseño
- Investigación de fallos y análisis de causas
- Desarrollo de aplicaciones para Windows
- Contacto
Referencias
-
Microsoft Learn, about_Remote_Troubleshooting. Sobre que Remoting está habilitado de forma predeterminada en Windows Server 2012 y versiones posteriores, que el servicio WinRM está deshabilitado de forma predeterminada en las versiones cliente de Windows, que modificar la configuración de la unidad WSMan: requiere permisos de administrador, los mensajes de error más habituales (Access is denied, conexión rechazada, Unable to check the status of the firewall, errores del cliente WinRM relacionados con TrustedHosts y HTTPS, tiempo de espera agotado, cuota superada) y cómo tratarlos, la enumeración del agente de escucha con Get-WSManInstance y los errores de directiva que dejan ListeningOn vacío, el comportamiento de las reglas de firewall en redes públicas, que en grupo de trabajo no se pueden usar cuentas con contraseña en blanco, y la restricción de token para administradores de otro dominio o cuentas locales junto con LocalAccountTokenFilterPolicy. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11
-
Microsoft Learn, PowerShell remoting over SSH. Sobre que a partir de PowerShell 6 se puede usar Remoting basado en SSH, que se han añadido los conjuntos de parámetros -HostName/-UserName/-KeyFilePath a New-PSSession/Enter-PSSession/Invoke-Command, que funciona en múltiples plataformas, y que por ahora no se admiten la configuración de endpoints ni JEA. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Security Considerations for PowerShell Remoting using WinRM. Sobre el hecho de que Remoting usa WinRM (la implementación de Microsoft de WS-Management), que los puertos predeterminados son HTTP 5985 / HTTPS 5986, que de forma predeterminada solo pueden conectarse los miembros del grupo Administrators y la sesión se ejecuta en el contexto del usuario, que la comunicación se cifra tras la autenticación, que TrustedHosts no es más que una lista que suprime el error de verificación de identidad, y el trasfondo del problema del second hop. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 ↩12
-
Microsoft Learn, Enable-PSRemoting. Sobre la lista de operaciones que realiza Enable-PSRemoting (inicio y automatización del arranque del servicio WinRM, creación del agente de escucha, excepción de firewall, habilitación de la configuración de sesión y cambio del descriptor de seguridad), que está habilitado de forma predeterminada en Windows Server, las restricciones en la red pública de las versiones cliente y SkipNetworkProfileCheck, y que se configura el endpoint correspondiente a la versión con la que se ejecutó. ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, Installation and configuration for Windows Remote Management. Sobre que los puertos del agente de escucha predeterminados de WinRM 2.0 son 5985/5986, que se selecciona Kerberos para las cuentas de dominio y NTLM para las cuentas locales, que Kerberos no se puede usar en grupos de trabajo y solo funciona en dominios, y que los equipos de TrustedHosts no se autentican y pueden recibir las credenciales, por lo que conviene mantener la lista al mínimo. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8
-
Microsoft Learn, Invoke-Command. Sobre que Invoke-Command puede ejecutar comandos en varios equipos con un solo comando, la diferencia entre la conexión temporal con -ComputerName y el uso de una PSSession con -Session, y parámetros como -ArgumentList o -FilePath. ↩ ↩2 ↩3
-
Microsoft Learn, PowerShell Remoting FAQ. Sobre que el número de conexiones simultáneas predeterminado es 32 y se puede cambiar con el parámetro ThrottleLimit, que la salida de los comandos remotos se serializa a CLIXML y se devuelve como un objeto deserializado (sin métodos), y que los resultados de Invoke-Command incorporan propiedades para identificar su origen. ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, about_Remote_Output. Sobre que la salida de los comandos remotos, tras pasar por la serialización y deserialización, se convierte en una instantánea de solo propiedades, y que los resultados se devuelven en el orden en que llegan, por lo que se reordenan mediante PSComputerName. ↩ ↩2 ↩3
-
Microsoft Learn, Making the second hop in PowerShell Remoting. Sobre el escenario del problema del second hop, la lista de soluciones y su orden de recomendación (CredSSP, delegación restringida de Kerberos basada en recursos, JEA, etc.), que CredSSP almacena en caché las credenciales en el lado remoto y por eso conlleva riesgo en caso de compromiso y está deshabilitado de forma predeterminada, y un ejemplo de cómo pasar credenciales mediante $Using:cred dentro de un ScriptBlock. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8
-
Microsoft Learn, Migrating from Windows PowerShell 5.1 to PowerShell 7. Sobre que, en entornos donde WinRM está habilitado, PowerShell 7 se conecta de forma predeterminada usando el endpoint existente de Windows PowerShell 5.1 (Microsoft.PowerShell), y que para crear el endpoint propio de PowerShell 7 hay que ejecutar Enable-PSRemoting. ↩ ↩2
-
Microsoft Learn, Enter-PSSession. Sobre que Enter-PSSession inicia una sesión interactiva con un único equipo remoto, que se termina con exit/Exit-PSSession, que hace falta ser miembro del grupo Administrators del lado remoto, y que al especificar por dirección IP se requiere configuración HTTPS o registro en TrustedHosts. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, How to configure WINRM for HTTPS (KB 2019527). Sobre los requisitos del certificado necesario para el agente de escucha HTTPS (certificado de autenticación de servidor del equipo local, CN que coincida con el nombre de host, no caducado, no revocado y no autofirmado), el procedimiento de comprobación con el complemento de certificados, la configuración mediante winrm quickconfig -transport:https, la comprobación con winrm enumerate winrm/config/listener, los puertos HTTP 5985/HTTPS 5986 desde Windows 7 en adelante, y el error 0x80338115 que aparece cuando no hay un certificado adecuado, junto con los atributos del certificado que hay que revisar. ↩ ↩2 ↩3
-
Microsoft Learn, about_Remote_Variables. Sobre el modificador de ámbito $using: para usar variables locales en comandos ejecutados en remoto, que el valor se pasa como una copia independiente en la sesión remota, y que la serialización hace que se pierdan los métodos. ↩ ↩2
-
Microsoft Learn, New-PSSession. Sobre que New-PSSession crea una conexión persistente (PSSession), que se usa para ejecutar varios comandos que comparten datos, que al indicar -ComputerName se crea una conexión temporal que se cierra tras cada comando, y que también admite conexiones basadas en SSH. ↩ ↩2 ↩3
-
Microsoft Learn, Running Remote Commands. Sobre la ejecución de archivos de script con Invoke-Command (-FilePath), y que en una sesión persistente creada con New-PSSession el estado, como las variables, se mantiene entre comandos. ↩
-
Microsoft Learn, Overview of Just Enough Administration (JEA). Sobre que JEA es una tecnología de seguridad que permite la administración delegada de lo que se gestiona con PowerShell, que se puede limitar qué cmdlets, funciones y comandos externos se pueden ejecutar, que las cuentas virtuales o las cuentas de servicio administradas por grupo permiten reducir el número de cuentas de administrador, y que las transcripciones y los registros permiten conocer lo que se ha ejecutado. ↩
Artículos relacionados
Artículos recientes con las mismas etiquetas para profundizar en temas cercanos.
El manejo seguro de credenciales en PowerShell — Cómo desterrar las contraseñas en texto plano de los scripts
Organiza el procedimiento para migrar las contraseñas en texto plano de scripts de PowerShell a un almacenamiento seguro: SecureString, D...
Directiva de ejecución de PowerShell y firma de scripts — Guía práctica para dejar de "tapar con Bypass"
La directiva de ejecución de PowerShell es un dispositivo de seguridad, no un límite de seguridad. Repasamos RemoteSigned, los ámbitos, M...
Dónde mirar cuando un script de PowerShell es lento — claves de arrays, pipeline y cruces de datos
Analizamos las causas típicas de la lentitud en PowerShell: += en arrays, pipeline vs. foreach, cruces con tablas hash, E/S de archivos y...
Deje de usar Write-Host — Flujos de salida de PowerShell y diseño de registros
Explica los seis flujos de salida de PowerShell, los problemas de Write-Host y su uso correcto, por qué se contamina el valor de retorno ...
Procesamiento paralelo en PowerShell — Cuándo usar ForEach-Object -Parallel y cuándo usar jobs
Diferencias entre ForEach-Object -Parallel, Start-ThreadJob y Start-Job, uso de $using:, ThrottleLimit y cuándo el paralelismo resulta má...
Temas relacionados
Estas páginas sitúan el tema en un contexto más amplio de servicios y decisiones.
Temas técnicos de Windows
Portal sobre desarrollo de Windows, investigación de fallos y aprovechamiento de activos existentes.
Servicios relacionados con este tema
El artículo está directamente relacionado con los siguientes servicios.
Desarrollo de aplicaciones para Windows
Aplicaciones empresariales, integración de dispositivos y herramientas de comunicación, de los requisitos al desarrollo.
Preguntas frecuentes
Preguntas habituales en las consultas sobre el tema del artículo.
- ¿Qué ocurre al ejecutar Enable-PSRemoting?
- Internamente se ejecuta Set-WSManQuickConfig, lo que inicia el servicio WinRM y automatiza su arranque, crea un agente de escucha (listener) que acepta solicitudes en cualquier dirección IP, habilita la excepción de firewall para el tráfico de WS-Management, y activa la configuración de sesión (endpoint) además de modificar los permisos de acceso remoto. En Windows Server está habilitado de forma predeterminada, pero en las versiones cliente de Windows es necesario ejecutarlo manualmente. Solo se requiere en el lado que recibe la conexión; en el lado que se conecta no hace falta ejecutarlo.
- ¿Qué se necesita para usar PowerShell Remoting en un entorno de grupo de trabajo (sin dominio)?
- Sin dominio no se puede usar la autenticación Kerberos, por lo que se recurre a NTLM. La forma básica consiste en registrar, desde el equipo que se conecta, el destino en la lista TrustedHosts de WSMan y pasar las credenciales explícitamente con -Credential. Sin embargo, un equipo incluido en TrustedHosts no se autentica (no se verifica su identidad) antes de enviarle las credenciales, por lo que conviene registrar únicamente los nombres de host estrictamente necesarios en lugar de usar comodines, y valorar, si es posible, configurar un agente de escucha HTTPS (5986).
- ¿Por qué no se pueden invocar métodos en los objetos que devuelve Invoke-Command?
- Porque la salida del comando remoto se serializa a XML (CLIXML) para poder enviarse por la red, y en el equipo local se reconstruye como un objeto deserializado. Se trata de una instantánea de las propiedades en el momento de la ejecución, no de un objeto vivo, por lo que no dispone de métodos. Operaciones como detener un servicio no deben invocarse como método en el lado local; hay que ejecutarlas dentro del ScriptBlock (en el lado remoto).
- ¿Qué es el problema del second hop (doble salto)?
- Es el problema que se produce cuando, desde el equipo A se entra por Remoting al servidor B, y desde B se intenta acceder a un tercer servidor C (por ejemplo, un servidor de archivos), quedando la conexión denegada. La autenticación Kerberos/NTLM predeterminada no envía las credenciales en sí mismas a B, por lo que B no puede autenticarse ante C en representación del usuario. Como solución existen varias opciones, que se eligen según los requisitos: pasar las credenciales de forma explícita dentro del ScriptBlock, la delegación restringida de Kerberos basada en recursos, o CredSSP (que aumenta el riesgo porque las credenciales se transfieren al lado remoto).
- ¿Puede conectarse cualquiera a PowerShell Remoting?
- No. De forma predeterminada, solo pueden conectarse los miembros del grupo Administrators del equipo remoto. Además, la sesión establecida se ejecuta en el contexto del usuario que se conectó, por lo que el control de acceso del sistema operativo se aplica con normalidad. Aun así, se trata de una puerta de entrada muy potente para los administradores, así que conviene combinarlo con varias capas de defensa: revisar las reglas de firewall, usar un agente de escucha HTTPS y limitar el acceso solo a los administradores estrictamente necesarios.
Perfil del autor
Página de presentación del autor del artículo.
Go Komura
Representante de KomuraSoft LLC
Especializado en desarrollo de software para Windows, consultoría técnica e investigación de fallos, sobre todo en proyectos con sistemas existentes y errores difíciles de reproducir.