{"id":13739,"date":"2017-07-12T08:00:03","date_gmt":"2017-07-12T15:00:03","guid":{"rendered":"https:\/\/www.sapien.com\/blog\/?p=13739"},"modified":"2017-07-11T16:22:19","modified_gmt":"2017-07-11T23:22:19","slug":"write-a-windows-service-in-powershell","status":"publish","type":"post","link":"https:\/\/dev.sapien.com\/blog\/2017\/07\/12\/write-a-windows-service-in-powershell\/","title":{"rendered":"Write a Windows Service in PowerShell"},"content":{"rendered":"<p>Previously I showed you the new Windows Application engine (<a title=\"https:\/\/www.sapien.com\/blog\/2017\/06\/14\/new-script-engines-for-windows-powershell\/\" href=\"https:\/\/www.sapien.com\/blog\/2017\/06\/14\/new-script-engines-for-windows-powershell\/\">https:\/\/www.sapien.com\/blog\/2017\/06\/14\/new-script-engines-for-windows-powershell\/<\/a>) and the Windows System Tray engine <a title=\"https:\/\/www.sapien.com\/blog\/2017\/07\/10\/creating-a-system-tray-application-with-powershell\/\" href=\"https:\/\/www.sapien.com\/blog\/2017\/07\/10\/creating-a-system-tray-application-with-powershell\/\">https:\/\/www.sapien.com\/blog\/2017\/07\/10\/creating-a-system-tray-application-with-powershell\/<\/a>.<br \/>\nToday I will show you the last of the three new engines, the Windows Service engine.<\/p>\n<p>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\u2019t have a lot of experience with this particular task.<br \/>\nYou do what most programmers do, you Google the task at hand. If you google \u201cwrite a windows service in powershell\u201d the first hit points to an MSDN magazine article: <a title=\"https:\/\/msdn.microsoft.com\/en-us\/magazine\/mt703436.aspx\" href=\"https:\/\/msdn.microsoft.com\/en-us\/magazine\/mt703436.aspx\">https:\/\/msdn.microsoft.com\/en-us\/magazine\/mt703436.aspx<\/a><br \/>\nMy compliments to the author, Jean-Francois Larvoire, who did a great job explaining the intricate details of building a service in Windows PowerShell.<br \/>\nIf you do this very often, you should definitely read that article.<\/p>\n<p>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.<\/p>\n<p>Get-Process solitaire -ErrorAction SilentlyContinue | Stop-Process \u2013PassThru<\/p>\n<p>I am assuming you can see that this will simply terminate any process named \u2018Solitaire\u2019. We will call our service \u201cSolitaireKiller\u201d<br \/>\nJust 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\u2019t hog a CPU core for no reason.<br \/>\nFor 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\u2019t think many folks will finish a game in that time.<\/p>\n<p>while($true) {<br \/>\nGet-Process solitaire -ErrorAction SilentlyContinue | Stop-Process \u2013PassThru<br \/>\nStart-Sleep \u2013Seconds 60<br \/>\n}<\/p>\n<p>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<\/p>\n<p>while($true) {<br \/>\n$ProcessList = Get-Process solitaire -ErrorAction SilentlyContinue<br \/>\nif($ProcessList) {<br \/>\nWrite-Host &#8220;Terminating Windows Solitaire process&#8221;<br \/>\n$ProcessList | Stop-Process \u2013Force | Out-Null<br \/>\n}<br \/>\nStart-Sleep \u2013Seconds 60<br \/>\n}<\/p>\n<p>That\u2019s 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.<\/p>\n<p><a href=\"https:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2017\/07\/image-4.png\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" style=\"margin: 0px; border: 0px currentcolor; display: inline; background-image: none;\" title=\"image\" src=\"https:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2017\/07\/image_thumb-4.png\" alt=\"image\" width=\"640\" height=\"435\" border=\"0\" \/><\/a><\/p>\n<p>Make sure you enter all pertinent information in the Version settings.<\/p>\n<p><a href=\"https:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2017\/07\/image-5.png\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" style=\"margin: 0px; border: 0px currentcolor; display: inline; background-image: none;\" title=\"image\" src=\"https:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2017\/07\/image_thumb-5.png\" alt=\"image\" width=\"640\" height=\"435\" border=\"0\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>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)<br \/>\n<a href=\"https:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2017\/07\/image-6.png\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" style=\"margin: 0px; border: 0px currentcolor; display: inline; background-image: none;\" title=\"image\" src=\"https:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2017\/07\/image_thumb-6.png\" alt=\"image\" width=\"640\" height=\"327\" border=\"0\" \/><\/a><\/p>\n<p>Now you can look at your service control panel and you will see the Solitaire Killer service. Remember the items you wrote in the \u2018Product name\u2019 and \u2018Description\u2019 fields for the version information? They are automatically used for the service name and description.<\/p>\n<p><a href=\"https:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2017\/07\/image-7.png\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" style=\"margin: 0px; border: 0px currentcolor; display: inline; background-image: none;\" title=\"image\" src=\"https:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2017\/07\/image_thumb-7.png\" alt=\"image\" width=\"640\" height=\"398\" border=\"0\" \/><\/a><\/p>\n<p>So now go ahead and start that service. Launch a game of Solitaire and wait. Within a minute it will be gone.<br \/>\nNow 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.<\/p>\n<p><a href=\"https:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2017\/07\/image-8.png\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" style=\"margin: 0px; border: 0px currentcolor; display: inline; background-image: none;\" title=\"image\" src=\"https:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2017\/07\/image_thumb-8.png\" alt=\"image\" width=\"640\" height=\"344\" border=\"0\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p><a href=\"https:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2017\/07\/image-9.png\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" style=\"margin: 0px; border: 0px currentcolor; display: inline; background-image: none;\" title=\"image\" src=\"https:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2017\/07\/image_thumb-9.png\" alt=\"image\" width=\"640\" height=\"327\" border=\"0\" \/><\/a><\/p>\n<p>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.<\/p>\n<p>&nbsp;<\/p>\n<p>You can download the script and the packaged executables from here: <a title=\"https:\/\/sapien.s3.amazonaws.com\/Blog_Post_Files\/SolitaireKiller.zip\" href=\"https:\/\/sapien.s3.amazonaws.com\/Blog_Post_Files\/SolitaireKiller.zip\">https:\/\/sapien.s3.amazonaws.com\/Blog_Post_Files\/SolitaireKiller.zip<\/a><\/p>\n<p>As always, if you have any ideas, comments, feedback, please use our feedback forum and reference this post.<br \/>\n<a href=\"https:\/\/www.sapien.com\/forums\/viewforum.php?f=23\">https:\/\/www.sapien.com\/forums\/viewforum.php?f=23<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>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 [&hellip;]<\/p>\n","protected":false},"author":5,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[283,1143,703,410,25],"tags":[28,1016,37,300,62],"class_list":["post-13739","post","type-post","status-publish","format-standard","hentry","category-howto","category-powershell","category-powershell-studio","category-primalscript-software-news","category-windows-powershell","tag-powershell","tag-powershell-studio","tag-primalscript","tag-service","tag-windows"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts\/13739","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/comments?post=13739"}],"version-history":[{"count":3,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts\/13739\/revisions"}],"predecessor-version":[{"id":13744,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts\/13739\/revisions\/13744"}],"wp:attachment":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/media?parent=13739"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/categories?post=13739"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/tags?post=13739"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}