PowerShell: Crear un módulo binario

Unas de las cosas maravillosas de PowerShell es poder generar nuestros propios módulos personalizados. Esto nos permite poder agrupar nuestras funciones, con nuestros nombres y características particulares de la misma manera que los módulos tradicionales (por ejemplo: ActiveDirectory, ServerManager, etc.)

Hay varios tipos de módulos (dejo enlace a la TechNet para tener más información sobre este concepto) que podemos construir en PowerShell, pero en este post en particular, pretendo enfocarme solamente en los módulos binarios utilizando C#.

Éstos módulos van a ser generados por medio de Visual Studio (para los que no sabían, existe una versión gratuita para descargar: Visual Studio Community 2015)

Nuestro módulo va a estar compuesto por una única función, la cual nos va a permitir revisar la disponibilidad de un dominio para utilizar en Office365 (este tema lo tratamos en un post anterior: Comprobar disponibilidad de dominio).

Ya teniendo instalado Visual Studio, lo primero que tenemos que hacer es crear un proyecto nuevo

Dentro de C# seleccionamos Class Library y escribimos el nombre de nuestro módulo: PowerShellRules en mi caso.

Con el proyecto creado, vamos a agregar una referencia para poder crear nuestros cmdlets. La referencia en cuestión es

System.Management.Automation

Para poder agregar esta referencia, utilizaremos NuGet.

Accedemos al menú Tools > NuGet Package Manager > Package Manager Console.

En la consola escribimos:

Install-Package System.Management.Automation

Al finalizar el proceso, podemos examinar que se encuentra ya declarada y agregada:

Esto sería lo básico para poder empezar a trabajar, pero como nosotros ya sabemos que vamos a hacer debemos agregar otra referencia, ahora es la System.Net que nos permite hacer lo siguiente: Utilizar las clases WebRequest y WebResponse.

Para poder agregar esta referencia, clic derecho sobre References y seleccionamos Add Reference…

Buscamos y seleccionamos System.Net como muestra la imagen

Y ahora empezamos a escribir nuestro primer comando de PowerShell!!

Empezamos escribiendo:

[Cmdlet(VerbsCommon.Find, "O365Domain")]
public class FindO365Domain : PSCmdlet
{

}

Donde declaramos el verbo que vamos a utilizar en el nombre de nuestro Cmdlet (para los que no se acuerdan, la mayoría de los Cmdlets tienen la estructura de “Verbo_–_Sustantivo“). En este ejemplo el sustantivo es “O365Domain”. Luego definimos la clase que hace referencia a este Cmdlet, para ello simplemente escribimos el verbo y sustantivo todo junto.

Esta función va a tener un único parámetro, llamado “Domain”, para declararlo, generamos una variable auxiliar

private string[] domainName;

Y luego el parámetro de la siguiente forma:

    [Parameter(
        Mandatory = true,
        ValueFromPipelineByPropertyName = true,
        ValueFromPipeline = true,
        Position = 0,
        HelpMessage = "Nombre de dominio a chequear."
    )]
    [Alias("Tenant")]
    public string[] Domain
    {
        get { return domainName; }
        set { domainName = value; }
    }

Ok, hasta ahora declaramos el parámetro “Domain” (con el alias Tenant) y obligatorio.

Simplemente antes de escribir el cuerpo del comando, vamos a recordar que para nosotros saber si un nombre de dominio para Office365 se encuentra utilizado, tendríamos que acceder a la siguiente dirección y obtener de respuesta un archivo xml:

https://login.windows.net/.onmicrosoft.com/FederationMetadata/2007-06/FederationMetadata.xml

Recordando estopodemos imaginar como resolverlo: Si obtenemos una respuesta correcta a un dominio, ya está utilizado, en C# sería algo así:

    protected override void ProcessRecord()
    {
        foreach (string domain in domainName)
        {
            WriteVerbose("Revisando la disponibilidad del dominio: " + domain);
            string addressCheck = "https://login.windows.net/" + domain + ".onmicrosoft.com/FederationMetadata/2007-06/FederationMetadata.xml";
            try
            {
                WebRequest request = WebRequest.Create(addressCheck);
                WebResponse response = request.GetResponse();
                WriteObject("");
                WriteObject(domain + ": Dominio en uso.");
                WriteObject("");
                response.Close();
            }
            catch (WebException ex)
            {
                if (ex.Status == WebExceptionStatus.NameResolutionFailure)
                {
                    WriteObject("");
                    WriteObject(domain + ": Dominio disponible.");
                    WriteObject("");
                }
                WriteObject("");
                WriteObject(domain + ": Dominio disponible.");
                WriteObject("");
            }
        }
    }

Ok. Tenemos la función, ahora tenemos que construir la .dll para poder probarla.

Utilizando la combinación de teclas Ctrl + Shift + B armamos el módulo. Este proceso nos va a devolver una ruta como la siguiente:

C:\Users\Victor\documents\visual studio 2015\Projects\PowerShellBinaryRules\PowerShellBinaryRules\bin\Debug\PowerShellRules.dll

Ahora abrimos una consola de PowerShell y ejecutamos:

Import-Module "C:\Users\Victor\documents\visual studio 2015\Projects\PowerShellBinaryRules\PowerShellBinaryRules\bin\Debug\PowerShellRules.dll"

Ya tenemos nuestro módulo cargado! Podemos comprobarlo ejecutando:

Get-Module

Ahora que sabemos que el módulo está en el sistema, podemos ejecutar un ejemplo con 2 nombres (el primero un invento y el segundo es el que yo tengo registrado):

Saludos, y feliz scripting!

Comments