Búsqueda de sitios web

Uso de PowerShell Invoke-Command para ejecutar scripts en equipos remotos


En este artículo, aprenderemos a usar el cmdlet Invoke-Command 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 usa características de administración remota de PowerShell Remoting. PowerShell Remoting le permite conectarse de forma remota a sesiones de PowerShell en computadoras mediante el servicio WinRM (Administración remota de Windows) y el protocolo Servicios web para administración (WS-Management). 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 usa 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 con el AES-56 (sin embargo, existe la amenaza de ataques de intermediario). 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. El

Enable-PSRemoting -Force

El comando habilita WinRM sin preguntarle a un usuario.

Luego, puede conectarse a la computadora de forma remota mediante PowerShell Remoting.

Tenga en cuenta que PowerShell Remoting no funcionará de forma predeterminada si su tipo de red está configurado como Pública. Entonces el comando devuelve el siguiente error:

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.

Habilite también 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 por direcciones IP, en este caso se usa 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 para WinRM o agregue el nombre de host/dirección IP a la lista de hosts confiables:

Set-Item wsman:\localhost\Client\TrustedHosts -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:\localhost\Client\TrustedHosts -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:\localhost\Client\TrustedHosts

Para aplicar los cambios, reinicie WinRM:

Restart-Service WinRM

También puede habilitar y configurar WinRM mediante 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]}

bloquear.

De manera 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 hacerlo, se usa el argumento -FilePath (en lugar de -ScriptBlock). En este caso, especifica la ruta al archivo de secuencia de comandos de PS1 local en su computadora (no es necesario que copie el archivo de secuencia de comandos en la computadora remota de destino):

Invoke-Command -ComputerName DC01 -FilePath C:\PS\Scripts\CheckSMBversion.ps1

¿Cómo usar Invoke-Command para ejecutar comandos en varias computadoras simultáneamente?

Puede usar Invocar-Comando para ejecutar comandos en varias computadoras remotas en paralelo (simultáneamente).

En el caso más simple, los nombres de las computadoras para ejecutar los comandos de PowerShell se separan con 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 obtener de un archivo de texto:

Invoke-Command -ScriptBlock {Restart-Service spooler} -ComputerName(Get-Content c:\ps\servers.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 está disponible, el script 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 usando Invoke-Command en varias computadoras, se ejecuta simultáneamente. Invoke-Command tiene una restricción en la cantidad máxima de computadoras que se pueden administrar al mismo tiempo (una cantidad limitada de PSSessions simultáneas). Esta restricción se establece en el parámetro ThrottleLimit (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 mayor carga 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 usa Luego, el resultado del comando no se devuelve a la consola. Para obtener los resultados, use el cmdlet Receive-Job.

Artículos relacionados