1.2K
Puede usar PowerShell Remoting (que apareció en PowerShell 2.0) para ejecutar comandos o scripts en una o varias computadoras remotas. PS Remoting se basa en el protocolo Web Services for Management (WS-Management).
Puede usar el modo de sesión interactiva remota de PS o la conexión persistente a una computadora remota. En este artículo, veremos varios ejemplos de cómo ejecutar un script de PowerShell de forma remota.
Configuración de WinRM para la comunicación remota de PowerShell
Para conectarse a una computadora de forma remota a través de PowerShell, WinRM (servicio de administración remota de Windows) debe estar habilitado y configurado en el dispositivo cliente remoto (está deshabilitado de forma predeterminada). La comunicación entre computadoras se realiza a través de protocolos HTTP o HTTPS, y todo el tráfico de red entre computadoras está encriptado. Puede usar NTLM y Kerberos para autenticarse en una computadora remota.
Para habilitar y configurar rápidamente la computadora para la administración remota a través de PowerShell Remoting y WinRM, ejecute el comando:
Enable-PSRemoting
Este comando prepara la computadora para la administración remota:
- Inicia el servicio WinRM y cambia el tipo de inicio a Automático;
- Agrega excepciones al Firewall de Windows Defender;
- Configura el agente de escucha de WinRM para aceptar conexiones remotas;
- Habilita la configuración de sesión para PowerShell.
Si la conexión de red de la computadora está configurada como Pública, recibirá un error cuando ejecute el comando Enable-PSRemoting:
La excepción del cortafuegos de WinRM no funcionará porque uno de los tipos de conexión de red en esta máquina está configurado como Público
Puede cambiar el tipo de red a Privado usando el comando:
Get-NetConnectionProfile | Set-NetConnectionProfile -NetworkCategory Private
O puede ignorar el perfil de red para WinRM:
Enable-PSRemoting –SkipNetworkProfileCheck -Force
PowerShell Remoting utiliza los puertos TCP HTTP (5985) y HTTPS (5986) para las comunicaciones de red. Si la computadora remota está protegida con el Firewall de Windows Defender con seguridad avanzada, lo siguiente Administración remota de Windows (HTTP-In) las reglas se habilitarán automáticamente después de ejecutar el comando Enable-PSRemoting:
- WINRM-HTTP-en-TCP
- WINRM-HTTP-en-TCP-NoScope
Puede habilitar las reglas de Windows Defender manualmente desde la consola gráfica o usando PowerShell:
Set-NetFirewallRule -Name "WINRM-HTTP-In-TCP" -RemoteAddress Any Set-NetFirewallRule -Name "WINRM-HTTP-In-TCP-NoScope" -RemoteAddress Any
Si el equipo remoto está en un grupo de trabajo (no unido al dominio de Active Directory) y un Público el perfil de red se aplica a la conexión LAN (en lugar de Dominio o Privado), debe permitir explícitamente el tráfico WinRM entrante en el Firewall de Windows:
Set-NetFirewallRule -Name "WINRM-HTTP-In-TCP-PUBLIC" -RemoteAddress Any
Verifique el estado del servicio WinRM con el comando Get-Service:
Get-Service WinRM
Como puede ver, el servicio WS-Management se está ejecutando. Ahora puede establecer sesiones con este host remoto y enviar comandos de PowerShell.
Para probar la conexión a una computadora remota a través de WinRM, use el siguiente comando:
Test-WSMan server1
Si obtiene una respuesta, se puede acceder a la computadora remota a través de PowerShell Remoting.
Pista. Si se está conectando a una computadora remota a través de PS Remoting mediante una dirección IP, es posible que reciba un error:
La conexión al servidor remoto 192.168.1.70 falló con el siguiente mensaje de error: El cliente WinRM no puede procesar la solicitud. La autenticación predeterminada se puede usar con una dirección IP en las siguientes condiciones: el transporte es HTTPS o el destino está en la lista TrustedHosts y se proporcionan credenciales explícitas.
En este caso, debe instalar un certificado HTTPS para PowerShell Remoting en la computadora remota (el camino largo) o agregar este host a los confiables en su computadora de administración:
Set-Item wsman:localhostClientTrustedHosts -value 192.168.1.70
Luego reinicie el servicio WinRM:
Restart-Service WinRM
De forma predeterminada, las conexiones de PSRemoting pueden ser utilizadas por usuarios con permisos de administrador local o por miembros del grupo de usuarios de administración remota local. Puede obtener los ajustes de configuración de la sesión registrada actual para PowerShell con el comando:
Get-PSSessionConfiguration -name microsoft.powershell
Si necesita cambiar los permisos del extremo remoto de PowerShell en Windows, ejecute el comando:
Set-PSSessionConfiguration -Name Microsoft.PowerShell -ShowSecurityDescriptorUI -Force
Cambiar la ACL actual.
Ejecución de comandos remotos con PowerShell Remoting
Para conectarse de forma interactiva a una computadora remota (con un nombre de host Server1) a través de PowerShell, ejecute el siguiente comando:
Enter-PSSession Server1
La vista de la CLI de PowerShell cambiará. Al comienzo de la línea, estará el nombre de la computadora remota a la que está conectado a través de WinRM. Una vez que se establece la sesión remota, todos los comandos que se ingresan en la consola de PowerShell se ejecutan en la computadora remota. PS Remoting funciona de la siguiente manera: los comandos ingresados en la computadora local se transmiten a la computadora remota y se ejecutan allí, luego el resultado se transmite de vuelta. Dado que todos los comandos se ejecutan localmente, no hay necesidad de preocuparse por la compatibilidad con la versión y los módulos de PowerShell.
Para finalizar la sesión interactiva remota, ejecute el comando:
Exit-PSSession
Solo las tareas de administración simples generalmente se realizan en computadoras remotas en modo interactivo. Para ejecutar un comando complejo o ejecutar el script de PowerShell de forma remota, use el cmdlet Invoke-Command.
Nota. También puede consultar nuestra publicación sobre cómo crear una GUI para scripts de PowerShell.
Uso de Invoke-Command para ejecutar secuencias de comandos de PowerShell de forma remota
El siguiente comando creará una conexión remota con la computadora Server1 y ejecutará el bloque de comandos especificado en el parámetro ScriptBlock. Después de eso, la sesión remota se cerrará automáticamente.
Invoke-Command -ScriptBlock {Restart-Service spooler} -ComputerName server1
Si necesita ejecutar varios comandos secuenciales de PowerShell en una máquina remota, separe los comandos en el ScriptBlock usando punto y coma:
Invoke-Command -ScriptBlock {Restart-Service spooler;Get-Date; wmic qfe list} -ComputerName server1
Puede ejecutar la tarea en segundo plano ejecutando Invoke-Command con el parámetro -AsJob. Pero, en este caso, el comando no devolverá el resultado a la consola de PoSh. Para obtener información detallada sobre el trabajo en segundo plano, use el cmdlet Receive-Job.
PowerShell le permite ejecutar scripts locales de PS1 en computadoras remotas. La idea es que almacene todas las instrucciones de PowerShell en un archivo .PS1 local en su computadora. Con PowerShell Remoting, puede transferir un archivo PS1 a una computadora remota y ejecutarlo allí.
Para ello, use el parámetro -FilePath en el cmdlet Invoke-Command en lugar de -ScriptBlock. Por ejemplo, para ejecutar el script c:pstune.ps1 en tres servidores remotos, puede usar el siguiente comando:
Invoke-Command -FilePath c:pstune.ps1 -ComputerName server1,server2,server3
La principal ventaja de esta forma de ejecutar secuencias de comandos de PowerShell es que no es necesario copiar el archivo de secuencia de comandos de PS1 en equipos remotos. El archivo de script de PowerShell se puede colocar en una unidad local o en una carpeta de red compartida. En este caso, para ejecutar el archivo de script de PS1, debe especificar la ruta UNC completa:
Invoke-Command -FilePath "\dc03Sharepstune.ps1" -ComputerName PCS12dd2
Si los scripts de PowerShell no pueden ejecutarse en la computadora remota, aparecerá un error:
Invocar comando: el archivo c:Sharepstune.ps1 no se puede cargar porque la ejecución de scripts está deshabilitada en este sistema. Para obtener más información, consulte about_Execution_Policies
Puede cambiar la configuración de la política de ejecución de PowerShell en una computadora remota o firmar su archivo de script de PowerShell con un certificado.
Si necesita ejecutar scripts de PowerShell con credenciales que no sean las del usuario actual, debe usar el -Credencial parámetro.
Primero, debe obtener la credencial y guardarla en una variable:
$cred = Get-Credential
Ahora puede ejecutar el script de PS en equipos remotos con las credenciales alternativas:
Invoke-Command -FilePath c:pstune.ps1 -ComputerName server1,server2,server3 -Credential $cred
Puede guardar la lista de computadoras en un archivo de texto y ejecutar el script de PowerShell de forma remota en todas las computadoras a la vez:
Invoke-command -ComputerName (get-content c:psservers.txt) -filepath c:pstune.ps1
De forma predeterminada, el cmdlet Invoke-Command envía la secuencia de comandos de PS1 a 32 equipos remotos de la lista al mismo tiempo. Si hay más de 32 computadoras, PoSh verifica el estado de ejecución del script en las primeras 32 computadoras. El comando se ejecuta en la siguiente computadora si se completa el script. Con el parámetro ThrottleLimit, puede aumentar este límite, pero tenga cuidado de no sobrecargar su red.
Cuando ejecuta el cmdlet Invoke-Command en varias computadoras, puede verificar previamente si se puede acceder a la computadora remota a través de WinRM. Si la computadora está disponible, puede ejecutar el código de PowerShell en ella usando Invoke-Command:
$RemoteComputers= get-content c:psservers.txt
ForEach $RemoteComputer in $RemoteComputers)
{
If (Test-WSMan -ComputerName $RemoteComputer)
{
Invoke-Command -ComputerName $RemoteComputer -FilePath c:pstune.ps1
}
Si desea pasar variables de sesión locales a una sesión remota de PowerShell, use el prefijo $Using:
$name=”script1.ps1”
Invoke-Command -ComputerName dc03 -Scriptblock{ write-host $using:Name}
Puede usar el parámetro ConnectionUri en Invoke-Command para ejecutar el comando en aplicaciones de back-end como Exchange o servicios en la nube de Azure/AWS. Por ejemplo:
$Creds = Get-Credential
$params = @{
ConfigurationName="Microsoft.Exchange"
ConnectionUri = 'https://lonexch1.theitbros.com/PowerShell'
Credential = $Creds
Authentication = 'Basic'
ScriptBlock = {Get-Mailbox BJackson -DisplayName "Brian Jackson"}
}
Invoke-Command @params
Uso de conexiones persistentes de PowerShell (sesiones)
Cada vez que ejecuta Invoke-Command, se crea una nueva sesión con la computadora remota. Esto requiere tiempo y recursos del sistema. En PowerShell, puede crear una sesión y ejecutar todos los comandos y scripts en ella.
Con el cmdlet New-PSSession, puede crear sesiones persistentes de PowerShell con equipos remotos.
Por ejemplo, creemos sesiones con tres computadoras y guardémoslas en la variable $PSSess:
Invoke-Command -FilePath c:pstune.ps1 -ComputerName server1,server2,server3 $PSSess = New-PSSession -ComputerName server1, server2, server3
Después de establecer una sesión, puede usarla para ejecutar comandos y scripts. Debido a que las sesiones son persistentes, puede obtener datos de ellas y utilizarlas en otros comandos y scripts.
Por ejemplo, el siguiente comando obtendrá una lista de procesos en servidores remotos y los almacenará en la variable $RemoteProcesses:
Invoke-Command -Session $PSSess {$RemoteProcesses = Get-Process}
Ahora puede usar esta variable en otros comandos en las mismas sesiones. En el siguiente ejemplo, usamos el cmdlet Where-Object para encontrar procesos que usan más de 500 MB de RAM):
Invoke-Command -Session $PSSess {$RemoteProcesses | where-object {$_.WorkingSet -GT 500000*1024}|select processname,@{l="Working Memory (MB)"; e={$_.workingset / 1mb}} |sort "Working Memory (MB)" -Descending}
La sesión remota persistente de PowerShell permanecerá activa hasta que cierre la consola de PowerShell o cierre o elimine la sesión a la fuerza mediante los cmdlets Disconnect-PSSession o Remove-PSSession, respectivamente.
¿Cómo ejecutar el comando PowerShell desde PSexec?
Puede usar la herramienta PsExec de Sysinternals para ejecutar comandos de PowerShell en una computadora remota. En este caso, no necesita habilitar y configurar WinRM en el host remoto.
Para ejecutar un comando de PowerShell en un host remoto de Windows:
- Descargue y extraiga el PsExec (https://docs.microsoft.com/en-us/sysinternals/downloads/psexec);
- Abra un símbolo del sistema como administrador y cambie al directorio con psexec.exe: cd c:pstools
- Ahora puede ejecutar un solo comando de PowerShell en una computadora remota:
psexec.exe \SrvNY01 powershell.exe -command "& {get-process}"
Puede ejecutar varios comandos a la vez:
psexec.exe \SrvNY01 powershell.exe -command "& {get-process;Get-Services; Get-CimInstance -ClassName Win32_OperatingSystem | Select LastBootUpTime
Sus comandos de PowerShell se ejecutarán en la máquina remota y psexec devolverá el código de salida 0.
Si necesita ejecutar de forma remota un archivo de script de PS1 local:
psexec -s \ SrvNY01 Powershell -ExecutionPolicy Bypass -File \dc1netlogonscriptsGet-Info.ps1
Además, tenga en cuenta que muchos comandos integrados de PowerShell tienen un parámetro ComputerName que le permite acceder directamente a una computadora remota a través de la red. Puede obtener una lista de dichos comandos:
Get-Command | Where-Object {$_.parameters.keys -contains "ComputerName"}
Por ejemplo, puede obtener registros de eventos desde una computadora remota:
Get-EventLog -LogName System -computername SrvNY01| where {$_.EventId -eq 1074}
O reinicie hosts remotos:
Restart-Computer -ComputerName SrvNY03, SrvNY02, SrvNY01
Como puede ver, PowerShell brinda amplias oportunidades para ejecutar scripts y comandos en computadoras remotas.














