Monitor Windows services with PowerShell

Schedule a PowerShell script to monitor local services in your Windows Server environment
Published on Friday, 10 April 2015

As a Windows Server and IIS administrator, you want your Windows services to run at all times. One can monitor Windows services in many, many, ways. Some of our customers websites may depend on certain services, which may be hard to monitor externally. For those Windows services that need local monitoring, I like to schedule a PowerShell script. Here is one...


How to monitor Windows Servers with PowerShell.

Start, stop, restart Windows services with PowerShell's Get-Service and Start-Service cmdlets

To get the status of a service, we can utilize the Get-Service PowerShell cmdlet, and the Start-Service cmdlet to start a service.

Some of our clients depend on a mail service running at localhost. For example because they haven't configured CDO cdoSendUsingPort in their classic ASP scripts. In the background, we use the IP Helper service to tunnel, or proxy, localhost:25 to an external SMTP service.

Bottom line, when the service isn't running, some customers are unable to send mail from their websites.

In PowerShell, you can combine the output of the Get-Service cmdlet with Start-Service, to start a service when it's not running:

Get-Service iphlpsvc | %{ if ( $_.Status -eq "Stopped" ) {
	Start-Service iphlpsvc
}}

If the status of the queried service is equal to "Stopped", use Start-Service to start the service. You can use this for nearly every Windows service, for instance LanmanWorkstation (Workstation service):

Get-Service LanmanWorkstation | %{
	if( $_.Status -eq "Stopped" ) {
		Start-Service LanmanWorkstation
	}
}

Or LanmanServer (Server service):

Get-Service LanmanServer | %{
	if( $_.Status -eq "Stopped" ) {
 		Start-Service LanmanServer
	}
}

SQL Server and SQL Server Agent (is a dependent service):

PS C:\Users\jan> Get-Service MSSQLSERVER

Status   Name               DisplayName
------ ---- -----------
Running  MSSQLSERVER        SQL Server (MSSQLSERVER)


PS C:\Users\jan> Get-Service MSSQLSERVER -DependentServices

Status   Name               DisplayName
------ ---- -----------
Running  SQLSERVERAGENT     SQL Server Agent (MSSQLSERVER)

PS C:\Users\jan> Stop-Service SQLSERVERAGENT
WARNING: Waiting for service 'SQL Server Agent (MSSQLSERVER) (SQLSERVERAGENT)' to stop...
PS C:\Users\jan> Get-Service SQLSERVERAGENT

Status   Name               DisplayName
------ ---- -----------
Stopped  SQLSERVERAGENT     SQL Server Agent (MSSQLSERVER)


PS C:\Users\jan> Stop-Service MSSQLSERVER
WARNING: Waiting for service 'SQL Server (MSSQLSERVER) (MSSQLSERVER)' to stop...
[...]
Get-Service MSSQLSERVER | %{
  if( $_.Status -eq "Stopped" ) {
    Get-Service SQLSERVERAGENT | %{
      if ( $_.Status -eq "Stopped" ) {
        Start-Service SQLSERVERAGENT
      }
   }
   Start-Service MSSQLSERVER
  }
}

Waiting for service state with Get-Service

If you are using Get-Service in PowerShell, you can even wait for a given time period before starting a service using the WaitForStatus method. For example:

$service = Get-Service( 'lanmanserver' )
$service.stop() # stops the given service
$service.WaitForStatus( 'Stopped', '0:01:00' ) # give the service a one minute time to fully stop
$service.start() # start the service

Test network connections in PowerShell with Test-NetConnection

You can use Test-NetConnection (PowerShell 4.0) or System.Net.Sockets.TcpClient to test network connections, and if they can be established:

(New-Object System.Net.Sockets.TcpClient).Connect( "localhost", "25" )
(New-Object System.Net.Sockets.TcpClient).Connect( "smtp.example.com", "587" )

Test-NetConnection -Port 25 -ComputerName localhost
Test-NetConnection -Port 587 -ComputerName smtp.example.com

Interested in more monitoring using PowerShell? Have a look at some of my Zabbix posts where I use PowerShell and WMI / CIM to monitor websites and application pools in Windows Server IIS.