Handling Windows services with Powershell

Today we will take a look at how we can handle Windows service with Powershell.

The challenge

Usually a software that is installed as a Windows service should run all day long without any issues. But did you ever run into the situation that a software does not run fully stable? That it only helps to restart the service? That is not design intend but what should we do? If it helps to restart a service once a day it can be used as a workaround. Nevertheless we should always try to force the vendor to correct the issue that makes the software instable or doing only parts of it’s work. But I also know that it is something not possible to convince the vendor for various reasons. Even if the vendor tries to fix the issue we just need to skip the time before the vendor has done his work.

To be honest it is not the biggest challenge to just restart a Windows service. But sometimes a service doesn’t start reliable or the start runs into a timeout. So we will also check the if the service started successfully and retry to start the service. I will cover some basics about handling with services in this post and publish a follow up article about checking the service state. In that case we have to check the state of the involved services in a loop and if needed trigger the start of a service again.

The implementation

As a basic information about Microsft Powershell I want to tell you that from a Powershell script or command line interface (CLI) we can run executeable programs. But Powershell has a really big bunch of available commands we can use. Those Powershell commands are called commandlets. They do the same as the well know Windows commands like ‘copy’, ‘delete’, ‘rename’ or ‘dir’ but Powershell gives us the opportunity to collect the output of those commandlets and to reuse the output in further actions.

Powershell commandlets usually are built of two parts. The first part defines what kind of an action will be done. Examples are ‘Get-‘, ‘Set-‘, ‘Read-‘, ‘Write-‘, ‘Start-‘, ‘Stop-‘. The second part describes what we want to start or waht we want to set. To find the way back to the Windows services there is a commandlet available that will show us the state of all available services.

Get-Service

You will se a list of all Windows services showing their state, name and description.

You can get the information of one single service by giving the name of the service as parameter:

Get-Service -Name TapiSrv

Or

Get-Service TapiSrv

Those two commands do the same because each Powershell commandlet has one parameter that does not have to be announced with it’s identifier. In this example the ‘Name’ parameter. You will see the state of the service ‘Telephony’ together with it’s display name.

You can also get a list of services if you pipe the output into a ‘Where-Object’ commandlet to filter the results:

Get-Service | Where-Object DisplayName -like 'VMWare*'

This way you will get all services with a display name that starts with ‘VMWare’.

It is also possible to store that result into a variable:

$services = Get-Service | Where-Object DisplayName -like 'VMWare*'

Later we can reference all services stored in that variable for example to restart those services.

Let’s come to a practical example. Assuming we are on a server that runs GFI Faxmaker and we want to restart all of it’s services. First we should find out which services belong to GFI. With a simple ‘Get-Service’ we get the list of all services and can see that all GFI services have a display name starting with ‘GFI’. With that knowledge we can use that information to filter the list to only show the needed services:

PS C:\Windows\system32> Get-Service | Where-Object DisplayName -Like 'GFI*'

Status   Name               DisplayName

------   ----               -----------

Running  FAXmaker Fax Se... GFI FaxMaker Fax Server

Running  FAXmaker MTA Se... GFI FaxMaker Message Transfer Agent

Running  GFI FaxMaker WSAPI GFI FaxMaker WSAPI

To restart all those services we can store them into a variable and reuse that variable to restart all those services:

$services = Get-Service | Where-Object DisplayName -Like 'GFI*'

Restart-Service $services

You will see the process of the restart of the GFI services.

Usually you don’t want to do that manually every time so you can run such a script once a day triggered by the Windows task scheduler as described here: Run Powershell scripts from Windows task scheduler

If you want to start more services by executing a single script you can add further lines containing the ‘Restart-Service’ commandlet.

There will be reasons to not only restart one or multiple services. For example if you have to stop a service to make a backup and start it again if everything is copied.

$services = Get-Service | Where-Object DisplayName -Like 'GFI*'

Stop-Service $services

# copy the needed files

Start-Service $services

Conclusion

I think you have seen a small part of the power of Microsft Powershell. Best of all is that Powershell is part of every Windows installation so that no further licensing is necessary and nothing has to be installed. Especially the option to pipe output into further commandlets or to store results in variables you can reuse together with the deep integration into Windows makes it very powerful and gives us many options in our daily work.

Another good thing is the option every Linux administrator would miss if it wasn’t there. At almost every position the curser stands you can press the ‘TAB’ key to auto complete what you started to type.

Have fun testing some more commandlets and feel free to comment this article.

Links to further read:

https://technet.microsoft.com/en-us/library/ee176858.aspx

https://technet.microsoft.com/en-us/library/ee177001.aspx

https://technet.microsoft.com/en-us/library/ee177005.aspx

https://technet.microsoft.com/en-us/library/ee176942.aspx

https://technet.microsoft.com/en-us/library/ee177028.aspx

1 thought on “Handling Windows services with Powershell

  1. Pingback: Controlled restart of multiple services - Blog: Florian Wilke

Leave a Reply

Your email address will not be published.