If you have a PowerShell script you'd like to run constantly in the background and start up automatically after a reboot, the best option is to run it as a Windows service. I'll show you how to set this up using NSSM, the Non-Sucking Service Manager.
Avatar

The scenario

Most PowerShell scripts aim to run a task and then exit. You'll usually execute a script from the PowerShell console or perhaps trigger it periodically via the Windows Task Scheduler. However, you may want to run a script 24/7 and ensure it starts up again after a reboot or crash. To do this, the easiest option is to use NSSM.

About NSSM

If you've not heard about NSSM before, it's a small service helper similar to the built-in program srvany. NSSM aims to make it extremely simple to configure any binary to run as a service and ensure it stays running. You can take a look at the NSSM website for more information about common use cases.

Example script

Take this example script below. This script runs a small web server using the Polaris framework. Polaris is a cross-platform, minimalist web framework written in PowerShell. Currently, this is not a Microsoft-supported module, but I encourage you to look at it if you are interested in experimenting with web servers and PowerShell commands. Like a normal web server, ours should run all the time, and we will use a Windows service to achieve this.

[cmdletbinding()]
param()

Import-Module -Name Polaris

New-PolarisGetRoute -Path '/helloworld' -Scriptblock {
    $Response.Send('Hello World!')
}

Start-Polaris -Port 8080

while($true) {
    Start-Sleep -Milliseconds 10
}

Installing Polaris

Currently, Polaris is not available in the PowerShell Gallery, so we'll need to install it manually. Download the zip archive from the git repository, and extract the contents to C:\Program Files\WindowsPowerShell\Modules\Polaris.

Download the Polaris zip file

Download the Polaris zip file

Your modules directory should look like this:

Polaris extracted to the modules folder

Polaris extracted to the modules folder

If we run this script manually, we can verify Polaris is running and serving requests at http://localhost:8080/helloworld. It will keep running until you press Ctrl+C.

Starting Polaris

Starting Polaris

Testing Polaris in the browser

Install NSSM

Now on to installing NSSM so we can configure our Windows service. If you are already using Chocolatey, you can install NSSM with the following:

Installing NSSM with Chocolatey

Installing NSSM with Chocolatey

If you don't have Chocolatey installed, you can download NSSM here.

Install the Windows service

After installing NSSM, we'll need to run a few commands to install our web server script as a Windows service. You'll need to run these next commands as an administrator.

We have to define a few variables. We'll need the path to NSSM itself, the name of the service we want to create, the path to PowerShell, the path to our Polaris script, and the argument string we'll pass to PowerShell.

$nssm = (Get-Command nssm).Source
$serviceName = 'Polaris'
$powershell = (Get-Command powershell).Source
$scriptPath = 'C:/4sysops/Start-Polaris.ps1'
$arguments = '-ExecutionPolicy Bypass -NoProfile -File "{0}"' -f $scriptPath
& $nssm install $serviceName $powershell $arguments
& $nssm status $serviceName
Start-Service $serviceName
Get-Service $serviceName
Install a script as a service

Install a script as a service

Validating the script

Now that we've installed our new service, we can test everything is working with Invoke-RestMethod.

Testing the web server with Invoke RestMethod

Testing the web server with Invoke RestMethod

As with any Windows service, we can also set this to start automatically on boot or restart if it unexpectedly terminates.

Subscribe to 4sysops newsletter!

Conclusion

You might find running a PowerShell script as a service handy in many use cases. Hopefully I've just whetted your appetite on what you can do with services, NSSM, and PowerShell.

avataravataravatar
5 Comments
  1. Avatar
    Ed 6 years ago

    Thanks!!

    avatar
  2. Avatar
    Anders 6 years ago

    Hello,

    When i try and use the Invoke-restmethod i get a 403 Error.

    Any Ideas? I use your code snippet.

     

  3. Avatar
    Chris Magnuson 5 years ago

    I would recommend changing

    while($true) {
        Start-Sleep -Milliseconds 10
    }

    to

    while ($Polaris.Listener.IsListening) {
       Wait-Event callbackeventbridge.callbackcomplete
    }

    Per the recommendation here.

  4. Avatar
    nezar 5 years ago

    Hello,

    I am having trouble running this line:

    & $nssm install $serviceName $powershell $arguments

    I get the following error:

    The expression after '&' in a pipeline element produced an object that was not valid. It must result in a command name, a script block, or a CommandInfo object.

    At line:1 char:3
    + & $nssm install $serviceName $powershell $arguments
    +   ~~~~~
        + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
        + FullyQualifiedErrorId : BadExpression

    how can I resolve this??

    I am not really good in powershell. more details will be appreciated.

    • Avatar

      @nezar

      What is displayed when you run the following line?

      (copy / paste the whole line including quotes)

      "$nssm install $serviceName $powershell $arguments"

Leave a reply

Your email address will not be published. Required fields are marked *

*

© 4sysops 2006 - 2023

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account