Cómo ejecutar comandos o scripts de PowerShell en computadoras remotas mediante Invoke-Command

Si alguna vez has intentado ejecutar comandos remotos en PowerShell y te has encontrado con obstáculos, probablemente seas muy frustrante. El cmdlet Invoke-Command es realmente muy útil para ejecutar scripts o comandos de forma remota, pero solo funciona si WinRM (Administración remota de Windows) está configurado correctamente. Normalmente, los problemas se producen porque WinRM no está habilitado en el equipo de destino o porque los firewalls bloquean las solicitudes entrantes. Configurarlo correctamente puede parecer un juego de azar, sobre todo si no estás familiarizado con los comandos exactos o la ruta para cambiar los perfiles de red o las reglas del firewall. Esta guía explica cómo habilitar WinRM correctamente, garantizar que tu red esté configurada para la administración remota y, posteriormente, cómo ejecutar comandos en sistemas remotos sin complicaciones.

Cómo habilitar PowerShell Remoting (WinRM) en Windows

Habilitar el servicio WinRM: algo imprescindible para que los comandos remotos funcionen

¿Cuál es la razón principal por la que Invoke-Command no se conecta? WinRM no está habilitado o no está configurado con las reglas de red correctas. Primero, necesita que el servicio WinRM esté ejecutándose y configurado. Para comprobar si WinRM ya está ejecutándose y escuchando, ejecute esto en PowerShell en el equipo de destino:

Get-Service -Name "*WinRM*" | fl WinRM, State Get-Item wsman:\localhost\Listener 

Si no está configurado, no te preocupes. En la máquina de destino, ejecuta:

winrm quickconfig

Este comando realiza varias funciones: inicia el servicio WinRM, lo configura para que se inicie automáticamente, crea un agente de escucha predeterminado y agrega excepciones al firewall. A veces, basta con ejecutarlo Enable-PSRemoting -Forcedentro de PowerShell como administrador, especialmente si intenta hacerlo de forma remota o mediante scripts. Tenga en cuenta que, en algunas configuraciones, podría necesitar ajustar su perfil de red a Privado o Dominio, ya que PowerShell remoto no funcionará correctamente en redes públicas de forma predeterminada.

Nota rápida: En algunas máquinas, podrías tener problemas con los perfiles de red. Es un poco extraño, pero cambiar la red de Pública a Privada desde Configuración > Red > Ethernet o Wi-Fi > Perfil de red suele solucionar los problemas de permisos. Si el servidor remoto sigue sin conectarse, podrías ajustar las reglas del firewall o permitir explícitamente el tráfico entrante de WinRM:

Set-NetFirewallRule -Name "WINRM-HTTP-In-TCP" –RemoteAddress Any

Esta línea permite el tráfico entrante de WinRM independientemente de la dirección de red, lo que resulta útil si se trabaja con varios segmentos de subred o configuraciones de red complejas. Recuerde que, por supuesto, Windows a veces tiene que complicarlo más de lo necesario.

Hosts de confianza: cuando se trabaja con grupos de trabajo o direcciones IP

Si sus sistemas no están en un dominio o se conecta por IP, deberá agregar esas máquinas remotas a su lista de hosts de confianza. Esto es un poco como una medida de «seguridad por conveniencia», pero es lo que se necesita. Ejecute:

Set-Item wsman:\localhost\Client\TrustedHosts -Value "192.168.1.201"

O, si te sientes imprudente, simplemente permite todo:

Set-Item wsman:\localhost\Client\TrustedHosts -Value "*"

No olvides que después tendrás que reiniciar el servicio WinRM:

Restart-Service WinRM
Nota: al agregar varios hosts, separe sus IP o nombres con comas entre comillas, como «192.168.1.201, 192.168.1.202».

Uso de Invoke-Commands para ejecutar comandos en computadoras remotas

Ejecutar un solo comando: sencillo pero requiere una configuración correcta

Una vez configurado WinRM y definidas las reglas de red, usar Invoke-Command solo requiere especificar la máquina de destino y lo que se desea ejecutar. Por ejemplo:

Invoke-Command -ComputerName dc01 -ScriptBlock { Get-Service wuauclt }

Esto le pedirá a la máquina remota dc01 que le indique si el Servicio de Actualización de Windows se está ejecutando. Verá el estado del servicio impreso: en una configuración funcionó perfectamente; en otra, podría haber algunos problemas de autenticación, así que revise sus permisos y reglas de red.

Consejo útil: si desea ejecutar el comando con una cuenta de usuario diferente, simplemente agregue -Credential y proporcione las credenciales:

$cred = Get-Credential Invoke-Command -ComputerName dc01 -Credential $cred -ScriptBlock { Get-NetAdapter }

Esto suele ser útil si su usuario actual no forma parte de los grupos de Administración remota o Administración en el equipo de destino. Tenga en cuenta que se requieren muchos permisos y, a veces, las políticas de seguridad de PowerShell bloquean ciertos comandos remotos.

Ejecutar varios comandos o scripts de forma remota: sí, puedes hacerlo

¿Quieres hacer más de una cosa a la vez? Simplemente separa los comandos con punto y coma dentro del ScriptBlock:

Invoke-Command -ComputerName dc01 -ScriptBlock { Get-TimeZone; Set-TimeZone -Name "Central Europe Standard Time" }

Y si tienes un script guardado en algún lugar, como C:\PS\CheckStatus.ps1, puedes ejecutarlo de forma remota con:

Invoke-Command -ComputerName dc01 -FilePath "C:\PS\CheckStatus.ps1"

De esta forma, no es necesario copiar scripts manualmente a sistemas remotos y se evitan los errores de política de ejecución. Resulta práctico para trabajos por lotes o scripts de administración que se ejecutan con frecuencia.

Atención: Si sus scripts acceden a recursos remotos (como recursos compartidos de red), podría encontrarse con el temido problema del «doble salto».Es un problema de seguridad de Windows: busque en Google soluciones alternativas como la delegación Kerberos o use CredSSP; de lo contrario, las credenciales no se transferirán a recursos de terceros.

Ejecutar comandos en varias computadoras a la vez

Comandos paralelos para un grupo de servidores

Si gestionas una flota de servidores, ejecutar comandos en serie sería un fastidio. Por suerte, Invoke-Command permite la ejecución en paralelo. Simplemente enumera tus servidores separados por comas:

Invoke-Command server1, server2, server3 -ScriptBlock { get-date }

También puedes almacenar los nombres en una matriz para reutilizarlos:

$servers = @("server1", "server2", "server3") Invoke-Command -ComputerName $servers -ScriptBlock { get-date }
O bien, puede alimentar una lista desde un archivo de texto, lo que facilita la automatización:

Invoke-Command -ComputerName (Get-Content c:\ps\servers.txt) -ScriptBlock { Restart-Service spooler }

Si está extrayendo nombres de host de Active Directory, el cmdlet Get-ADComputer ayuda a filtrar determinados sistemas:

$computers = (Get-ADComputer -Filter 'OperatingSystem -like "*Windows server*" -and Enabled -eq "true"').Name Invoke-Command -ComputerName $computers -ScriptBlock { Get-EventLog -LogName System -Newest 10 } -ErrorAction SilentlyContinue

¿Y si uno o más destinos están desconectados u ocupados? El parámetro -ErrorAction SilentlyContinue mantiene el script funcionando sin problemas. Además, para ver qué máquina respondió, use la variable PSComputerName dentro de su ScriptBlock:

$results = Invoke-Command -ComputerName $computers -ScriptBlock { get-date } $results | Select-Object PSComputerName, * 

Conexiones persistentes remotas de PowerShell: ahorre tiempo y evite problemas

Crea una sesión que perdure

Si ejecuta varios comandos en la misma máquina remota, conviene mantener una sesión activa en lugar de reconectarse cada vez. A continuación, se explica cómo crear y usar una sesión persistente:

$session = New-PSSession -ComputerName Server01, Server02 Invoke-Command -Session $session -ScriptBlock { Get-ComputerInfo | select OsLastBootUpTime }

Una vez que hayas terminado, cierra esa sesión con:

Remove-PSSession $session

Esta configuración puede ahorrar mucho tiempo al administrar varios servidores, especialmente si ejecuta varios comandos en un script o una tarea programada. Tenga en cuenta que las sesiones pueden permanecer en la memoria, así que ciérrelas cuando ya no las necesite. Además, algunas configuraciones podrían requerir ajustes adicionales de seguridad o cambios de política para permitir sesiones persistentes.

Sinceramente, configurar la administración remota de PowerShell puede parecer un reto al principio, pero una vez que lo dominas, es bastante potente. Solo recuerda revisar las reglas de red y firewall, y ten paciencia con las peculiaridades.