MSDN Blogs
  • WarNov Developer Evangelist

    Añadir IP a Azure SQL DB con PowerShell

    Azure brinda enormes ventajas; entre ellas, la posibilidad de poder configurarlo y administrarlo desde cualquier parte del mundo. Sin embargo en ambientes como el de SQLDB (antes conocido como SQL Azure) para poder entrar a administrar la DB la ip de nuestra máquina de trabajo ha de estar autorizada; así que cada vez que nos conectamos desde una IP nueva, debemos entrar al portal a autorizarla… y esto me parece una pérdida de tiempo que puede ahorrarse a través de las herramientas de automatización que Azure provee tanto para línea de comandos multiplataforma (Windows, Linux, MacOS) como para PowerShell (únicamente en Windows)

    image

    Las interfaces de comandos cross platform están basadas en JavaScript y requieren de NodeJS; las puedes descargar de aquí:

    Pero; aunque hasta aquí vamos bien, podemos ir mejor! Y es que en Windows, como lo mencioné existe PowerShell que ofrece muchas más utilidades que la simple consola de comandos. Así que también se publicaron los cmdlets (así se llaman los comandos en PowerShell) para esta plataforma y los pueden descargar de aquí. El poder de PowerShell lo lleva hasta a integrarse a Visual Studio 2013, tal como lo ilustro en este post.

    Los nombres técnicos que adquirieron cada uno de estos conjuntos de interfaces fueron azure-sdk-tools para PowerShell y  azure-sdk-tools-xplat  para las consolas cross platform. Y, siguiendo los links citados, podrán observar que además de todo, tanto el código C# para PowerShell como el código JavaScript para xplat ha sido abierto y publicado en GitHub.

    Y bien, ya que los empapé con el contexto que gira alrededor de mi solución para el problemilla aquel de agregar la IP a mi servidor de SQLDB, les comento que decidí usar PowerShell con el fin de aprovechar que ahora puedo editar código PowerShell desde el mismísimo Visual Studio 2013, aprovechando características como IntelliSense y demás que hacen la codificación más agradable. Para lograr esto, instalé PowerShell Tools for Visual Studio 2013, que es una extensión para nuestro editor preferido. (Si quieres saber cómo construir tu propia extensión, haz clic aquí).

    Luego de esto, de una manera bastante cómoda escribí las siguientes líneas de código, que con fines ilustrativos comentaré de manera extensiva:

    #
    # SQLDBAuthCurrentIP.ps1
    #===========================
    #By: @WarNov 7/12/2014 - 18:12
    #This script adds to the Specified SQL DB Server Database the IP
    #of this machine as a new firewallrule
    
    
    
    Param(
    
        #Nombre del servidor SQLDB ej. p5x8y4oi1z    
        [string]$serverName,  
        #Nombre de la regla de firewall que se insertará. A pesar de ser
    #obligatorio en el comando de Azure, en este script es opcional #si se omite, el script produce un GUID como nombre
    #y lo pasa a Azure
    [string]$ruleName, #La ruta donde el archivo *.publishsettings está localizado con
    #la información de la suscripción de Azure a la que accederemos
    [string]$publish ) #Hacemos referencia a la suscripción de Azure, sencillamente
    #importando el archivo



    Import-AzurePublishSettingsFile -PublishSettingsFile $publish #Procesamos el nombre de la regla. Si viene vacío,
    #creamos un GUID. Observen el manejo que se da a los comparadores
    if($ruleName.Length -eq 0){
    #A través de .NET instanciamos la clase guid y asignamos
    $ruleName=[guid]::NewGuid(); } #Ahora obtendremos la ip que queremos agregar. #Dado que no hay forma de obtener la ip externa usada por nuestro
    #cliente es necesario usar una herramienta online que nos informe
    #cual es nuestra ip; en este caso, usaré una que construí yo mismo
    #y que corre en Azure basada en un Generic Handler sencillo de
    #ASP.NET; con esta sencilla línea de código:
    #Request.UserHostAddress #Luego a través de .NET creamos un WebClient #y ejecutamos un downloadstring especificando la url
    $ipAddress=(New-Object Net.WebClient).
    DownloadString('http://warnov.com/@ip')
    #Finalmente ejecutamos el comando principal,
    #que agregará la IP al servidor bajo la suscripción de Azure
    New-AzureSqlDatabaseServerFirewallRule -ServerName $serverName ` -RuleName $ruleName -StartIpAddress $ipAddress `
    -EndIpAddress $ipAddress

    Ya con este script listo, lo podemos ejecutar desde el mismo VS2013 para chequear si hay posibles errores.
    Una vez depurado, lo podemos llamar desde la consola de comandos, pasando como parámetro el nombre del servidor, el nombre de la regla (opcional) y la ruta del archivo de .publishsettings de Azure que se requiere para que tengamos acceso a la suscripción desde nuestra máquina. Este archivo se descarga una sola vez con este comando: azure account download

    Un ejemplo de ejecución:

    image

    Y, como en la mayoría de casos tanto el nombre del servidor como el archivo de settings es el mismo, lo que podemos es hacer otro script que ponga estos parámetros automáticamente por nosotros, así cuando necesitemos agregar la IP solo llamamos a este segundo script sin necesidad de poner parámetros.

    Así pues, hemos visto cómo mediante PowerShell podemos automatizar tediosas tareas como la de agregar la IP a Azure como una regla de firewall cada vez que queremos administrar nuestras bases de datos SQL DB desde una máquina distinta.

    He abierto el código de este pequeño proyecto en Github, donde también podrán encontrar por ejemplo, una rutina que permite borrar todas las reglas de firewall que tengamos para un servidor SQL DB dado, a través de PowerShell:

  • WarNov Developer Evangelist

    PowerShell en Visual Studio 2013


    Nuestra velocidad de vida cada vez aumenta. Y necesitamos hacer más cosas correctamente en el menor tiempo posible. En un escenario de estos, repetir una tarea, un comando, una rutina, me parece cada vez más desgastante.

    A través de la historia de la ingeniería de sistemas, siempre ha existido la manera de programar tareas a través de lenguajes tipo script con los que creamos archivos de procesamiento por lotes; por ejemplo los .bat en Windows. Desde Unix con BASH, hasta Windows con la discreta consola de comandos o el todo poderoso PowerShell (que hasta permite llamar a ejecutarse objetos .NET para desarrollar tareas inimaginables en un entorno de scripting tradicional), están hoy disponibles para que ahorremos nuestro precioso tiempo.

    Precisamente PowerShell siendo tan poderoso, cada vez toma más vigencia hoy en la industria y hasta en la vida de los desarrolladores (ya no es cosa única de IT Pros). Y en este orden de ideas lo primero que un desarrollador pensaría es:

    “… y puedo usar PowerShell desde casa? –o sea: desde el allmighty Visual Studio 2013?…”

    Hoy día me agrada responder que sí; hoy se puede y se pueden entonces aprovechar todas las ventajas de administración de código fuente tanto con git como con TFS, el intellisense, step by step debugging, etc. etc:

    image

    Esto es una maravilla en escenarios complejos en los que tenemos que manejar mucha automatización. Sobretodo ahora con Microsoft Azure, donde casi todas las tareas de configuración las podemos ejecutar a punta de comandos que tienen su representación en PowerShell a través de los azure-sdk-tools.

    Sin embargo esta funcionalidad no viene out of the box hoy en día. Tal vez en un siguiente update o release de VS, tengamos la plantilla para proyectos tipo PowerShell preinstalada. Pero pues… para eso están las extensiones de Visual Studio; en especial, PowerShell Tools for Visual Studio 2013, que es la extensión que por ahora requeriremos para trabajar con PowerShell. (Si quieres saber cómo construir tu propia extensión, haz clic aquí).

    Una vez instalada la aplicación, tendremos el tipo de proyecto PowerShell disponible:

    image

    Y una vez creado, aparece la solución con el proyecto embebido y allí podemos agregar tantos ítems como queramos:

    image

    Cada uno de esos archivos es un script PowerShell que podremos ejecutar desde la línea de comandos o con el mismo PowerShell.

    De hecho cada script se puede ejecutar desde Visual Studio propiamente para poder hacer el debug. Por ahora, el medio de escoger cual script se ejecutará es un poco arcaico, pero efectivo. Y es dar F5 mientras se tiene el foco en el archivo de script abierto que queremos depurar.

    Pues bien, arranquemos con el padre de los programas de ejemplo. El Hello World.

    En PowerShell, se escribe en consola con el comando Write-Host y entre comillas el texto a imprimir (o acaso directamente una variable como $textoAImprimir). Así que abrimos el archivo de script y escribimos:

    #
    # Script.ps1
    #
    Write-Host "hello world"
    pero cuando le damos F5, CRASH!

    [ERROR] . : File Script.ps1 cannot be loaded because running scripts is disabled on this system…

    Esto ocurre porque el scope de ejecución de VS no tiene los permisos para la ejecución de scripts.

    Pero este sencillo fix es suficiente ejecutándolo una sola vez desde Visual Studio:

    Reiniciar Visual Studio, abrir el proyecto de PowerShell, y escribir en el editor la línea

    Set-ExecutionPolicy RemoteSigned

    seleccionar el texto y presionar CTRL+F8  (O clic derecho sobre la línea y escoger ejecutar línea actual).

    Ahora borramos la línea y al presionar F5, todo funcionará sin problemas, porque Visual Studio en adelante tendrá permisos para ejecutar scripts de PowerShell:

    image

    Digamos ahora que queremos algo un poco más avanzado y es averiguar cual es nuestra IP externa. O sea con la que los servidores identifican nuestros llamados. No hay un comando estándar que nos permita saber esto. Entonces podemos recurrir a un servicio web que lo haga, o hacer webscrapping de alguna página web que retorne esta info (como cuando escribimos en el buscador what’s my ip).

    Personalmente, he creado un servicio en uno de mis sevidores de Azure que hace esto. La dirección del mismo es http://warnov.com/@ip

    Si visitan esa dirección, aparecerá un texto con su dirección IP externa.

    Entonces necesitamos un comando que pueda hacer una conexión http y bajar contenido de tipo string. Una alternativa sería instalar curl y hacer el llamado desde PowerShell, cosa que es completamente válida. Pero para darle más matiz al asunto, me permitiré hacer un llamado a .NET para traerme el nunca bien ponderado WebClient y luego decirle que baje un string desde una URL que para ilustración, vendrá dada por un parámetro:


    param
    ( #The URL from which we can obtain our current external IP [string]$serviceURL ) $ipAddress=(New-Object Net.WebClient).DownloadString($serviceURL) Write-Host $ipAddress

    Como se aprecia, hay una sección de param (esto es estándar en PowerShell). Y luego los parámetros se pueden llamar por nombre o ubicación.

    Vemos como a través de New-Object instanciamos una clase .NET. En este caso usando toda la jerarquía, llamamos a Net.WebClient para ser instanciado. Luego, a esa instancia de inmediato le llamamos el método DownloadString y como parámetro le pasamos el parámetro del script.

    Cómo se pasa ese parámetro a Visual Studio?

    Solo basta con darle clic derecho al proyecto en la solución y escoger Properties, lo que nos abre un form para escribir de inmediato los parámetros del script tal como lo haríamos en la línea de comandos:

    image

    Luego de esto ejecutamos, y obtenemos:

    image

    Y así pues, hemos creado un script usando todo el poder de Visual Studio. Además, podemos adicionarlo a git o TFS y tener todas las otras ventajas de trabajar con este poderoso IDE.

    Luego, solo basta acceder el script con PowerShell y ejecutarlo!

    image

    Es así como hemos visto la manera en la que podemos trabajar con PowerShell desde Visual Studio, ahora que será cada vez más frecuente la necesidad de usar esta herramientas en entornos de configuración y automatización. Vimos como es posible pasar parámetros al script y como ejercicio les dejo que pongan un breakpoint y vean como la ejecución se detiene y pueden evaluar el valor de las variables, como si fuera una aplicación típica de Visual Studio.

  • WarNov Developer Evangelist

    Cómo crear extensiones para Visual Studio 2013 (vsix)

    Andaba yo por ahí dando Soporte a uno de mis SaaS que tengo sobre Azure, cuando noté que era muy molesto que dado que el internet 4G que tengo me cambia en todo momento la IP, entonces siempre tenía que meterme al portal a agregar una nueva regla de firewall para poder acceder a administrar la SQL DB desde mi máquina local.

    Entonces se me ocurrió escribir un script en powershell que hiciera esa tarea en batch, de manera de que ya me podría ahorrar mucho tiempo. Además me motivó el hecho de que ahora en VS2013 tenemos un excelente plugin que nos permite desarrollar sobre PowerShell directamente desde Visual Studio.

    Pues bien, acabé de hacer mi script, e iba a pasar a poner en la documentación la fecha en la que fue creado. Pero oh sorpresa cuando not�� que no tenía ni idea de cuál era la fecha en la que estábamos. Así que miré en el teléfono y vi que no podía hacer copy paste de esa fecha.

    Y bueno, abrí notepad para presionar F5, pues esto inserta la fecha y hora actual en el editor y podría copiar y pegarla en Visual Studio. Pero sucede que reemplacé Notepad por Notepad++ y este último tampoco tiene esa funcionalidad.

    Así que para nunca tener que volver a pasar por esta inmensa agonía, decidí escribir mi propia macro para Visual Studio 2013, que insertara la fecha y hora… pero; momento, las macros ya no están en Visual Studio 2013. Así que a hacer una extensión se dijo.

    Afortunadamente hoy a diferencia de cuando yo hacía las extensiones para un lenguaje de programación que estaba creando llamado APL.NET por allá en 2005, crear extensiones para VS es muy sencillo. Y obviamente, se puede a punta de código administrado.

    Basta descargar el SDK de Visual Studio 2013 que es de apenas unos cientos de megas. Después de esto ya en el mismísimo Visual Studio 2013 tendremos unas nuevas plantillas de proyecto para extensibilidad:

    image

    Las opciones son enormes. Pero para comenzar, crearemos un Visual Studio Package. Con esto será suficiente para crear la extensión que inserta un timestamp en el editor de código de Visual Studio 2013.

    Esto nos lleva a un Wizard donde primero escogemos el lenguaje y firmamos el assembly con una llave propia o una autogenerada. La autogenerada funciona bien.

    image

    Luego agregamos la información básica de nuestra extensión:

    image

    Ahora escogemos las funcionalidades ofrecidas por nuestra extensión. Como solo quiero insertar la fecha y la hora, un comando de menú basta

    image

    Asignamos un nombre programático y uno descriptivo para nuestro comando. El nombre descriptivo es el que aparecerá en el menú Tools de Visual Studio 2013 para que al hacerle clic, la fecha y hora se inserte en nuestro editor:

    image

    El soporte a testing está incluido si lo deseamos. Por ahora no lo incluiré y sencillamente daré Finish:

    image

    Obtenemos entonces una solución nueva con esta estructura:

    image

    El archivo que seleccioné es el core de nuestro comando y allí es donde lo vamos a implementar.

    Si alguna vez escribieron macros para VS con VB, recordarán el famoso objeto DTE (Development Tool Environment). Este es el objeto que encapsula toda el modelo de objetos de automatización de Visual Studio. Así que recurriremos a él para poder intervenir en el editor de código.

    El assembly que lo incluye (EnvDTE) ya viene referenciado por el wizard. Así que solo basta incluir el Namespace.

    using EnvDTE;

    Ahora buscamos el método MenuItemCallback y borramos el código por defecto que incluye.

            private void MenuItemCallback(object sender, EventArgs e)
            {
                
            }

    El código que escribamos dentro de este método será el que se ejecute cuando el usuario le hace clic al comando. Copiaré aquí todo el código con extensos comentarios para que observen como trabajé la extensión:

    private void MenuItemCallback(object sender, EventArgs e)
    {
    //Obtenemos una referencia al objeto DTE


    DTE dte = GetService(typeof(DTE)) as DTE;
    //El objeto DTE tiene un documento activo y es aquel
    //archivo de código sobre el que estamos
    //trabajando actualmente. Este documento activo tiene
    //varios objetos sobre los que podemos actuar. Aquí como
    //modificaremos el texto, hacemos referencia al contenido
    //de texto del documento activo:
    TextDocument objTextDoc =
    dte.ActiveDocument.Object("TextDocument")
    as TextDocument;

    //Este objeto de tipo TextDocument tiene un atributo
    //llamado Selection que como su nombre lo indica, nos
    //permite acceder al texto seleccionado en el editor.
    //De esta manera nos permite cambiarlo. Si no hay texto

    //seleccionado, entonces nos retorna cadena vacía.
    //Qué pasaría si cambiamos el texto en este caso?
    //Correcto, se inserta un nuevo texto en la posición actual
    //del cursor. Entonces sencillamente procedemos:
    objTextDoc.Selection.Text = String.Concat(DateTime.Now.ToShortDateString(),
    " - ",
    DateTime.Now.ToShortTimeString()); }

    Y bien, apuesto que muchos de ustedes jamás pensaron que fuera tan fácil escribir una extensión para Visual Studio 2013.

    Ahora, para probar la extensión, en Visual Studio siempre hemos tenido una gran característica que es la instancia experimental de Visual Studio. De manera que nuestras extensiones propias no vayan a dañar nuestra instalación en producción de Visual Studio. O sea que si ejecutamos este proyecto, se abre otro Visual Studio (experimental) y la extensión se ejecuta solo sobre este último (imagínense un “emulador” de VS). El debug se hace idéntico a el que se haría con cualquier tipo de aplicación convencional:

    image

    Y el resultado de hacer clic sobre el comando:

    image

    Ahora solo basta compilar ir a la carpeta bin por nuestro archivo .vsix, que es auto instalable en los sistemas con Visual Studio 2013:
    image

    Si le damos doble clic, nuestra extensión se instalará ahora sí en nuestra versión de producción de Visual Studio y ya no tendremos problema porque no sabemos en qué fecha estamos cuando vayamos a poner un timestamp! Smile

    He abierto el código fuente de esta solución y lo puedes encontrar en mi cuenta de Github:

    Por si fuera poco, si queremos compartir la extensión, la podemos subir gratuitamente a la Galería de Visual Studio donde miles de desarrolladores tendrán acceso a ella. El proceso es muy sencillo y permite además de subir la extensión ponerle tags para que por ejemplo cuando un desarrollador busque insert timestamp, obtenga resultados: 

    image

    Es más, si desde dentro de Visual Studio el developer entra a Tools->Extensions and Updates, nuestra extensión también queda disponible:

    image

    Es una excelente forma de compartir con la comunidad!!!

  • WarNov Developer Evangelist

    Usar Visual Studio 2013 con Github

    Este párrafo solo es para dar una ligera indicación de la manera más cómoda para trabajar nuestro código a ser creado con VS2013, hospedándolo en Github, sobretodo al iniciar un nuevo desarrollo.

    En este caso solo es necesario crear el repo en Github. Luego de allí sacamos la url del mismo:

    image

    Después de esto fijamos la carpeta local sobre la que queremos trabajar la solución. Una vez fijada, en Visual Studio ejecutamos el clone ANTES de crear la solución:

    Abre el Team Explorer y selecciona conexiones:

    image

    Y ejecuta estos pasos:

    image

    1. Pegar la URL del repo
    2. Ubicar el folder local
    3. Clonar el repo

    image

    Solo después de la clonación, creamos la nueva solución. Primero escogemos el repo recientemente clonado:

    image

    Y entonces tendremos la opción de asociarle una nueva solución:

    image

    Luego de crear la solución de inmediato aparece el Solution Explorer, con todos los elementos nuevos (observa el símbolo + ) listos para hacer commit y posteriormente push a Github:

    image

     

    De esta manera, ya tendríamos sincronizada nuestra nueva solución con Github, lista para trabajar.

Page 1 of 1 (4 items)