Quick access

This post explains how to monitor a multiple services on a list of servers and send alert when the given service is in stopped state. This script will allow you to read a list of servers from the input file and establish connection to all remote
servers to pull service status.

Thanks for this script. It is working when I run through "Windows Powershell ISE". I am using the following command:-
PS C:\windows_Service> Get-ServiceSQLAlert -ComputerList C:\windows_Service\server.txt -includeService NameOfTheService -To XYZ@abc.com -From 123abc@abc.com -SMTPMail mail.abc.Com
But I want to schedule this script through SQL Agent job.
The 1st step of the job:-
C:\windows_Service\ServicesStatusAlert.PS1
the 2nd step of the job:-
Get-ServiceSQLAlert -ComputerList C:\windows_Service\server.txt -includeService NameOfTheService -To XYZ@abc.com -From 123abc@abc.com -SMTPMail mail.abc.Com
But I am getting the follwoing error message:-
'The term 'Get-ServiceSQLAlert' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. '. Process Exit Code -1. The step failed.
How Do I fix it?

I had experience similar errors and came to this conclusion its either due to Local Workstation Security Permission or can be possibly blocked by your Group Policy Check restrictions on interactive mode, run as service, and run as backup operator etc.
Try running in powershell
get-service -computername Computerabc(The server in question) -service spooler
If you are able to pull remote information than its a permissions issue with the AD account running the powershell script commands.
#1 Try running the command with a domain admin account. This worked for me but would not be good due to security if using a schedule task to run your script in terms of automation. You would want to use some type of service account with restricted admin rights.
#2 If you wish to use a non-admin account. Utilize Group Policy to allow permissions the account that would be used to run the script. Grant this account stop, start, read service permissions to the service in question within Group Policy.
Insert the command below in the code vs using the get-service (this checks for all services) if you do not have an admin account you will not be able run this script unless you specify the script to check specific services that you have permissions to. You must also list this same service in the call command.
get-service -computername Computerabc(The server in question) -service spooler(service you want to check)

Forgot to include this.
If you are not able to run this simple command then its a permissions related issue. You can test this by using another account with higher security on that box your trying to reach. Use an account that is administrator on the destination box.
get-service -computername PC123

This is an excellent script. I'm having some issues running it using normal service account. I do not have Domain Admin rights and when I run it only works locally for localhost. For any remote servers I get errors when attempting to get-service from the remote servers.
Error
PS C:\ .\Microsoft.PowerShell_profile.ps1
Get-Service : Cannot open Service Control Manager on computer 'Su-W-dev017'. This operation might require other privileges.
At line:1 char:12
+ get-service <<<< -computername Su-W-dev017
+ CategoryInfo : NotSpecified: (:) [Get-Service], InvalidOperationException
+ FullyQualifiedErrorId : System.InvalidOperationException,Microsoft.PowerShell.Commands.GetServiceCommand
Can you provide me which permissions or group policy would be require to run this script? Our customer for security reasons, do not allow domain admin rights or local admin rights on boxes. We are provided services account that are not admin on the boxes. When one for their admin are logged into the box it works like a charm (they have domain admin rights). Can you help me or point me in the right direction how I can run the script without admin rights?
Thank you Prashanth in advance .

Hello!
thanks for this fantastic script! I tried to run it using a CMD file, including providing the necessary parameter values. For that I use as similar setup as the previous poster but I use the variables instead of the values.
Function Get-ServiceSQLAlert
{
#FULL CODE HERE
}
#command below with variables:
Get-ServiceSQLAlert -ComputerList $ComputerList -includeService $includeService -To $To -From $From -SMTPMail $SMTPMail
In my CMD file I have the following:
start powershell.exe -ExecutionPolicy RemoteSigned -NoExit -Command ". C:\ServicesStatusAlert.ps1; Get-ServiceSQLAlert -ComputerList c:\serverlist.txt -includeService SQLSERVERAGENT,MSSQLSERVER -To email@domain.com -From otheremail@domain.com -SMTPMail smtp-exch.xyzl.domain.net"
However, whatever I do, I get the following error:
Get-Content : Cannot bind argument to parameter 'Path' because it is an empty string.
At C:\ServicesStatusAlert.ps1:
127 char:36
+ Foreach($ServerName in (Get-Content <<<< $script:list)){
+ CategoryInfo : InvalidData: (:) [Get-Content], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Microsoft.PowerShell.Commands.GetContentComm
and
If I change $script:list = $ComputerList to $script:list = 'c:\serverlist.txt' it works but as soon as I provide the serverlist file as parameter it creates the above error message.
Funny enough: Despite the error message, the script produces the expected output but I really wonder why I get this error!
Any help is appreciated!
Cheers Rene

I set out for the same goal. I don't have much powershell script experience, so I had to research. Apparently there are user functions and system functions (probably not the correct jargon). If I created the user function get-servicesqlalert, it would disappear after I closed the PS cmd window. Rather than investigate how to make it not disappear, I just created a file ServiceSQLAlertRun.ps1 that contained this function, then below it, the command I wanted to run.
e.g.:
Function Get-ServiceSQLAlert
{
#FULL CODE HERE
}
#command below:
Get-ServiceSQLAlert -ComputerList C:\ServiceStatus\server.txt -includeService MyService1,MyService2,AnotherService3 -To jsmith@jsmith.com -From ksmith@ksmith.com -SMTPMail 192.168.0.222
Then created the scheduled task:
Action:
%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe
Add arguments:
-NoProfile -NoLogo -NonInteractive -ExecutionPolicy ByPass -File \\fileserver\scripts\PSScripts\ServiceStatus\ServiceSQLAlertRun.ps1
I actually initiated the process of scheduling the task via the event viewer, and based a task on event 7036 (I think-- whatever the "task stop/start" one is). Each time a service stops or starts, it'll fire off the task.

Hi,
Thanks for awesome report..
But i am facing one issue..If i give input of 20 server and run Script and if it find any server offline script will stop logically it should skip that server and send notification that XYZ server is down and keeping running for other server.
Is it possible to add that point in script...

I am getting below error at the time of calling and we have smtp ip we dont have email.Kindly help me
PS C:\PWR> Get-ServiceSQLAlert -ComputerList C:\PWR\server.txt -includeService MSSQL$PRDRESTORE02,SQLAgent$PRDRESTORE02
-To sqlsupport@ncdex.com -From sqlsupport@ncdex.com -SMTPMail 150.XX.XX.X
Get-ServiceSQLAlert : The term 'Get-ServiceSQLAlert' is not recognized as the name of a cmdlet, function, script file,
or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and
try again.
At line:1 char:1
+ Get-ServiceSQLAlert -ComputerList C:\PWR\server.txt -includeService MSSQL$PRDRE ...
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Get-ServiceSQLAlert:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException

This is great, thank you so much! It is working well, but I'd like the option to add multiple recipient email addresses (much like you can with the services themselves, separated by commas). This is my first PS script I've ever worked with and I've spent a few hours reading about multiple recipients and send-message and System.Net.Mail.MailMessage, but I'm having a hard time porting a solution into your script here.