Contents

Ejecutar script de PowerShell como servicio de Windows

Lo más habitual cuando ejecutamos un script de PowerShell es que o bien lo ejecutemos a mano o bien lo hagamos automáticamente de forma periódica ejecutando PowerShell como tarea programada. En la entrada de hoy veremos un tercer escenario, ‘instalaremos’ un script de PowerShell como servicio de Windows.

¿Por qué ejecutar un script de PowerShell como servicio?

Si bien PowerShell no está diseñado para este tipo de uso, eso no quiere decir que no podamos hacerlo. Ejecutar un script de PowerShell como servicio de Windows nos va a permitir** tenerlo corriendo las 24 horas** del día y nos va a asegurar que si por cualquier motivo la máquina que lo ejecuta sufre un reinicio éste vuelva a ejecutarse.

/wp-content/uploads/2018/11/Servicio.png
Powershell como servicio de Windows

Conociendo NSSM

NSSM (the Non-Sucking Service Manager) es una pequeña aplicación que nos va a permitir ejecutar cualquier binario como servicio de forma muy sencilla. Para nosotros el binario será el ejecutable de PowerShell que llamará al script que vamos a ejecutar.

Podemos descargar NSSM desde su página web. Como es una aplicación portable lo que descargaremos será un zip con la versión de 32bits y la de 64. Para hacer el proceso más sencillo podemos descomprimir el ejecutable directamente en C:\Windows\System32 para asegurarnos de que lo tenemos en nuestro PATH.

Diseñando el script de PowerShell

Tenemos que tener en cuenta que no cualquier script de PowerShell es apto para ser ejecutado como servicio. Necesitamos que la ejecución de nuestro script nunca finalice, porque de hacerlo simplemente nuestro servicio se pararía. Para no finalizar nunca la ejecución del script podemos valernos de un simple While:

1
2
3
4
# Creamos un bucle infinito para que la ejecución del script se mantenga
while ($true) {
    # Aquí dentro ejecutamos nuestro código
}

Otra cosa que deberemos tener en cuenta es cada cuanto queremos que se ejecute el bucle. Si el contenido de nuestro script realizara tareas demandantes de recursos y volviera a ejecutarse justo después de finalizar nos podríamos encontrar con que consumiera gran cantidad de recursos de nuestra máquina de forma continuada. Es por ello que es buena idea añadir un tiempo de espera después de cada ejecución que vendrá determinado por la acción que vaya a realizar el script:

1
2
3
4
5
6
7
# Creamos un bucle infinito para que la ejecución del script se mantenga
while ($true) {
    # Aquí dentro ejecutamos nuestro código

    # Paramos la ejecución durante 60 segundos
    Start-Sleep -Seconds 60
}

Para esta entrada vamos a hacer un script que se asegure de que el servicio spooler siempre esté ejecutándose, algo que a priori no parece muy útil pero que puede ser útil con algún otro servicio con tendencia a caerse.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Creamos un bucle infinito para que la ejecución del script se mantenga
while ($true) {
    # Obtenemos el servicio Spooler
    $Servicio = Get-Service -Name spooler
    # Si tiene estado stopped lo volvemos a iniciar
    if ($Servicio.Status -eq 'stopped') {
        $Servicio | Start-Service
    }
    # Paramos la ejecución durante 60 segundos
    Start-Sleep -Seconds 2
}

‘Instalando’ el script de PowerShell como servicio de Windows

Ahora que ya tenemos instalado NSSM y tenemos a punto nuestro script de PowerShell podemos pasar a ‘instalarlo’ como servicio. Para ello abrimos una consola de PowerShell como administrador (también podríamos hacer esto desde cmd) y vamos a definir las variables que necesitaremos pasarle a NSSM:

1
2
3
4
5
6
7
8
# Nombre que daremos a nuestro servicio
$NombreServicio = 'Sobrebits'
# Ruta del ejecutable de PowerShell
$RutaPowershell = 'C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe'
# Argumentos a pasar al ejecutable de PowerShell:
# ExecutionPolicy para asegurarnos de que no se bloquea la ejecución del script
# File donde indicamos la ruta de nuestro script
$Argumentos= '-ExecutionPolicy Unrestricted -File C:\Scripts\Servicio_PowerShell.ps1'

Y por último ejecutaremos nuestro NSSM con las variables que acabamos de crear:

1
nssm install $NombreServicio $RutaPowershell $Argumentos

Si todo ha ido bien ya deberíamos ver ‘instalado’ nuestro script de PowerShell como servicio así que solo haría falta arrancarlo y ver si funciona:

/wp-content/uploads/2018/11/ServicioSobrebits.png
Servicio Sobrebits

Si queremos eliminar el servicio siempre podemos hacerlo mediante:

1
nssm remove $NombreServicio confirm

Conclusión

Ejecutar un script de PowerShell como servicio de Windows abre un abanico aún más grandes de automatización a nuestros sistemas, así que espero que le podáis sacar partido a NSSM.