Using Powershell to check service and send email
Ran into an issue with services stopping for no reason and causing IIS to stop. This was happening in the middle of the night and was sporadic in nature, making it hard to find a root cause. As a band-aid I created a Powershell 2 script to check for the service, restart if not in a running state and send and email.
Here is the script.
# Checks for a service to be running and starts if needed.
# Author: Me
# Date: 01/16/2012
# Name: checksvculti1.ps1
# must use a wrapper script with powershell script due to running at privileged access.
function FuncCheckService{
param($ServiceName)
$arrService = Get-Service -Name $ServiceName
if ($arrService.Status -ne "Running"){
Start-Service $ServiceName
FuncMail -To "myemail@yourhost.com" -From "myserver@yourhost.com" -Subject "Servername :
($ServiceName) service started." -Body "Service $ServiceName started" -smtpServer "mysmtpserver.com"
}
}
function FuncMail {
param($To, $From, $Subject, $Body, $smtpServer)
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$msg.From = $From
$msg.To.Add($To)
$msg.Subject = $Subject
$msg.IsBodyHtml = 1
$msg.Body = $Body
$smtp.Send($msg)
}
FuncCheckService -ServiceName "IISADMIN"
the script is pretty simple and really has two defined functions FuncCheckService and FuncMail. the last line of the script runs FuncCheckService and adds the parameter -ServiceName where you define the service you want to check.
Now to modify this script you only have to change a few settings.
The line in FuncCheckService that calls the FuncMail you will need to change
- -To
- -From
- -Body
- -smtpServer
And the last line of the script is where you will define the service to check. Change value after -ServiceName to the service you want to check.
If you notice in the comments for the script I mention that is must be run in a wrapper script. The reason is do to privileges need to be run. I am running this script in Unrestricted mode. The wrapper script looks like this.
powershell.exe -command "Set-ExecutionPolicy Unrestricted -force"
powershell.exe c:\Scripts\checksvculti1.ps1
Save this file and the Powershell script with whatever names you like and in the same directory. You can now schedule this to run as a scheduled task.
37 Responses to “Using Powershell to check service and send email”
Trackbacks/Pingbacks
- Using Powershell to check service and send email – VMDK 自修室 - […] Using Powershell to check service and send email […]
Hi,
Could you please let me know if i export the running and stopped services to CSV file, How can send the attachment in this email.
Regards,
Raja
Raja,
Here is a modification that uses a Powershell 2 cmdlet Send-MailMessage that is exactly what I did with the function. What it adds is attachments. The post I wrote was for PowerShell 1 which doesn’t have Send-MailMessage comdlet. You can add additional attachments by seperating with commas. ( -Attachments “c:\temp\file1.txt, c:\temp\file2.txt”
function FuncCheckService{
param($ServiceName)
$arrService = Get-Service -Name $ServiceName
if ($arrService.Status -ne “Running”){
Start-Service $ServiceName
Send-MailMessage -To “myemail@yourhost.com” -From “myserver@yourhost.com” -subject “Servername : ($ServiceName) service started.” -Body “Service $ServiceName started” -smtpServer “mysmtpserver.com” -Attachments “c:\temp\file1.txt”
}
}
FuncCheckService -ServiceName “IISADMIN”
Mark
Hi,
Thank you for the Script, I have added your above script on to one of my script. But when i am trying to run them it is not running completely. If i run them individually they are working fine..Can you please tell why this is happening.. Please help me
#***********************************************
#Display Current System Time
#***********************************************
Get-WmiObject Win32_OperatingSystem |Select *Time*
#**********************************************
#Displays SharePoint Services on Services.msc
#**********************************************
Get-Service W3SVC, SPAdminV4, SPSearch4, SPUserCodeV4, SPTraceV4, SPWriterV4, WebAnalyticsService,ProfSvc |Select DisplayName, Status
#***********************************************
#Within the Windows PowerShell we can add SharePoint snap in to run SP cmdlets
#***********************************************
Add-PSSnapin Microsoft.SharePoint.PowerShell
#*****************************
#List all the Webapplications
#*****************************
Get-SPWebApplication | Select URL, Status
#*************************
#List all SP Services Status on all servers in the FARM where it is hosted
#*************************
Add-PSSnapin microsoft.sharepoint.powershell -ErrorAction SilentlyContinue
$services = new-object system.collections.sortedlist
$servers = (get-spfarm).servers
foreach ($server in $servers)
{
foreach($service in $server.serviceinstances)
{
if ($service.status = “Online”)
{
$s = $service.typename
if ($services.contains($s))
{
$serverlist = $services[$s]
$servername = $server.name
$services[$s] = “$serverlist – $servername”
}
else
{
$services[$s] = $server.name
}
}
}
}
$services
#********************************
#List All Service Applications Status
#********************************
Get-SPServiceApplication | Select URL, Status
#*******************************************
#Adds IIS snap in, We don’t have IIS Snap in installed
#*******************************************
Import-Module WebAdministration
Get-WebItemState IIS:\AppPools\11ca010994114457bbf73ec80bcd7b85
Get-WebItemState IIS:\AppPools\11ca010994114457bbf73ec80bcd7b85
Get-WebItemState IIS:\AppPools\582e9ccb5b6041289eb20cf6dc7a0dda
Get-WebItemState IIS:\AppPools\bd5c0c275496426a9b0afdfc6324a4fd
Get-WebItemState IIS:\AppPools\Classic .NET AppPool
Get-WebItemState IIS:\AppPools\DefaultAppPool
Get-WebItemState IIS:\AppPools\e9757c5b418b47a0a28931b48f725c8f
Get-WebItemState IIS:\AppPools\SecurityTokenServiceApplicationPool
Get-WebItemState IIS:\AppPools\SharePoint – 2100
Get-WebItemState IIS:\AppPools\SharePoint – 55555
Get-WebItemState IIS:\AppPools\SharePoint – 80
Get-WebItemState IIS:\AppPools\SharePoint Central Administration v4
Get-WebItemState IIS:\AppPools\SharePoint Web Services Root
Regards,
Raja
Raja,
The way you are retrieving the list will not work with the script. The script was only created for a single service. Unfortunately I do not have a SharePoint 2010 server I can test this out on, but I see a post the has systems.collected.sortedlist for SharePoint and in a comment below there is a different way to get the list http://talbottcrowell.wordpress.com/2010/10/22/listing-services-on-sharepoint-farm-by-server-using-powershell/ . Give me a bit and let me see if I can modify the script for a multi-service check.
Hi,
I have already the script in place with me, But is there a way that i can run these CMDlets combined.. and export the data to excel
Regards,
Raja
Raja,
You can run them combined. Create each of them as functions and call the functions. That’s how I did it with the service check. The service check and the email send are both functions and it allowed me to run the service check and call the mail send in the same script. For the excel export there is a cmdlet call export-csv. There is a good reference here http://technet.microsoft.com/en-us/library/ee176825.aspx. It is as simple to run as Get-Process | Export-Csv c:\scripts\test.txt.
Hi,
I am able to modify the script and able to run all the commands and get teh scripts, But when i do this i am not able to send the email. can you please help me in integrating the script which can send email as well.
$strServices=Get-Service W3SVC, SPAdminV4, SPSearch4, SPUserCodeV4, SPTraceV4, SPWriterV4, WebAnalyticsService,ProfSvc|Select name, Status
$strServiceApplications=Get-SPServiceApplication | Select name, Status
$strWebapplications=Get-SPWebApplication | Select name, Status
$services = new-object system.collections.sortedlist
$servers = (get-spfarm).servers
foreach ($server in $servers)
{
foreach($service in $server.serviceinstances)
{
if ($service.status = “Online”)
{
$s = $service.typename
if ($services.contains($s))
{
$serverlist = $services[$s]
$servername = $server.name
$services[$s] = “$serverlist – $servername”
}
else
{
$services[$s] = $server.name
}
}
}
}
$Report=$strServices+$strServiceApplications+$strWebapplications+$servers| Export-CSV -Path “C:\Healthreport.csv” –NoTypeInformation
Raja,
Add this line after the last line.
Send-MailMessage -To me@myserver.com -From maint@myserver.com -subject “Service Report” -SmtpServer my.smtp.server -Attachments $Report
This will send it the report as an attachment to you using the Send-MailMessage cmdlet.
Can we use this for multiple services in a system?
This particular script is only written for one service check, but you could use it as a base to make it for multiple services.
Thanks for the script, it starts any services which in stopped status. My problem is i have scheduled it for every 10 Mins. But for every 10 Mins i am getting e-mail notification whenever it runs. I want to modify the script that whenever it detects the service is stopped and then starts then only i should get a email notification not always even that perticular service is running.
Can anybody please help me to sort out the issue. Many thanks in Advance.Here is my current script
function FuncCheckService{
param($ServiceName)
$arrService = Get-Service -Name $ServiceName
if ($arrService.Status -ne “Running”){
Start-Service $ServiceName
FuncMail -To “to-email@domain.com” -From “from-mail@domain.com” -Subject “Servername : ($ServiceName) service started.” -Body “Service $ServiceName started” -smtpServer “relay.mailserver.com”
}
}
function FuncMail {
#param($strTo, $strFrom, $strSubject, $strBody, $smtpServer)
param($To, $From, $Subject, $Body, $smtpServer)
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$msg.From = $From
$msg.To.Add($To)
$msg.Subject = $Subject
$msg.IsBodyHtml = 1
$msg.Body = $Body
$smtp.Send($msg)
}
FuncCheckService -ServiceName “VMware VirtualCenter Server”
The Powershell script is looking for -ne Running, If you are getting an email everytime it runs it is not seeing it running. I am suing this script like it is written all over the place. The question is are you using the wrapper script mentioned in the post to call the script as this requires elevated rights.
The wrapper script, let’s say called chkvCenter.cmd should contain these two lines.
powershell.exe -command “Set-ExecutionPolicy Unrestricted -force”
powershell.exe c:\Scripts\checksvculti1.ps1
The script looks correct other than that piece.
I am totally new to this scripting World. Could you please let me know how wrapper script work. Is this new notepad file and save as .cmd? with those 2 lines mentioned in it? and schedule .cmd to run the script? Please help
no problem, that is correct. save the two lines in notepad and save with .cmd extension.
I included those 2 lines in notepad and saved as srv.cmd. when i run this i am getting the error.
Set-executionpolicy: A parameter canot find that matches parameter name unrestricted -force’
You have this line in there with the quotes correct?
powershell.exe -command “Set-ExecutionPolicy Unrestricted -force”
and this is running from a command prompt and not from a powershell command line
Yes, Correct. i did all the things which you had mentioned. and running thru command prompt.but m getting the error message… but interesting thing is when i execute .cmd i recive email immediatly.
any solution??
What Windows version are you running the script on? Windows 2008 R2, Windows 7, Windows Server 2012 or Windows 2003 R2? Makes no sense why it is not taking the command. Give me a bit more detail on your environment.
its windows 2003R2..and i have admin capabilities.. Powershell 1.0
I think the problem is you are running PowerShell 1.0 and Set-ExecutionPolicy Unrestricted -force is supported in PowerShell 2.0. You can install PowerShe11 2.0 on your Windows 2003 R2 server. First make sure to install .NET 2.0 sp2 next install PowerShell 2 Windows Management Framework from http://support.microsoft.com/kb/96892. Make sure to download the correct Windows 2003 package and install it. This PowerShell script is for PowerShell 2.0.
Thank you, I want to write a output in a location to the notepad. How i can do it.? Please help
Are you wanting to write the output of the script to a file after it runs? What is it you are trying to achieve? Give me an idea and I can give you the example for use with the check service script.
yes. i want to write the output of the script to Notepad after it runs as a logging.. am not talking about this perticular script , script may be anything but i want it to be written its output to notpad when it runs each time without overwritten
Sorry for the delay things have been a bit busy for me lately. To write to a file you will need to define the logfile name and location then for each line use Out-File to append content and also Add-Content to write information to the file. Something like this should work.
function FuncCheckService{
param($ServiceName)
$LogFileName = “c:\logs\servicechk.txt”
$arrService = Get-Service -Name $ServiceName
if ($arrService.Status -ne “Running”){
Start-Service $ServiceName
Add-Content -Path $LogFileName -Value “`n$Now” -Encoding ASCII
Add-Content -Path $LogFileName -Value “`nServername : ($ServiceName) service started.” -Encoding ASCII
FuncMail -To “myemail@yourhost.com” -From “myserver@yourhost.com” -Subject “Servername : ($ServiceName) service started.” -Body “Service $ServiceName started” -smtpServer “mysmtpserver.com”
}
}
Hi,
I was searching for powershell script as a workaround to monitor one of my service which is having problem of hanging frequently.
Thank you for your script, I will be able to have this running while working on the permanent solution of the root cause.
However, I have a problem. When I execute the script in powershell manually, it is running fine where it notifies me if the service is running and only restarting it if the service is down.
But when I put it in Taks Scheduler, it always restart the service regardless it is Running or not.
I’m using Windows Server 2008 R2 Enterprise and PowerShell v2.
The script is like this (I added some other requirement for the OK status):
————————————————————————
function FuncCheckService{
param($ServiceName)
$arrService = Get-Service -Name $ServiceName
# If the service is running just send OK notification to email
if ($arrService.Status -eq “Running”){
FuncMail -To “me@email.com” -From “server@email.com” -Subject “SERVERNAME : ($ServiceName) OK.” -Body “Service $ServiceName OK” -smtpServer “smtp.mailserver.com”
}
# If the service is not running, do a stop and start of the service and notify the action via email
if ($arrService.Status -ne “Running”){
Stop-Service $ServiceName
# Wait for 20 seconds before starting the service
ping 192.0.2.2 -n 1 -w 20000 > nul
Start-Service $ServiceName
FuncMail -To “me@email.com” -From “server@email.com” -Subject “SERVERNAME : ($ServiceName) service started.” -Body “Service $ServiceName started” -smtpServer “smtp.mailserver.com”
}
}
function FuncMail {
#param($strTo, $strFrom, $strSubject, $strBody, $smtpServer)
param($To, $From, $Subject, $Body, $smtpServer)
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$msg.From = $From
$msg.To.Add($To)
$msg.Subject = $Subject
$msg.IsBodyHtml = 1
$msg.Body = $Body
$smtp.Send($msg)
}
FuncCheckService -ServiceName “Apache Tomcat”
————————————————————————
I am not sure if the script or the way I put it in the Task Scheduler.
If the script is OK, I might need your advise on how can I put this on task scheduler.
Thanks.
Did you create the cmd wrapper script that calls the PowerShell script and also with the task scheduler make sure the parameters are not set to only run when logged in. One other point is to make sure the account running the task has the right to run batch and services
No, I did not create the cmd wrapper.
Actually, I don’t really understand what is the cmd wrapper and how to create and use it.
Can you help me to explain how I can create and use/operate the cmd wrapper?
Thanks.
Regards,
Kafan
You need to create the wrapper script ( a wrapper script is another script that calls a script) The reason is due to privileges the script needs so it can run. So the first line in the script sets PowerShell to run in unrestricted mode and then runs the PowerShell script. Copy the below contents and save it as chksvc.cmd, make sure to change the paths and name of the script to match yours.
powershell.exe -command “Set-ExecutionPolicy Unrestricted -force”
powershell.exe c:\Scripts\checksvculti1.ps1
Now in you scheduled task point it to use chksvc.cmd and you should be good to go.
Could you please tell me how to add more server in the mentioned script? I need 4 more services status but they are in different server.
Thankyou
The script is for only running locally on a single server. You would have to use psremoting feature to execute the command from a single point to multiple servers and that’s not what this script was designed to do.
Hi,
I have to import the result in database then I will send a mail by database mail configuration(MSSQLServer).
Please help me if possible.
Thanks,
Ajitesh
Thanks a lot for this wrapper script.It ran successfully on my server without any issues.
Glad it was of use!
The code is running fine when I right click on the wrapper script (.cmd file) “As Administrator”, but when I execute the same from Task Scheduler, it is not giving the expected results. I have checked the options “Run whether user is logged in or not” and “Run with highest privileges”
Are you using your id to run the task? One way is to set the task to run as System and it should be ok.
I used “Service Account” and also tried with “System” account, but it did not work either way. Please let me know if you need more information.