En este artículo aprenderemos a utilizar el Invocar-Comando cmdlet para ejecutar comandos o scripts de PowerShell de forma remota. Puede usar PowerShell para ejecutar comandos de forma remota en una o más computadoras en su red. El cmdlet Invoke-Command utiliza funciones de administración remota de Comunicación remota de PowerShell. PowerShell Remoting le permite conectarse de forma remota a sesiones de PowerShell en computadoras a través de WinRM (Administración remota de Windows) y Servicios web para la gestión (WS-Management) protocolo. Este servicio brinda la capacidad de establecer sesiones remotas de PowerShell y ejecutar su código.
Configuración de WinRM para la comunicación remota de PowerShell
PowerShell Remoting utiliza HTTP (puerto TCP / 5985) o HTTPS (puerto TCP / 5986) para comunicarse entre computadoras. De forma predeterminada, se utiliza el protocolo HTTP, pero incluso este tráfico se cifra mediante el AES-56 (sin embargo, existe la amenaza de ataques de tipo man-in-the middle). También se puede utilizar la autenticación Kerberos o NTLM.
WinRM debe estar ejecutándose en las computadoras remotas a las que se va a conectar. Verifique el estado del servicio WinRM:
Get-Service -Name "*WinRM*" | fl
Si el servicio no se está ejecutando, inícielo:
Enable-PSRemoting
WinRM has been updated to receive requests. WinRM service started. WinRM is already set up for remote management on this computer.
Este comando iniciará el servicio WinRM (y lo configurará para que se inicie automáticamente), establecerá la configuración predeterminada de winrm y agregará reglas de excepción al Firewall de Windows. La Enable-PSRemoting –Force
El comando habilita WinRM sin preguntarle al usuario.
Luego, puede conectarse a la computadora de forma remota utilizando PowerShell Remoting.
Set-WSManQuickConfig : ... WinRM firewall exception will not work since one of the network connection types on this machine is set to Public. Change the network connection type to either Domain or Private and try again.
Debe cambiar la ubicación de la red a Privada o usar este comando:
Enable-PSRemoting –SkipNetworkProfileCheck.
También habilite la regla de Firewall de Windows Defender que permite el acceso a WinRM en redes públicas. Puede habilitar la regla de firewall usando GPO o PowerShell:
Set-NetFirewallRule -Name 'WINRM-HTTP-In-TCP' -RemoteAddress Any
Para probar la conexión a una computadora remota a través de PowerShell Remoting, ejecute el siguiente comando:
Test-WsMan compname1
Si no tiene un dominio de Active Directory o accede a las computadoras a través de PowerShell Remoting mediante direcciones IP, en este caso, se utiliza el protocolo NTLM para la autenticación. Al usar NTLM, aparece el siguiente error si intenta ejecutar Invoke-Command:
[192.168.1.201] Connecting to remote server 192.168.1.102 failed with the following error message: The WinRM client cannot process the request. Default authentication may be used with an IP address under the following conditions: thetransport is HTTPS or the destination is in the TrustedHosts list, and explicit credentials are provided. Use winrm.cmd to configure TrustedHosts. Note that computers in the TrustedHosts list might not be authenticated. + FullyQualifiedErrorId: CannotUseIPAddress,PSSessionStateBroken
Para que la autenticación NTLM funcione correctamente en una computadora que está utilizando para conectarse, haga algunas cosas más: emita un certificado SSL o agregue el nombre de host / dirección IP a la lista de hosts de confianza:
Set-Item wsman:localhostClientTrustedHosts -value 192.168.1.201
O puede permitir la conexión a todas las computadoras (no se recomienda, porque es una de las desventajas de NTLM: no admite la autenticación mutua).
Set-Item wsman:localhostClientTrustedHosts -value *
Se debe aplicar la misma configuración en hosts remotos.
Para mostrar la lista de hosts de confianza, ejecute el comando:
Get-Item WSMan:localhostClientTrustedHosts
Para aplicar los cambios, reinicie WinRM:
Restart-Service WinRM
También puede habilitar y configurar WinRM usando Políticas de grupo.
¿Cómo ejecutar comandos de PowerShell de forma remota usando Invoke-Command?
El cmdlet Invoke-Command permite ejecutar un comando en uno o más equipos remotos.
Por ejemplo, para ejecutar un solo comando en una computadora remota, use lo siguiente:
Invoke-Command -ComputerName dc01 -ScriptBlock {$PSVersionTable.PSVersion}
Este comando mostrará la versión de PowerShell instalada en la computadora remota, cuyo nombre se especifica en el -ComputerName
parámetro. Ingrese el comando que se ejecutará en una computadora remota en el -ScriptBlock {[cmdlet]}
cuadra.
De forma predeterminada, un comando enviado a través de Invoke-Command se ejecuta como el usuario actual en una computadora remota. Si desea ejecutarlo como otro usuario, solicite las credenciales de usuario y guárdelas en una variable:
$cred = Get-Credential
Invoke-Command -ComputerName dc01 -Credential $cred -ScriptBlock {Get-NetAdapter}
Este comando de PowerShell muestra la lista de interfaces de red en una computadora remota:
Puede ingresar más de un comando en ScriptBlock, separados por punto y coma. Por ejemplo, el siguiente comando mostrará la zona horaria actual y la cambiará a otra:
Invoke-Command -Computername dc01 -ScriptBlock {Get-TimeZone| select DisplayName;Set-TimeZone -Name "Central Europe Standard Time”}
Invoke-Command le permite ejecutar no solo comandos individuales, sino también ejecutar scripts de PowerShell. Para ello, se utiliza el argumento -FilePath (en lugar de –ScriptBlock). En este caso, especifique la ruta al archivo de secuencia de comandos de PS1 local en su computadora (no necesita copiar el archivo de secuencia de comandos a la computadora remota de destino):
Invoke-Command -ComputerName DC01 -FilePath C:PSScriptsCheckSMBversion.ps1
¿Cómo utilizar Invoke-Command para ejecutar comandos en varios equipos simultáneamente?
Puede utilizar Invoke-Command para ejecutar comandos en varias computadoras remotas en paralelo (simultáneamente).
En el caso más simple, los nombres de las computadoras en las que ejecutar los comandos de PowerShell están separados por comas:
Invoke-Command server1, server2, server3 -ScriptBlock {get-date}
Puede colocar la lista de computadoras en una variable (matriz):
$servers = @("server1","server2","server3")
Invoke-Command -ScriptBlock { get-date} -ComputerName $servers
O obtén de un archivo de texto:
Invoke-Command -ScriptBlock {Restart-Service spooler} -ComputerName(Get-Content c:psservers.txt)
También puede obtener una lista de equipos en AD mediante el cmdlet Get-ADComputer del módulo AD para PowerShell:
Para ejecutar un comando en todos los hosts de Windows Server en el dominio, use el siguiente código de PowerShell:
$computers = (Get-ADComputer -Filter 'OperatingSystem -like "*Windows server*" -and Enabled -eq "true"').Name
Invoke-Command -ComputerName $computers -ScriptBlock {Get-Date} -ErrorAction SilentlyContinue
Si una computadora está apagada o no disponible, la secuencia de comandos no se detendrá debido al parámetro SilentlyContinue y continuará ejecutándose en otras computadoras.
Para comprender de qué computadora proviene un resultado, use la variable de entorno PSComputerNamee.
$results = Invoke-Command server1, server2, server3 -ScriptBlock {get-date}
$results | Select-Object PSComputerName, DateTime
Cuando se ejecuta un comando con Invoke-Command en varios equipos, se ejecuta simultáneamente. Invoke-Command tiene una restricción sobre el número máximo de equipos que se pueden administrar al mismo tiempo (un número limitado de sesiones de PS simultáneas). Esta restricción se establece en el ThrottleLimit parámetro (el valor predeterminado es 32). Si desea ejecutar un comando en más de 32 computadoras (128, por ejemplo), use –ThrottleLimit 128
(sin embargo, su computadora tendrá una carga más alta para establecer una gran cantidad de PSSessions).
Para ejecutar comandos en computadoras remotas a través de Invoke-Command en segundo plano, un atributo especial –AsJob
se utiliza. Entonces, el resultado del comando no se devuelve a la consola. Para obtener los resultados, utilice el Recibir trabajo cmdlet.