Blog

14/02/2017

Administración masiva con PowerShell – PSRemoting (parte 2/2)

Funcionamiento y uso

Tenemos dos maneras de usar PSRemoting, de uno a uno o de uno a muchos.

De uno a uno

Esta forma nos va a permitir conectarnos con la PowerShell a un equipo remoto.

Enter-PSSession -ComputerName srv-001.

Desde ese momento todos los comandos que pongamos se ejecutaran en el equipo al que nos hemos conectado. Nos muestra el nombre del equipo entre corchetes, al inicio de la línea.

Salimos de la sesión remota ejecutando Exit-PSSesion nos desaparecerá el nombre de equipo del inicio de la línea y todos los comandos que ejecutemos en ese momento volverán a ser locales.

De uno a muchos

Usando este método podremos pasar cualquier comando a un listado de quipos que deseemos, esto nos va a permitir un abanico de posibilidades importante ya que el resultado es devuelto al equipo desde el que lo hemos lanzado.

Para hacer esta tarea usamos el comando Invoke-Command, los objetos que devuelve este comando son objetos nuevos al que se les añade la propiedad PSComputerName que indica el equipo que lo ha generado.

Para evitar saturar el equipo que ejecuta el comando viene por defecto limitado a 32 equipos, podremos poner más pero solo 32 se ejecutaran a la vez y conforme vaya terminando alguno empezara con otro equipo. Se puede cambiar usando el parámetro -trhottling acompañado del número de sesiones concurrentes que queremos.

Algunos ejemplos:

#Limpiar la cache de lon-dc1 y lon-cl1
Invoke-Command -ComputerName lon-dc1, lon-cl1 -ScriptBlock {clear-dnsClientCache }

#Ejecutar el script demo.ps1 en lon-dc1 y lon-svr1
Invoke-Command -ComputerName lon-dc1, lon-svr1 -FilePath “C:\demo.ps1” -ThrottleLimit 1

#Coger la MAC de todos los adaptadores físicos de todos los equipos de Active Directory.
Invoke-Command -ComputerName (Get-ADComputer -filter * | select -ExpandProperty DNSHostName) -ScriptBlock {Get-NetAdapter -Physical| select systemname,name,macaddress |ft -AutoSize}

< #Sacar fichero HTLM con cuanto espacio disponible hay en cada disco de cada equipo de Active Directory#>
Invoke-command -ComputerName (Get-ADComputer -filter * | select -ExpandProperty DNSHostName) -scriptblock {get-wmiobject -class Win32_LogicalDisk -filter “DriveType = 3”} | convertto-html -property PSComputerName, DeviceID,FreeSpace,Size | Out-File c:\discos.html

Pasar parámetros a los equipos remotos

Para poder pasar parámetros a los comandos que se ejecutan en los equipos remotos tenemos que declararlos previamente con param y rellenarlos con el parámetro -argumentlist, en el siguiente comando vemos como se crean los parámetros $l y $c y en el parámetro -argumentList llamamos a la variable $log y $cantidad. Estos inputs pasan por orden a los parámetros así que $log pasa al parámetro $l y la variable $cantidad al parámetro $c. En argumentlist podremos también poner valores o incluso comandos entre ().

#Pasar variables como parámetros
$log = ‘security’
$cantidad = read-host “Cuantos registros quieres?”
Invoke-Command -ComputerName lon-dc1 -ScriptBlock {
param ($l,$c)
get-eventlog -LogName $l -Newest $c
} -ArgumentList $log, $cantidad#Pasar valores como parámetros
Invoke-Command -ComputerName lon-dc1 -ScriptBlock {
param ($l,$c)
get-eventlog -LogName $l -Newest $c
} -ArgumentList “security”, 10#Pasar comando entre paréntesis como parámetro
Invoke-Command -ComputerName srv-001 -ScriptBlock {
param ($l,$c)
get-eventlog -LogName $l -Newest $c
} -ArgumentList “security”, (read-host “¿cuantos registros quieres?”)

Sesiones persistentes

El comando invoke-command cada vez que se conecta a un equipo usa una sesión, y los objetos temporales son exclusivos de cada sesión.

Por Ejemplo:

Invoke-Command -computername lon-dc1 -ScriptBlock {$variable = 1000}
Invoke-Command -ComputerName lon-dc1 -ScriptBlock {$variable}

Este comando no devolverá nada dado que la variable $variable no existe.
Para poder usar estos objetos en distintas ejecuciones tenemos que usar sesiones persistentes que permiten reutilizar la misma sesión cada vez que usamos PSRemoting.
Lo más cómodo es meter las sesiones en variables, no es obligatorio, pero si nos ahorra esfuerzo al reutilizar la variable cada vez que se quiera usar la sesión.

$DC1= New-PSSession -ComputerName lon-dc1 -Credential (get-credential UserName Administrator -Message “Contraseña para dc1” )

$svr1= New-PSSession -ComputerName lon-svr1

Ahora ya se puede reutilizar la sesión.

#Crear la variable
Invoke-Command -Session $DC1 -ScriptBlock {$variable = 1000}#la llamamos usando la sesión veremos que conserva la variable.
Invoke-Command -Session $dc1 -ScriptBlock {$variable}

Las sesiones persistentes se tienen que borrar.

#borrar la sesión
Remove-PSSession $dc1

Si no las borramos cuando superan el timeout se desconectan y ya no se puede utilizar.

Conclusiones:

En definitiva, podemos ver la potencia que nos ofrece PowerShell en entornos corporativos permitiéndonos hacer prácticamente cualquier cosa que necesitemos, desde recoger información hasta realizar cambios, si se puede hacer por PowerShell se puede automatizar. Esto responde a esa pregunta que me hacen muchas veces ¿Por qué usar comandos del tipo Test-Connection si ya tenemos esa funcionalidad haciendo un ping? La respuesta es clara, porque podremos automatizarlo o masificarlo.

Jonatan Alonso
Microsoft Lead Trainer

 

Análisis, Artículos , , , , , ,

Comenta esta información