Creando un módulo de PowerShell del mundo real: Funciones de andamiaje

¿Estás luchando por encontrar el módulo de PowerShell perfecto para tu escenario único? Con miles de módulos disponibles, podría sentirse como si debieras conformarte con lo que hay. Bueno, eso podría dejar tu solución incompleta o ineficiente. ¿Por qué no empezar a crear módulos en su lugar?

Esta guía te guiará para crear módulos y construir soluciones robustas y reutilizables adaptadas a tus necesidades.

¡Convierte tus scripts en potentes bloques de construcción que puedes reutilizar en diferentes proyectos!

Creación de un módulo de inventario de computadoras

En esta guía, crearemos un módulo de PowerShell para recopilar información sobre hardware de computadoras. Este módulo ayudará a los administradores de sistemas a recopilar y reportar información sobre memoria, almacenamiento y detalles del procesador en varios sistemas.

Nuestro módulo incluirá:

  • Funciones para recopilar información específica del hardware
  • Soporte de sistemas remotos utilizando sesiones de PowerShell
  • Formato de salida estandarizado para informes consistentes

Este ejemplo práctico demuestra conceptos esenciales de desarrollo de módulos mientras se crea una herramienta útil para la administración de sistemas.

Configuración del módulo de PowerShell

Administrar tus scripts en múltiples sistemas puede convertirse rápidamente en caos. Pero cuando tus flujos de trabajo se convierten en una batalla cuesta arriba, los módulos de PowerShell son útiles. Un módulo es una forma estructurada de agrupar y reutilizar scripts para ahorrar tiempo y reducir errores.

Vamos a combinar conceptos clave para construir un módulo de PowerShell.

Empieza por crear el directorio del módulo y definir el propio módulo para organizar tu trabajo.

## Create the module directory in the all-user location
mkdir 'C:\Program Files\PowerShell\Modules\ComputerInventory'

## Create the module to hold the module functions
Set-Content -Path 'C:\Program Files\PowerShell\Modules\ComputerInventory\ComputerInventory.psm1' -Value ''

El comando Set-Content crea un módulo llamado ComputerInventory en la ruta de todos los usuarios. Esta ubicación se elige porque hace que el módulo sea accesible para cualquier persona que inicie sesión en la máquina, lo cual es crucial en entornos empresariales donde varios usuarios necesitan acceso a la misma funcionalidad de PowerShell. A diferencia de las ubicaciones específicas del usuario, esta ruta centralizada garantiza la disponibilidad consistente del módulo y una gestión más fácil en todo el sistema.

Verificar la disponibilidad del módulo:

## The module is already showing up as available
Get-Module ComputerInventory -ListAvailable

Aunque actualmente sea una cáscara, esto confirma que se cargará adecuadamente más tarde.

Funciones de armazón

Un módulo bien estructurado es crítico, pero lo que contiene es lo que lo hace verdaderamente útil. Evita perder tiempo descubriendo para qué sirve cada parte en lugar de ser productivo creando un armazón para las funciones de tu módulo.

Abre el módulo en un editor de texto como VS Code, luego arma las funciones.

Empieza creando funciones de marcador de posición con nombres descriptivos.

function Get-MemoryInfo {
    [CmdletBinding()]
    param()

}

function Get-StorageInfo {
    [CmdletBinding()]
    param()

}

function Get-ProcessorInfo {
    [CmdletBinding()]
    param()

}

Los nombres de las funciones siguen una convención de nombres de verbo-sustantivo consistente.

Los nombres de las funciones en PowerShell siguen una convención de nombres de verbo-sustantivo, que es un patrón de nombres estandarizado. En este caso, las funciones se llaman:

  • Get-MemoryInfo
  • Get-StorageInfo
  • Get-ProcessorInfo

Cada nombre de función comienza con el verbo “Get” (indicando que recupera información) seguido de un sustantivo que describe qué información recupera (Memoria, Almacenamiento o Procesador).

Esta convención de nombres es importante en PowerShell porque hace que las funciones sean predecibles y más fáciles de entender: los usuarios pueden comprender rápidamente lo que hace una función solo con mirar su nombre.

Verifique su existencia ejecutando lo siguiente:

Get-Command -Module ComputerInventory

Cuando ejecutas el comando Get-Command -Module ComputerInventory, verías una salida similar a esta:

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Function        Get-MemoryInfo                                     1.0.0      ComputerInventory
Function        Get-ProcessorInfo                                  1.0.0      ComputerInventory
Function        Get-StorageInfo                                    1.0.0      ComputerInventory

Este comando lista todas las funciones disponibles en el módulo ComputerInventory, que incluye las tres funciones que creamos: Get-MemoryInfo, Get-StorageInfo y Get-ProcessorInfo.

En esta etapa, el módulo incluye las funciones base. Vamos a mejorar estas funciones definiendo una salida consistente utilizando objetos personalizados.

Salida Estandarizada con Objetos Personalizados

Las salidas inconsistentes en los scripts pueden convertir una tarea simple en una pesadilla de análisis de datos y resolución de problemas. En el desarrollo profesional de PowerShell, garantizar salidas consistentes es fundamental para la escritura de scripts efectiva.

La estandarización de la salida con objetos personalizados ayuda a mantener la consistencia entre las funciones.

En el siguiente script:

  • Los objetos personalizados incluyen las propiedades ComputerName, HardwareCategory e Info.
  • La propiedad HardwareCategory agrupa tipos de hardware similares, y ComputerName está diseñada para escalabilidad multi-computadora.
function Get-MemoryInfo {
    [CmdletBinding()]
    param()

    $outObject = @{
        'ComputerName'      = ''
        'HardwareCategory'  = 'Memory'
        'Info'              = $null
    }

    $outObject
}

function Get-StorageInfo {
    [CmdletBinding()]
    param()

    $outObject = @{
        'ComputerName'      = ''
        'HardwareCategory'  = 'Storage'
        'Info'              = $null
    }

    $outObject
}

function Get-ProcessorInfo {
    [CmdletBinding()]
    param()

    $outObject = @{
        'ComputerName'      = ''
        'HardwareCategory'  = 'Processor'
        'Info'              = $null
    }

    $outObject
}

Primero, volvamos a importar el módulo para asegurarnos de tener la última versión:

Import-Module ComputerInventory -Force

Ahora puedes ejecutar las funciones para ver su salida:

PS> Get-MemoryInfo
Name                           Value
----                           -----
Info                           
HardwareCategory              Memory
ComputerName                  

PS> Get-StorageInfo
Name                           Value
----                           -----
Info                           
HardwareCategory              Storage
ComputerName                  

PS> Get-ProcessorInfo
Name                           Value
----                           -----
Info                           
HardwareCategory              Processor
ComputerName

Cada función devuelve una tabla hash con las propiedades ComputerName e Info vacías, pero con sus respectivas categorías de hardware definidas.

Agregando un parámetro de sesión para soporte remoto

Imagina la necesidad de ejecutar tus scripts en decenas o incluso cientos de computadoras. Si cada función requiriera especificar manualmente un nombre de computadora, sería engorroso y propenso a errores. Afortunadamente, PowerShell Remoting proporciona una solución.

En lugar de un parámetro ComputerName, utiliza un parámetro Session para aprovechar PowerShell Remoting:

function Get-MemoryInfo {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [System.Management.Automation.Runspaces.PSSession]$Session
    )

    $outObject = @{
        'ComputerName'      = $Session.ComputerName
        'HardwareCategory'  = 'Memory'
        'Info'              = $null
    }

    $outObject
}

function Get-StorageInfo {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [System.Management.Automation.Runspaces.PSSession]$Session
    )

    $outObject = @{
        'ComputerName'      = $Session.ComputerName
        'HardwareCategory'  = 'Storage'
        'Info'              = $null
    }

    $outObject
}

function Get-ProcessorInfo {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [System.Management.Automation.Runspaces.PSSession]$Session
    )

    $outObject = @{
        'ComputerName'      = $Session.ComputerName
        'HardwareCategory'  = 'Processor'
        'Info'              = $null
    }

    $outObject
}

Este parámetro garantiza flexibilidad al escalar a múltiples sistemas.

El parámetro de sesión está diseñado para utilizar PowerShell Remoting para ejecutar comandos en computadoras remotas. Esto es lo que lo hace poderoso:

  • Está definido como un parámetro obligatorio que acepta un objeto PSSession (específicamente del tipo System.Management.Automation.Runspaces.PSSession)
  • El parámetro de sesión proporciona automáticamente el nombre de la computadora a través de $Session.ComputerName, que se completa en el objeto de salida

Este enfoque ofrece varias ventajas:

  • Permite una escalabilidad eficiente al trabajar con múltiples sistemas
  • En lugar de crear nuevas conexiones para cada comando, puedes reutilizar la misma sesión para múltiples operaciones, lo cual es más eficiente que establecer conexiones individuales para cada llamada de función
  • Puedes probar las funciones creando una sola PSSession y usándola en todas las funciones de inventario, como se muestra en el ejemplo donde se crea una sesión de prueba con: $testSession = New-PSSession -ComputerName SRV2

Guardar y volver a importar el módulo:

ipmo ComputerInventory -Force

Prueba de las funciones

¿Cómo te aseguras de que un módulo funciona después de construirlo? La prueba es esencial para confirmar que las funciones de tu módulo se comportan como se espera y devuelven datos precisos. Saltarse este paso podría llevar a sorpresas en entornos de producción.

Establecer una sesión remota y probar el módulo:

$testSession = New-PSSession -ComputerName SRV2

Get-MemoryInfo -Session $testSession
Get-StorageInfo -Session $testSession
Get-ProcessorInfo -Session $testSession

Cada función debería devolver un objeto con las propiedades esperadas y el nombre de equipo correcto. Estas funciones son la base de una herramienta de inventario robusta.

Basándonos en el código mostrado, cuando pruebas estas funciones con una sesión remota, la salida se vería algo así:

PS> $testSession = New-PSSession -ComputerName SRV2
PS> Get-MemoryInfo -Session $testSession
Name                           Value
----                           -----
Info                           
HardwareCategory              Memory
ComputerName                  SRV2

PS> Get-StorageInfo -Session $testSession
Name                           Value
----                           -----
Info                           
HardwareCategory              Storage
ComputerName                  SRV2

PS> Get-ProcessorInfo -Session $testSession
Name                           Value
----                           -----
Info                           
HardwareCategory              Processor
ComputerName                  SRV2

Cada función devuelve una tabla hash que contiene el nombre de equipo (de la sesión), la categoría de hardware específica y un campo de Info (actualmente nulo pero diseñado para contener la información real del hardware).

Conclusión

En este artículo, has aprendido por qué es esencial crear tus propios módulos de PowerShell para abordar desafíos únicos que ningún módulo prefabricado puede abordar. Exploramos cómo los módulos personalizados pueden cambiar el juego para configuraciones especializadas o procesos dentro de tu entorno.

Este es solo el comienzo de nuestro viaje con el módulo ComputerInventory. En las próximas publicaciones del blog, ampliaremos esta base añadiendo capacidades reales de recopilación de información de hardware, manejo de errores y funciones avanzadas de gestión remota.

¡Permanezcan atentos mientras transformamos este marco básico en una herramienta poderosa para administradores de sistemas!

Source:
https://adamtheautomator.com/powershell-module-functions/