Skip to content

Monitor Service & Restart

Published: 2024-01-10

Two powershell scripts below related to starting and stopping services. Used with a particularly troublesome service that would get stuck from time to time.

  • SMTP Server should be an internal server
  • Change the other variables as appropritate

Start Service

  • Here we attempt to start the service and wait for 30 seconds. If we can't get it started, alert and disable the task (that presumably runs every 5 minutes) to avoide many email notifications.
$service = Get-Service -Name "ServiceName"

if ($service.Status -eq [System.ServiceProcess.ServiceControllerStatus]::Stopped) {

    $service.Start()

    $service.WaitForStatus([System.ServiceProcess.ServiceControllerStatus]::Running, [timespan]::FromSeconds(30)) | Out-Null

    if ($service.Status -ne [System.ServiceProcess.ServiceControllerStatus]::Running) {

        $sendMailMessageSplat = @{
            From = 'pwrshl_prc <pwrshl_prc@domain.com>'
            To = 'username <username@domain.com>', 'username2 <username2@domain.com>'
            Subject = 'error starting ServiceName'
            Body = "was not able to start the ServiceName service."
            Priority = 'High'
            SmtpServer = 'x.x.x.x'
        }
        Send-MailMessage @sendMailMessageSplat

        Disable-ScheduledTask -TaskName 'TaskName'
    }
} 

Stop Service

  • Here the requirement was to attempt a normal shutdown for 1 minute. If not achieved, force a stop. If that errors out - alert.
  • It’s hard to test the state where you’ve requested a stop, but the executable is stuck in “stop pending”.
$service = Get-Service -Name "ServiceName"

if ($service.Status -eq [System.ServiceProcess.ServiceControllerStatus]::Running) {

    $service.Stop()

    $service.WaitForStatus([System.ServiceProcess.ServiceControllerStatus]::Stopped, [timespan]::FromMinutes(1)) | Out-Null
}

if (($service.Status -eq [System.ServiceProcess.ServiceControllerStatus]::Running) -or
    ($service.Status -eq [System.ServiceProcess.ServiceControllerStatus]::StopPending)) {

    $wmisvc = Get-WmiObject -Class win32_service -Filter "name = 'ServiceName'"
    try {
        Stop-Process -Id $wmisvc.processid -Force -PassThru -ErrorAction Stop
    }
    catch {

        $sendMailMessageSplat = @{
            From = 'pwrshl_prc <pwrshl_prc@domain.com>'
            To = 'username <username@domain.com>', 'username2 <username2@domain.com>'
            Subject = 'error stopping ServiceName'
            Body = "was not able to top the ServiceName service."
            Priority = 'High'
            SmtpServer = 'x.x.x.x'
        }
        Send-MailMessage @sendMailMessageSplat
    }  
}

<#
Get-WmiObject -Class win32_service | Where-Object {$_.state -eq 'stop pending'}
https://woshub.com/killing-windows-services-that-hang-on-stopping/
#>

Windows Scheduled Task

  • Can be run as two tasks:

    Two Tasks

    • The first is the start service - check every 5 minutes and start it if down
    • The second to stop the service once per day
  • How to call a powershell script form a Scheduled Task.

    Schedule Task Parameters