PowerShell Basics: Módulos

¡Hola a todos! Hoy se publica una nueva entrega de la saga PowerShell Basics, en la que se habla (o escribe) de una de las formas más comúnmente utilizadas para extender la funcionalidad de la Shell: Los Módulos. Como los demás artículos de esta serie, el objetivo principal es acercar esta herramienta, e intentar facilitar su incorporación al scripting diario de aquellos que aún no la conozcan. Sin más dilación, toca empezar con la teoría:

¿Qué es un módulo?

Es una agrupación de funcionalidades interrelacionadas de PowerShell, que son susceptibles de ser referenciadas o cargadas dinámicamente. Entre las utilidades que proporcionan se pueden encontrar cmdlets, proveedores, funciones, alias, etc. Esto permite ampliar la funcionalidad de PowerShell, ya sea agregando un proveedor al que antes no se tenía acceso, o proporcionando cmdlets necesarios para realizar tareas específicas.

Tipos de módulos

Los módulos más habituales son de los tipos binario, script y manifiestos de módulos.

Módulos Binarios

Son ensamblados .NET (.dll) que contienen código compilado. Los desarrolladores pueden usar los lenguajes presentes en la plataforma .NET, como por ejemplo C#, para crear cmdlets, proveedores… prácticamente cualquier funcionalidad de PowerShell.

Módulos Script

Son archivos de texto con una extensión particular (.psm1) cuyo contenido es cualquier tipo de código PowerShell válido. Los administradores de sistemas y desarrolladores de scripts pueden usar este modelo para crear módulos cuya funcionalidad incluya funciones, variables, alias…

Manifiestos de módulos

Un manifiesto de módulo describe los contenidos del módulo y determina cómo procesarlo. Es un archivo de texto, y se usa tan fácilmente como copiándolo en la raíz de la carpeta del módulo. Información como el autor, versión, etc. quedan visibles de este modo para PowerShell.

Más adelante se detalla con un ejemplo cómo crear tanto un módulo de script como su manifiesto.

Cómo trabajar con Módulos

Carga/Descarga

Desde la versión 3.0, PowerShell es capaz de descubrir los CmdLets/Funciones disponibles en todos los módulos disponibles, para proceder a cargar el módulo adecuado cuando se invoque una función perteneciente al mismo por primera vez. En versiones anteriores, por contra, era necesario cargar explícitamente el módulo en cuestión antes de que toda o parte de su funcionalidad estuviese expuesta, para lo que se utilizaba el cmdlet Import-Module <nombremodulo>.

Para ilustrar la carga dinámica de módulos, nada mejor que acudir a la siguiente captura de pantalla. En ella se muestra cómo se pueden descargar todos los módulos de memoria, y cómo al invocar un cmdlet  (New-RandomPassword, una función incluída en un módulo de Script) se carga el módulo correspondiente, así como los módulos que éste invoca.

image

Además, para aquellos que se sientan curiosos, siempre es posible escribir Get-Module –ListAvailable , que les va a dar una lista completa con todos los módulos instalados y disponibles en el sistema.

image

Por supuesto, si se hace un get-module –name <mod> | fl de un módulo determinado, se va a obtener información adicional con respecto al módulo en cuestión.

Creación de un Módulo del tipo Script

Los módulos más fáciles de crear para un administrador de sistemas suelen ser los del tipo script, ya que no se diferencian demasiado de un script que esté bien organizado. En primer lugar, lo más importante a la hora de crear un módulo es saber dónde guardarlo para poder usarlo a posteriori. Esto lo podemos descubrir en cualquier momento gracias a la variable $env:psmodulepath, que nos dice en qué carpetas PowerShell va a acudir a buscar módulos para cargar.

image

Una vez se sabe dónde es posible guardar módulos, ya sólo falta escribirlo. La creación de un módulo de script difiere con respecto a éstos en que nunca se va a utilizar de forma interactiva. Mientras un script se va ejecutando, es posible programar interacciones con el usuario, de forma que el script actúa como un único programa. Por contra, en los módulos, lo que sucede es que las funciones escritas en el módulo pasan a estar integradas en la Shell, de forma que  pasan a ser bloques únicos e independientes.

Por ejemplo, el módulo PlainIT, tiene una variable $variable, tres funciones Set-Title, Get-WinVersion y ab (cuyo único motivo de existencia es este artículo). Las funciones se definen como unidades independientes, o bien pueden hacer llamadas a otras, sean parte de éste u otro módulo. En todo caso, el código ejecutable debe quedar siempre encapsulado dentro de una, y nunca quedar “suelto”. En un script normal, este “código suelto” es necesario para el funcionamiento del mismo, pero en un módulo, lo que se expone son las partes del script, para poder trabajar de una forma más flexible.

image

Aunque no son obligatorios, incluir un manifiesto en el módulo suele ser una buena idea. Especialmente si se va a distribuir el módulo, o se quiere llevar un control más preciso de la versión de cada uno de ellos. Como vimos en el Get-Module –ListAvailable, el número de versión que se haya definido en el manifiesto se publica junto a la definición del módulo. Esto ayuda a identificar qué versión de un módulo cargar, siempre que varias versiones del mismo estén coexistiendo en el sistema, sea por el motivo que sea (por ejemplo, que haya cambios mayores en la versión más reciente, y la anterior sea necesaria por motivos de retrocompatibilidad)

image

Como ya vimos, se había definido una función llamada ab, y su motivo de existencia era este artículo. Su misión: Ayudar a comprender el alcance de las variables del módulo. Se puede observar en la captura de pantalla con el código del módulo que hay una variable fuera de una función, llamada (de forma harto ingeniosa) $variable. Un lector avispado puede pensar que eso es una forma ideal de tener constantes definidas para la shell. A fin de cuentas, se definen las variables en un módulo, se carga el módulo et voilà… Pues no. Las variables definidas fuera de una función se quedan definidas dentro del ámbito del módulo. Esto viene a ser que, desde la Shell, no se pueden acceder “directamente”, pero sí que están disponibles para todas las funciones del módulo. En resumen: Se convierten en valores globales accesibles por todas las funciones/cmdlets del módulo.

image

Conclusión

Y con esto, se ha tratado en grandes rasgos qué son los módulos, sus tipos. dónde encontrarlos, la forma de descubrirlos, cómo crearlos… Y en definitiva, todo lo necesario para incorporarlos al conjunto de herramientas que todo Scripter de PowerShell necesita saber.

En definitiva, se puede vivir sin crear módulos personalizados, pero usarlos hace que la vida sea más fácil.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *