Actualidad

08/07/2020

/ , , , , ,

Cuatro formas de automatizar con estilo usando PowerShell

PowerShell es la línea de comandos ubicua de Microsoft. Con los años, este lenguaje lanzado en 2006 se ha convertido en mi principal herramienta para moverme por el “Universo Microsoft”.

Todo lo puede, para todo sirve y siempre está a mano, como el destornillador del Doctor Who. Y aunque es cierto que en los últimos tiempos Microsoft ha abierto el abanico a otras líneas de comandos, como Azure CLI (AZ) para Azure o Bash para Azure y WSL, PowerShell aún sigue teniendo una posición muy sólida en el ecosistema, e incluso mejor desde el lanzamiento en 2016 de la versión multiplataforma (Mac OS, Linux): PowerShell Core.

Pero vayamos al grano. Puede que tu día a día sea una sucesión de scripts, probablemente rápidos, pero ¿qué pasa cuando son largos? ¿Qué haces si tienes que esperar a completar una o varias tareas que pueden llevar 10, 20 o 60 minutos?

Para estos casos, he depurado estrategias de notificación para ignorar el script hasta que algo relevante suceda. Esto es particularmente útil cuando tienes varios scripts pendientes, u otros proyectos, o una video llamada en curso. 😉

Las comparto en este artículo, sin un orden en particular, para que puedes aprovecharlas en tu día a día, por utilidad, o por mera diversión: 3 estrategias de notificación y 1 sorpresa.


8 bits

En PowerShell puedes implementar avisos sonoros como los de las videoconsolas de 8 bits de los años 80. Así identificas de oído si tu script ha llegado a alguna etapa importante.

Es como un Write-Host sónico. Además, la implementación es super sencilla:

[console]::beep(500,300)

El ejemplo muestra cómo reproducir un sonido de 500 hertzios y 300 milisegundos. Más hertzios, más agudo. Más milisegundos, más duración.

Fun Fact: ¿Sabías que 440 hertzios es la frecuencia que se emplea como sonido de referencia para afinar de instrumentos como el piano o el violín? ¡Puedes afinar tu guitarra o violín usando cualquier PC con Windows!

Por supuesto puedes jugar con las duraciones y frecuencias (aunque no del todo con el ritmo) para formar diferentes «códigos» o incluso melodías famosas. Por ejemplo:

Star Wars – Imperial March, de John Williams

[console]::beep(440,500)
[console]::beep(440,500)
[console]::beep(440,500)
[console]::beep(349,350)
[console]::beep(523,150)
[console]::beep(440,500)
[console]::beep(349,350)
[console]::beep(523,150)
[console]::beep(440,1000)
[console]::beep(659,500)
[console]::beep(659,500)
[console]::beep(659,500)
[console]::beep(698,350)
[console]::beep(523,150)
[console]::beep(415,500)
[console]::beep(349,350)
[console]::beep(523,150)
[console]::beep(440,1000)

Visto en: Music from the Command Line:Performed by Powershell

Los Vengadores – Assemble, de Alan Silvestri

[console]::beep(440,1800) [console]::beep(440,200) [console]::beep(440,600) [console]::beep(660,100) [console]::beep(580,1200) [console]::beep(520,800) [console]::beep(490,800) [console]::beep(440,1200)

[Nota: Melodía sacada de oído por mí]

Juegos de Guerra (1983)

Los veteranos del software como yo, recordareis la película «Juegos de Guerra» protagonizada por Matthew Broderick. En ella una IA llamada WOPR trataba de iniciar una guerra termonuclear por culpa de una red mal segmentada y un hacker. Hay muchas lecciones sobre ciberseguridad e IA en esa película.

Una de las cosas que recuerdo es la voz de la WOPR. Pero desde hace décadas, con el API de voz de Windows (si lo tienes configurado) puedes tener algo parecido en tus scripts usando estos comandos:

$text = "Extraño juego, la única manera de ganar es no jugar."
$object = New-Object -ComObject SAPI.SpVoice
$object.Speak($text) | Out-Null

[Referencia friki obligada: https://www.youtube.com/watch?v=FboBAFiLDbI]

Por supuesto puedes jugar con bastantes parámetros como la velocidad, otras voces e idiomas. Pero eso añade complejidad al script.

En resumen, puedes emitir información compleja y descriptiva de lo que va sucediendo durante la ejecución de tus scripts sin tener que prestarle atención. O leer archivos de texto de forma automática. O gastar bromas.

Este API tiene muchas posibilidades y PowerShell lo pone fácil. ¿Podrá integrarse con Alexa o Siri?


Alertas en Windows 10

En Windows 10 hay dos formas típicas de notificar algo al usuario: mediante un cuadro de diálogo y mediante el centro de notificaciones.

Para lanzar un molesto, pero efectivo cuadro de diálogo, no tenemos más que poner:

Add-Type -AssemblyName PresentationFramework #Ensamblado para la sesión.
[System.Windows.MessageBox]::Show('CPE1704TKS ?')

Esto nos permite explorar nuevas opciones de control de nuestros scripts, como por ejemplo recibir una notificación sobre si continuar una acción, o no, en lugar de solamente notificar algo.

Para ello tenemos una amplia gama de opciones de MessageBox como:

$msgBoxInput = [System.Windows.MessageBox]::Show('¿Una partidita de ajedrez?','WOPR','YesNoCancel','Error')
Write-host "Profesor Falken dijo:"$msgBoxInput

Pero también podemos emplear elementos de consola más avanzados como el Out-GridView con la opción -PassThru:

$myList = @("Tic, tac, toe","Chess","Global thermonuclear war")
$selection = $myList | Out-GridView -Title "Select a game" -PassThru
Write-host "Lets play:"$selection

Por último, en Windows tenemos algo más moderno y algo menos intrusivo como el centro de notificaciones, que funciona como el de un móvil y que no interrumpirá nuestro flujo de trabajo o reunión en curso. Aunque parece una buena opción, la generación de notificaciones es bastante más compleja y requiere de procesos adicionales para no acabar llenando de basura la barra de tareas.

Add-Type -AssemblyName System.Windows.Forms #Ensamblado para la sesión.

$global:balloon = New-Object System.Windows.Forms.NotifyIcon
$path = (Get-Process -id $pid).Path
$balloon.Icon = [System.Drawing.Icon]::ExtractAssociatedIcon($path)
$balloon.BalloonTipIcon = [System.Windows.Forms.ToolTipIcon]::Info
$balloon.BalloonTipTitle = "General Kenobi says..."
$balloon.BalloonTipText = 'Hello there!'
$balloon.Visible = $true
$balloon.ShowBalloonTip(5000)

Resumiendo, Windows y PowerShell nos ofrecen muchas opciones para gestionar notificaciones nativas, con relativa facilidad.


Epílogo: Like a boss

Como hemos podido comprobar, los scripts largos no tienen por qué ser aburridos, ni consumir tu atención y tu valioso tiempo. Basta con echarle algo de imaginación y emplear la vasta lista de posibilidades que ofrece PowerShell para facilitar nuestro trabajo.

Por mucho hype que haya con C#, JavaScript o Go, a menudo PowerShell puede ser la solución más rápida, compatible y con mejor TCO, para resolver problemas o automatizar procesos.

Y hasta aquí este artículo. Me despido con un meme en PowerShellNever gonna give you up, de Rick Ashley.

Que por supuesto puedes incluir en tus scripts. Pero ojo con el volumen del audio al ejecutar esto:

iex (New-Object Net.WebClient).DownloadString("http://bit.ly/e0Mw9w")