Any PowerShell script can be transformed to a real Windows service that runs in the background and starts automatically during your server boot. You can create a Windows service using srvany.exe
or instsrv.exe
tools (from Windows Server Resource 2003 Kit) which allow you to run the powershell.exe
process with a parameter that contains the path to your PS1 script file.
The main disadvantage of creating a service using this method is that srvany.exe does not control a PowerShell script execution state, and if the app crashes (hangs up), the service does not see it and goes on working. To create a Windows service from a file that contains a PowerShell script, in this article we will use the NSSM (Non-Sucking Service Manager) toolkit, which does not demonstrate the above mentioned disadvantages.
You can download and install NSSM manually or using Chocolatey. Firstly, install Choco itself:
Set-ExecutionPolicy Bypass -Scope Process -Force; `
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
Then install the NSSM package:
choco install nssm
In this example, we will track the changes in a specific Active Directory group in real time and inform a security administrator using a pop-up notification and e-mail (the script is given in this article) .
So, we have a PowerShell code that needs to be saved as a PS1 file. Let’s add an infinite loop that performs a check every minute:
while($true) {
#Your PS code
Start-Sleep –Seconds 60
}
You can create a service from a PowerShell script using NSSM directly from PowerShell:
$NSSMPath = (Get-Command "C:\ps\nssm\win64\nssm.exe").Source
$NewServiceName = “CheckADGroup”
$PoShPath= (Get-Command powershell).Source
$PoShScriptPath = “C:\ps\CheckADGroup\checkad.ps1”
$args = '-ExecutionPolicy Bypass -NoProfile -File "{0}"' -f $PoShScriptPath
& $NSSMPath install $NewServiceName $PoShPath $args
& $NSSMPath status $NewServiceName
Start-Service $NewServiceName
Check the service status in PowerShell:
Get-Service $NewServiceName
So you have created and started your new Windows service. Make sure that it has appeared in the services management console (services.msc).
CheckADGroup has appeared, it is configured to start automatically and is currently running. As you can see, your PowerShell script is running inside the nssm.exe process.
In order the service can show notifications in a user session enable the Allow service to interact with desktop option on the Log on tab.
Start-Service -Name ui0detect
However, Interactive Services Detection Service has been completely removed from Windows 10 build 1803, and you won’t be able to switch to Session 0. So you won’t see the notification windows displayed under System account.
You can change the service description using this command:
& $NSSMPath set $NewServiceName description “Monitoring of AD group changes”
To remove the service you have created, use the sc delete
command or:
nssm remove CheckADGroup