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:
- 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.