Sesiones Reutilizables de PowerShell: Una Guía para Conexiones Remotas Persistentes

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/