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 https://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.