PS Give alert upon service failure

Hey there,

If this is outside the scope of this forum, I am very sorry and please feel free the remove it.

Basically I wanted to know if it was possible to make a script that notifies me (by mail) when a certain Service fails and then tries to restart the service. However it should not require a lot of manual input.

This script below was made by Craig Irvin (GitHub - CraigI/ServiceAlertFromRecovery: Restart and Alert on service failure using Recovery tab) and it mostly does what I want to test but I can’t seem to get it to actually work.

So I use the Print Spooler service as a way to test this script, I make it so the first recovery option is “Run a Program” and fill in the following:
“Program: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe”
"Command line parameters: -command “& {C:\scripts\ServiceFailure_SendMail.ps1 ‘Spooler’ %1%}”

I then -force the spoolsv process to stop to simulate a failure and see if the script triggers into action. It does not.
When I remove the commandline parameters, the powershell.exe proces does seem to execute. (Get-Process does list it.)

When I change the script below slightly and remove “$TimesRestarted = $args[1]” and remove the array @ $ServiceName and replace it with “$ServiceName = “Spooler””. Then fill in the following:
“Program: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe”
“Command line parameters: C:\scripts\ServiceFailure_SendMail.ps1”

It does work.

What am I doing wrong?

$ComputerName = (get-wmiobject Win32_Computersystem).name
$ServiceName = $args[0]
$ServiceDisplayName = (Get-Service $ServiceName).DisplayName
$TimesRestarted = $args[1]

Get-Service $ServiceName
$Status = (Get-Service $ServiceName).Status
If ($Status -ne "Running")
{
	Start-Service $ServiceName
}

function SendAlert
{
  $FromAddress = "ServiceFailure@domain.com"
  $ToAddress = "mailbox@domain.com"
  $MessageSubject = "Service: $ServiceName failed @ $ComputerName"
  $MessageBody = "The $ServiceDisplayName ($ServiceName) service on $ComputerName has restarted $TimesRestarted times in the last 24 hours. Please review server event logs for further information."
  $SendingServer = ""

  $SMTPMessage = New-Object System.Net.Mail.MailMessage $FromAddress, $ToAddress, $MessageSubject, $MessageBody

  $SMTPClient = New-Object System.Net.Mail.SMTPClient $SendingServer
  $SMTPClient.Send($SMTPMessage)
}
SendAlert

You can make a scheduled task or loop with this example.

$test = Get-Service -DisplayName 'Print Spooler' ; $time = 0
If ($test.Status -ne 'Running'){Start-Service $test ; $time++}

$mailparam = @{
From = "ServiceFailure@domain.com"
To = "mailbox@domain.com"
Subject = "$($test.DisplayName) failed for $($test.MachineName)"
Body = "The $($test.DisplayName) ($($test.name)) service on $($test.MachineName) 
has restarted $time times in the last 24 hours. Please review server 
event logs for further information."
SmtpServer = ""
}

Send-MailMessage @mailparam

Sorry for the late reply.

That’s definitely a valid option, thank you very much.

I am, however, still confused as to why I can’t get the script in my op to work.