Gestionar sistemas remotos puede convertirse rápidamente en un dolor de cabeza, especialmente al ejecutar múltiples comandos en diferentes máquinas. El constante ir y venir de reconexión a los sistemas puede desperdiciar tiempo y ralentizar tu flujo de trabajo. ¿Te resulta familiar? ¡No te preocupes, hay una mejor manera!
En esta guía, aprenderás a utilizar sesiones de PowerShell reutilizables para hacer más rápido, fácil y eficiente el manejo de sistemas remotos.
¿Listo para mejorar tus habilidades de remoting en PowerShell? ¡Vamos a sumergirnos en ello!
Creación y Uso de una Sesión
Cuando trabajas con sistemas remotos, una de las tareas más tediosas puede ser reconectar a ellos cada vez que ejecutas un comando. En tales casos, entran en juego las sesiones reutilizables.
Crear una sesión persistente mantiene una conexión continua. Al hacerlo, eliminas la necesidad de conectar y desconectar al ejecutar múltiples comandos repetidamente.
Para empezar, necesitarás crear una sesión reutilizable.
El cmdlet New-PSSession
establece una conexión persistente con la computadora remota:
$session = New-PSSession -ComputerName SRV2
Este objeto de sesión se puede pasar a comandos como Invoke-Command
, lo que te permite reutilizar la misma sesión a lo largo de tu script.
Por ejemplo, puedes probar la conexión ejecutando un comando básico:
Invoke-Command -Session $session -ScriptBlock { hostname }
Una sesión reutilizable también te permite almacenar y recuperar variables en el sistema remoto:
Invoke-Command -Session $session -ScriptBlock { $foo = 'Please be here next time' } Invoke-Command -Session $session -ScriptBlock { $foo }
Esta capacidad de almacenamiento persistente es una ventaja significativa de las sesiones reutilizables, que te permite mantener el estado a lo largo de múltiples comandos.
Adaptando la Función para Uso Remoto
Adaptemos la función de inventario para que funcione con sesiones reutilizables.
Primero, agregamos un parámetro Sesión
para aceptar un objeto de sesión, donde el cmdlet Get-Member
ayuda a identificar el tipo de objeto de sesión:
$session | Get-Member
Después de identificar que el objeto de sesión es del tipo System.Management.Automation.Runspaces.PSSession
, el siguiente paso es definir la función Obtener-ValorWmiObjeto
.
Esta función utiliza el parámetro de sesión para habilitar la ejecución remota, lo que le permite ejecutar un bloque de script en el sistema remoto y recuperar una propiedad WMI específica.
function Get-WmiObjectValue { [CmdletBinding()] param( # Specify the name of the WMI property to query [Parameter(Mandatory)] [string]$PropertyName, # Specify the name of the WMI class to query [Parameter(Mandatory)] [string]$WmiClassName, # Specify the remote session object to use for invoking the command [Parameter(Mandatory)] [System.Management.Automation.Runspaces.PSSession]$Session ) # Define the script block to execute on the remote machine $scriptBlock = { # Get the sum of the specified property from the WMI class $number = (Get-CimInstance -ClassName $using:WmiClassName | Measure-Object -Property $using:PropertyName -Sum).Sum # Convert the sum to gigabytes $numberGb = $number / 1GB # Round the result to 2 decimal places [math]::Round($numberGb, 2) } # Execute the script block on the remote machine using the provided session Invoke-Command -Session $Session -Scriptblock $scriptBlock }
Probemos esta función y veamos qué sucede.
Get-WmiObjectValue -PropertyName Capacity -WmiClassName Win32_PhysicalMemory -Session $session
En algún momento te encontrarás con este error. Pero no te preocupes. Sigue leyendo y aprenderás cómo solucionar este error.
Abordando Problemas de Autenticación
Si te encuentras con errores de “Acceso denegado”, es probable que se deba a permisos insuficientes. Por defecto, las sesiones reutilizables heredan las credenciales utilizadas para crearlas.
Verifica el nombre de usuario actualmente autenticado en el sistema:
whoami
Si el usuario de dominio, llamado usuario, no tiene permiso para consultar WMI en la computadora remota, eleva el Invoke-Command
para usar una cuenta de administrador.
Primero, crea un objeto de credencial con el cmdlet Get-Credential
para especificar credenciales alternativas al crear la sesión:
$adminCred = Get-Credential -UserName adam
Una vez autenticado, prueba la sesión:
Invoke-Command -Session $session -Scriptblock {hostname} -Credential $adminCred
Esta prueba asegura que la sesión funcione como se espera antes de ejecutar tu función de inventario.
Pero si la sesión no funcionó, es porque ya se creó con credenciales incorrectas. Si es así, debes eliminar la sesión actual:
Remove-PSSession -Session $session
El cmdlet Remove-PSSession
elimina la sesión en las computadoras locales y remotas.
Con la sesión antigua eliminada, crea una nueva sesión. Pero esta vez, autentica la sesión como usuario administrador:
$session = New-PSSession -ComputerName SRV2 -Credential $adminCred
Intenta de nuevo el Invoke-Command
usando la nueva sesión y observa qué sucede.
Invoke-Command -Session $session -Scriptblock {hostname} -Credential $adminCred
Ahora que tienes confianza en que la nueva sesión funciona, intentemos la función de nuevo.
Get-WmiObjectValue -PropertyName Capacity -WmiClassName Win32_PhysicalMemory -Session $session
Reuniéndolo Todo
El trabajo duro ha terminado y es hora de combinar todo en un solo script.
Este script final recopila la información del inventario, muestra los resultados y limpia la sesión:
function Get-WmiObjectValue { [CmdletBinding()] param( # Specify the name of the WMI property to query [Parameter(Mandatory)] [string]$PropertyName, # Specify the name of the WMI class to query [Parameter(Mandatory)] [string]$WmiClassName, # Specify the remote session object to use for invoking the command [Parameter(Mandatory)] [System.Management.Automation.Runspaces.PSSession]$Session ) # Define the script block to execute on the remote machine $scriptBlock = { # Get the sum of the specified property from the WMI class $number = (Get-CimInstance -ClassName $using:WmiClassName | Measure-Object -Property $using:PropertyName -Sum).Sum # Convert the sum to gigabytes $numberGb = $number / 1GB # Round the result to 2 decimal places [math]::Round($numberGb, 2) } # Execute the script block on the remote machine using the provided session Invoke-Command -Session $Session -Scriptblock $scriptBlock } ## Grab the alternate credential: Get-CimInstance will work on the remote computer $adminCred = Get-Credential -UserName adam ## Create a session authenticating as the adam (admin) user $session = New-PSSession -ComputerName SRV2 -Credential $adminCred ## Find the total memory and total volume storage space on the remote computer $totalMemoryGb = Get-WmiObjectValue -PropertyName Capacity -WmiClassName Win32_PhysicalMemory -Session $session $totalStorageGb = Get-WmiObjectValue -PropertyName FreeSpace -WmiClassName Win32_LogicalDisk -Session $session Write-Host "The computer $($session.ComputerName) has $totalMemoryGb GB of memory and $totalStorageGb GB of free space across all volumes." ## Remove the shared session Remove-PSSession -Session $session
Guarda y ejecuta el script (Get-InventoryInfo.ps1) para verificar que funcione como se espera.
Conclusión
En este tutorial, has aprendido a construir una función sólida que utiliza sesiones reutilizables para administrar de manera efectiva computadoras remotas. Ahora sabes cómo mantener una conexión persistente a través de múltiples comandos y ejecutar tareas complejas en sistemas remotos sin desconectarte cada vez.
En el futuro, puedes ampliar este conocimiento incorporando sesiones reutilizables en flujos de trabajo de automatización más grandes. Un ejemplo sería expandir la función de inventario para recopilar métricas adicionales del sistema o automatizar tareas de mantenimiento en múltiples máquinas remotas.
Combine sesiones reutilizables con otras funciones de PowerShell. Optimiza tus esfuerzos de gestión de TI y automatización para ahorrar tiempo y reducir la intervención manual.
Source:
https://adamtheautomator.com/powershell-reusable-sessions/