El icono del programador de tareas de WindowsPowerShell es el más que digno sucesor de la línea de comandos de Windows. Aparecido en noviembre de 2006, de hecho, ya hace tiempo que existe también para macOS y para Linux (desde 2016). Es infinitamente más potente y se basa en pequeños programas escritos en C# llamados cmdlets. En la actualidad se usa para casi todo pero es indispensable para gestionar profesionalmente los productos de Microsoft, ya que toda su gestión se basa generalmente en cmdlets de PowerShell.

Si te interesa aprenderlo, hace ya unos cuantos años que hice un tutorial de iniciación, y en este mismo blog tengo varios trucos basados en el uso de PowerShell.

El caso es que, a pesar de llevar danzando por Windows justo ahora 15 años, algunas de las partes más antiguas del sistema no se llevan todavía bien con él 🤦🏻‍♂️

Una de esas partes es el programador de tareas de Windows. Este software tan útil y tan esencial (sobre todo en servidores) debe de llevar más de 2 décadas sin tocarse más que para corregir bugs (y no todos), creo yo. Ya he hablado aquí también de otros de sus problemas.

El problema con los scripts PowerShell

Aunque PowerShell está muy bien para lanzar comandos sueltos de administración, la mayor parte de las veces lo que necesitaremos es crear scripts más complejos, con varias líneas de código y combinando acciones, como algunos de los que he compartido aquí, que mencionaba antes.

Estos scripts tienen la extensión .ps1 y Windows incluso tiene un pequeño editor o IDE para crearlos: el PowerShell ISE:

El icono de PowerShell ISE al buscarlo en el menú de inicio de Windows 11

que te ayuda con las funciones, a probar, etc... y cuyo aspecto es el siguiente:

El entorno de edición de Script, ISE

Una vez que has creado un script PowerShell que quieres ejecutar periódicamente, en la tarea programada lo normal es que, en las acciones, metas tan solo la ruta al archivo .ps1 en cuestión. Al fin y al cabo, como pasa con los .bat que se asocian a cmd.exe, éstos están asociados a powershell.exe ¿no? Pues no. Aunque estás asociados, no funcionan y tu tarea no se ejecutará correctamente.

Vale, pues lo siguiente que todo el mundo prueba es emplear el parámetro -file de PowerShell que sirve para indicar explícitamente la ruta de un archivo .ps1 que queramos ejecutar. Por ejemplo, este es powershell.exe ejecutando un script que tengo en algunos servidores y que sirve para detectar el espacio libre en todos los discos y avisar por email si baja de un determinado umbral:

powershell.exe -file ruta-al-archivo.ps1

¡Estupendo! Sin embargo, el problema es que cuando metes esto en la acción de tu tarea programada, al darle a ejecutar el script jamás se ejecuta y además queda en ejecución, como congelado, para siempre jamás. Otro fiasco...

¿Entonces qué podemos hacer?

Internet está lleno de artículos que te dicen que le pongas el parámetro en la ruta, o el parámetro por separado, o que pongas en la ruta de ejecución la ruta en la que está el script, etc... Ninguna de estas recetas funciona.

La única solución que he encontrado válida en todos estos años es un poco más enrevesada.

Consiste en poner tan solo powershell.exe como comando y usar el script como comando mediante el parámetro -Command. Además, conviene decir que no cargue el perfil del usuario (salvo que sea estrictamente necesario por algo), decirle que no es un script interactivo (de modo que no se vaya a interrumpir nunca la ejecución con la interfaz de usuario) y que quite las restricciones a la ejecución.

Es decir, lo que debemos hacer es pasarle estos parámetros:

-NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command "& ruta al script a ejecutar"

Pero, y aquí hay un gran pero, el verdadero truco está en que para que el script funcione debemos precederlo con un "et" o "ampersand" (&) o no funcionará.

Este es el aspecto de una de mis tareas programadas que usa un script .ps1 en un servidor:

Aspecto de la tarea (Action) en el programador

Fíjate en cómo tras el -Command empieza la ruta del script, pero tiene el & delante, justo después de las comillas que abren el parámetro. O más en detalle al editarlo:

Aspecto de la tarea al editarla

Es importante que el & esté entre las comillas. Este símbolo es especial para PowerShell. Se llama operador de llamada y sirve para indicar al parámetro que lo que se va a ejecutar es un script obtenido de un archivo o de un bloque de texto.

Esta es la única manera que conozco que esto funciona en el programador de tareas de Windows Server. La verdad es que Microsoft debería ponerse las pilas con esto y facilitarnos la vida a los que administramos algún sistema que otro. No parece tan difícil de arreglar ¿verdad Microsoft?

¡Espero que te resulte útil!

Escrito por un humano, no por una IA