Previously I showed you the new Windows Application engine (https://www.sapien.com/blog/2017/06/14/new-script-engines-for-windows-powershell/) and the Windows System Tray engine https://www.sapien.com/blog/2017/07/10/creating-a-system-tray-application-with-powershell/.
Today I will show you the last of the three new engines, the Windows Service engine.
Writing a Windows Service can be a challenging experience, even for a programmer. Generally, unless you do that exact thing for a living, nobody writes a Windows Service very often. So most folks don’t have a lot of experience with this particular task.
You do what most programmers do, you Google the task at hand. If you google “write a windows service in powershell” the first hit points to an MSDN magazine article: https://msdn.microsoft.com/en-us/magazine/mt703436.aspx
My compliments to the author, Jean-Francois Larvoire, who did a great job explaining the intricate details of building a service in Windows PowerShell.
If you do this very often, you should definitely read that article.
But, for most of us, this is not a very frequent task. So I will show you a way of doing this without knowing much about services or C#. All you need is PowerShell. Instead of using a script from somewhere on the internet we use a one-liner today.
Get-Process solitaire -ErrorAction SilentlyContinue | Stop-Process –PassThru
I am assuming you can see that this will simply terminate any process named ‘Solitaire’. We will call our service “SolitaireKiller”
Just as previously with the System Tray Application in the last post, the script needs a loop, so it executes the code inside again and again. Also like the tray app, we need to sleep in between iterations so we don’t hog a CPU core for no reason.
For terminating a solitaire game it is not necessary to do that within a second of startup anyway, so we just go with a minute. I don’t think many folks will finish a game in that time.
while($true) {
Get-Process solitaire -ErrorAction SilentlyContinue | Stop-Process –PassThru
Start-Sleep –Seconds 60
}
Run that as a script and it will just kill any Solitaire game you are playing within a minute. We do want to get a notification when a process was terminated, so we make a little adjustment to our script
while($true) {
$ProcessList = Get-Process solitaire -ErrorAction SilentlyContinue
if($ProcessList) {
Write-Host “Terminating Windows Solitaire process”
$ProcessList | Stop-Process –Force | Out-Null
}
Start-Sleep –Seconds 60
}
That’s all. So now we make that a service. Package your script with the Windows Service engine and the PowerShell version most appropriate for your script.
Make sure you enter all pertinent information in the Version settings.
Services need to be installed on a system. To make your life easer, all that is also already build in. All you need to do is run the service executable from an elevated command prompt with /i (as in install)
Now you can look at your service control panel and you will see the Solitaire Killer service. Remember the items you wrote in the ‘Product name’ and ‘Description’ fields for the version information? They are automatically used for the service name and description.
So now go ahead and start that service. Launch a game of Solitaire and wait. Within a minute it will be gone.
Now look at your event log. What you wrote there with Write-Host (or any other PowerShell output mechanism) will show up here in the Application Event Log.
To remove the service from your system, simply stop the service and use the /u parameter (as in uninstall) and it will be gone. Please note that it may take a few seconds to exit and that you may need to restart the services control panel to see that.
You can download the script and the packaged executables from here: https://sapien.s3.amazonaws.com/Blog_Post_Files/SolitaireKiller.zip
As always, if you have any ideas, comments, feedback, please use our feedback forum and reference this post.
https://www.sapien.com/forums/viewforum.php?f=23
Am running the latest builds of powershell studio 2017 but am not able to see the latest engines, have also veriefied have latest version of .Net is installed.
Please help
These are available now in PrimalScript. PowerShell Studio will have them in the next service build.
Thanks for your prompt reply, and when is the next expected relase for powershell studio?
Sometime next week I am told. No promises though 😀
Great! Simple but looks complete.
Look into “OnCustomCommand” https://msdn.microsoft.com/en-us/library/system.serviceprocess.servicebase.oncustomcommand(v=vs.110).aspx which can be very useful for sending commands to a running service.
PS D:\scripts> cmd /c sc control /?
DESCRIPTION:
Sends a CONTROL code to a service.
USAGE:
sc control [service name]
= user-defined control code
=
See also sc stop, sc pause, etc.
I also believe that changing the service perms will allow it to run as a non-admin account.
PS D:\scripts> cmd /c sc privs /?
DESCRIPTION:
Changes the required privileges setting of a service.
The privilege settings take effect when the
service process starts due to the first service in
the process being started. At that time, the Service
Control Manager (SCM) computes the union of all privileges
required by all services that will be hosted in the same
process and then creates the process with those
privileges. An absence of this setting is taken to imply
that the service requires all the privileges that
the security subsystem allows for the process running
in the service’s configured account.
USAGE:
sc privs [service name] [privileges]
OPTIONS:
privileges =
[E.g., SeBackupPrivilege/SeRestorePrivilege]
Of course the user account may also require some updated privileges depending on what the service is trying to do.
Hi,
How can the Script react to the Stop command? I’d like to use ist for writing Logfileentry “service Stopped”.
Registering a Windows Service using the “./filename /i” command flagged the service as potential malware in Windows Defender ATP, it installs successfully but can cause issues in an enterprise environment. Is there a “safer” way to register a service?
https://docs.microsoft.com/en-us/dotnet/framework/windows-services/how-to-install-and-uninstall-services
service.exe /i does the same internally and I have never seen it flagged as malware anywhere, but your settings may be different. I would suspect on a locked down system any new service, regardless of how it gets registered, has to be white-listed first.
Is it possible that the EXE is not signed? I believe Defender will alert on unsigned EXEs running as a service.
You are right Jim, that could be an issue too.