This post explains how to monitor a given service on a group of servers. The function Get-ServiceStatusReport comprises of various cmdLets and function to monitor any given service on a list of servers.
- Get-Service
- HTML Ouptut
- Email Address validation
You can customize it as per your requirement.
The Function Get-ServiceStatusReport contains five parameters
- computerList – List of Servers
- ServiceName – Name of Service
- SMTPMail – SMTP mail address
- FromID – Valid Email ID
- ToID – Valid Email ID
First you create the function using the below code and call the function. which is shown below
Example :-
Get-ServiceStatusReport -ComputerList c:\computer.txt -ServiceName SQL -SMTPMail mail01.pa.com -To pjayaram@ap.com -From pjayaram@ap.com
Script – You can also download this script below
*******************************************************************************
Function Get-ServiceStatusReport
{
param(
[String]$ServiceName,[String]$ComputerList,[String]$To,[String]$From,[string]$SMTPMail
)
$script:list = $ComputerList
$ServiceFileName= “c:\ServiceFileName.htm”
New-Item -ItemType file $ServiceFilename -Force
# Function to write the HTML Header to the file
Function writeHtmlHeader
{
param($fileName)
$date = ( get-date ).ToString(‘yyyy/MM/dd’)
Add-Content $fileName “<html>”
Add-Content $fileName “<head>”
Add-Content $fileName “<meta http-equiv=’Content-Type’ content=’text/html; charset=iso-8859-1′>”
Add-Content $fileName ‘<title>Service Status Report </title>’
add-content $fileName ‘<STYLE TYPE=”text/css”>’
add-content $fileName “<!–”
add-content $fileName “td {”
add-content $fileName “font-family: Tahoma;”
add-content $fileName “font-size: 11px;”
add-content $fileName “border-top: 1px solid #999999;”
add-content $fileName “border-right: 1px solid #999999;”
add-content $fileName “border-bottom: 1px solid #999999;”
add-content $fileName “border-left: 1px solid #999999;”
add-content $fileName “padding-top: 0px;”
add-content $fileName “padding-right: 0px;”
add-content $fileName “padding-bottom: 0px;”
add-content $fileName “padding-left: 0px;”
add-content $fileName “}”
add-content $fileName “body {”
add-content $fileName “margin-left: 5px;”
add-content $fileName “margin-top: 5px;”
add-content $fileName “margin-right: 0px;”
add-content $fileName “margin-bottom: 10px;”
add-content $fileName “”
add-content $fileName “table {”
add-content $fileName “border: thin solid #000000;”
add-content $fileName “}”
add-content $fileName “–>”
add-content $fileName “</style>”
Add-Content $fileName “</head>”
Add-Content $fileName “<body>”
add-content $fileName “<table width=’100%’>”
add-content $fileName “<tr bgcolor=’#CCCCCC’>”
add-content $fileName “<td colspan=’4′ height=’25’ align=’center’>”
add-content $fileName “<font face=’tahoma’ color=’#003399′ size=’4′><strong>Service Stauts Report – $date</strong></font>”
add-content $fileName “</td>”
add-content $fileName “</tr>”
add-content $fileName “</table>”
}
# Function to write the HTML Header to the file
Function writeTableHeader
{
param($fileName)
Add-Content $fileName “<tr bgcolor=#CCCCCC>”
Add-Content $fileName “<td width=’10%’ align=’center’>ServerName</td>”
Add-Content $fileName “<td width=’50%’ align=’center’>Service Name</td>”
Add-Content $fileName “<td width=’10%’ align=’center’>status</td>”
Add-Content $fileName “</tr>”
}
Function writeHtmlFooter
{
param($fileName)
Add-Content $fileName “</body>”
Add-Content $fileName “</html>”
}
Function writeDiskInfo
{
param($filename,$Servername,$name,$Status)
if( $status -eq “Stopped”)
{
Add-Content $fileName “<tr>”
Add-Content $fileName “<td bgcolor=’#FF0000′ align=left ><b>$servername</td>”
Add-Content $fileName “<td bgcolor=’#FF0000′ align=left ><b>$name</td>”
Add-Content $fileName “<td bgcolor=’#FF0000′ align=left ><b>$Status</td>”
Add-Content $fileName “</tr>”
}
else
{
Add-Content $fileName “<tr>”
Add-Content $fileName “<td >$servername</td>”
Add-Content $fileName “<td >$name</td>”
Add-Content $fileName “<td >$Status</td>”
Add-Content $fileName “</tr>”
}
}
writeHtmlHeader $ServiceFileName
Add-Content $ServiceFileName “<table width=’100%’><tbody>”
Add-Content $ServiceFileName “<tr bgcolor=’#CCCCCC’>”
Add-Content $ServiceFileName “<td width=’100%’ align=’center’ colSpan=3><font face=’tahoma’ color=’#003399′ size=’2′><strong> Service Details</strong></font></td>”
Add-Content $ServiceFileName “</tr>”
writeTableHeader $ServiceFileName
#Change value of the following parameter as needed
Foreach($ServerName in (Get-Content $script:list))
{
$service = Get-Service -ComputerName $servername| where { $_.displayname -like “*$ServiceName*”}|select MachineName,Name,status
if ($Service -ne $NULL)
{
foreach ($item in $service)
{
Write-Host $item.MachineName $item.name $item.Status
writeDiskInfo $ServiceFileName $item.MachineName $item.name $item.Status
}
}
}
Add-Content $ServiceFileName “</table>”
writeHtmlFooter $ServiceFileName
function Validate-IsEmail ([string]$Email)
{
return $Email -match “^(?(“”)(“”.+?””@)|(([0-9a-zA-Z]((\.(?!\.))|[-!#\$%&’\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-zA-Z])@))(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,6}))$”
}
Function sendEmail
{
param($from,$to,$subject,$smtphost,$htmlFileName)
[string]$receipients=”$to”
$body = Get-Content $htmlFileName
$body = New-Object System.Net.Mail.MailMessage $from, $receipients, $subject, $body
$body.isBodyhtml = $true
$smtpServer = $MailServer
$smtp = new-object Net.Mail.SmtpClient($smtphost)
$validfrom= Validate-IsEmail $from
if($validfrom -eq $TRUE)
{
$validTo= Validate-IsEmail $to
if($validTo -eq $TRUE)
{
$smtp.Send($body)
write-output “Email Sent!!”
}
}
else
{
write-output “Invalid entries, Try again!!”
}
}
$date = ( get-date ).ToString(‘yyyy/MM/dd’)
sendEmail -from $From -to $to -subject “Service Status – $Date” -smtphost $SMTPMail -htmlfilename $ServiceFilename
}
********************************************************************
Output –
Download the code here ServicesReport
Thanks for reading my space..
Happy Learning!!
What is the layout of c:\computer.txt?
\\servername\instance
\\servername\instance
…
or
instancename
instancename
..
or some other layout?
LikeLike
Just ServerName
abc
def
ghi
LikeLike
Are you able to execute? Let me know if you need any more information. Thanks.
LikeLike
Hi Prashanth, Thank you for the script, its good.
email is not working for multiple recipients can you please help me on this
LikeLike
Hi Chhatish,
Does email functionality working at least for single recipient?
–Prashanth
LikeLike
Hi Prashanth, it is working for single recipeint
LikeLike
can you please share your email id i will share the script with you, i have modified a little bit and share with you
LikeLike
Send me the script @powershellsql@gmail.com
LikeLike
You downloaded version of the code has computer.txt hardcoded. I’m just wondering if there are any other differences between the posted code and what is in the download file. Can you check this, thanks 🙂
LikeLike
Good find. Thanks for letting me know. I’ve modified the file, you can test with a new file. Thank you!!!
LikeLike
Very nice. Thanks for sharing.
LikeLike
Exactly what I was looking for.. great work.. thnx!!
LikeLike
How can I add multiple services to check?
LikeLike
Hi Sam,
I’ve re-wrote the script to handle multiple services. I’ll upload it by tomorrow.
LikeLike
Hello Sam,
Here is the updated script which meets your requirement.
Thanks for reading my space.
Bye.
LikeLike
Is powershell required for all the servers. From which server we need to run this powershell script
Please advise
LikeLike
Narayanan,
No. Windows PowerShell 2.0 is installed by default on newer versions of the Windows operating systems.
You need have Powershell 2.0 from where you want to execute this script, Its not mandatory that the destination need to be configured with Powershell
-Prashanth
LikeLike
One more question,..is this will check daily and there is no end date.
Regards
Narayanan.
LikeLike
You can schedule a job to run daily.
LikeLike
Can you modify the script to send email if there are stopped services only?
LikeLike
sure you can do. Let me write one for you.
–Prashanth
LikeLike
Hi Prashanth,
when I am running it is running as infinite loop. Is there any fix for this. Please help in this regard
LikeLike
Hi Hari,
Can you check the input file?
Make sure that it don’t have any space and use backspace to keep the cursor to the last line of the input file.
Let me know your test results.
LikeLike
Hi Prashanth,
Thanks for reply. Still same problem, It continuously updating htm file.
LikeLike
Hi Prashanth,
I want to get only sql server services only. Is there any way we can do it
LikeLike
Hi Hari,
Can you please explain bit more in detail?
–Prashanth
LikeLike
Hi Prashanth,
I want to implement this in my server where I have only sql server services . Is there any way we can do it. Also still I am getting that infinite loop. Could you please help me.
LikeLike
HI , How to use this script daily using scheduled task, How to call the function in scheduled task, Please help
LikeLike
Hi Pushparaj,
Download the script and at the bottom of the script
just you need to calling function with the required parameter
for example, save the download file as Servervices.ps1
function Get-ServiceStatusReport
{
—
—
—
}
Get-ServiceStatusReport -ComputerList c:\computer.txt -ServiceName SQL -SMTPMail mail01.pa.com -To pjayaram@ap.com -From pjayaram@ap.com
and create the task scheduler
Refer the blog on how to create the task scheduler job
–Prashanth
LikeLike
Hi prashanth,
This script is working great. But if complete os is down we are not getting in report. Is there any way we can get status report mentioning server is down.
LikeLike
Hi Prashanth, I am new to scripting and I am actually looking for this type of script only. But my requirement is that I need to check different services (some are similar services ) on a list of 15 servers. The report should have just the status of only those services on each server that I require. I need only one report a day with all these details. Because we are having an application that is very crucial and we need to check for services on daily basis as they are very crucial to the bank. Please let me know if you can help on this.
LikeLike
Hi Dinesh,
You can refer the below link
Let me know if you need any further help on this.
–Prashanth
LikeLike
Hi Prashanth, The script is working fine. Excellent work by you. Thanks. But it is now working differently. I have 5 services to be checking on 4 servers. the report that comes out is the server name column has the same server name and there are 5 services for each server.. Meaning, for 4 servers to be checked for 5 services, we would be getting 20 lines. The first 5 lines are for server1, the next for server 2 and likewise. But the output now is like the server name is the same for all the 20 lines, the service names are in order… I did check the codes line by line but it is the same as the original that u have uploaded…. can you please help….?
LikeLike
And to add to my above comment, when I run it from the powershell directly, the results are perfect as expected but when I run this through a scheduled task, the results are as described above. I am not sure what the issue is.
LikeLike
I think its a problem with the profile.
–Prashanth
LikeLike
Hi,
Is there a way to modify the script so that it does not send the email, just outputs the HTML file to a location of my choice?
LikeLike
Hi Graham,
You can comment the line with #.
Go to an end of function where you can see sendEmail -from …….line and comment it
#sendEmail -from $From -to $to -subject “Service Status – $Date” -smtphost $SMTPMail -htmlfilename $ServiceFilename
–Prashanth
LikeLike
Hi Prashant,
How do i modify the script to store my service names in a file?
Also what will happen if the service is not available on the server? What will be the status displayed in report?
Thanks
aniruddha
LikeLike
Hi Aniruddha,
You can use Import-Csv to read the data from a file.
I can show you one example how you can do from a file.
For example,
Input file – serverlist.csv
ServerName,ApplicationName
hqdbsp18,DW
hqdbsp09,Heat
###Code
#Change value of following variables as needed
$ServerList = “f:\Powersql\ServerList.csv”
$OutputFile = “f:\Powersql\Output.htm”
$HTML = ‘
#Header{font-family:”Trebuchet MS”, Arial, Helvetica, sans-serif;width:100%;border-collapse:collapse;}
#Header td, #Header th {font-size:14px;border:1px solid #98bf21;padding:3px 7px 2px 7px;}
#Header th {font-size:14px;text-align:left;padding-top:5px;padding-bottom:4px;background-color:#A7C942;color:#fff;}
#Header tr.alt td {color:#000;background-color:#EAF2D3;}
‘
$HTML += ”
Database Name
RecoveryModel
Last Full Backup Date
Last Differential Backup Date
Last Log Backup Date
”
[System.Reflection.Assembly]::LoadWithPartialName(‘Microsoft.SqlServer.SMO’) | out-null
Import-Csv $ServerList |ForEach-Object {
$ServerName=$_.ServerName
$AppName=$_.ApplicationName
$HTML += “$ServerName – $AppName”
$SQLServer = New-Object (‘Microsoft.SqlServer.Management.Smo.Server’) $ServerName
Foreach($Database in $SQLServer.Databases)
{
$DaysSince = ((Get-Date) – $Database.LastBackupDate).Days
$DaysSinceDiff = ((Get-Date) – $Database.LastDifferentialBackupDate).Days
$DaysSinceLog = ((Get-Date) – $Database.LastLogBackupDate).Days
IF(($Database.Name) -ne ‘tempdb’ -and ($Database.Name) -ne ‘model’)
{
if ($Database.RecoveryModel -like “simple” )
{
$HTML += ”
$($Database.Name)
$($Database.RecoveryModel)
$($Database.LastBackupDate)
NA
NA
”
}
else
{
$HTML += ”
$($Database.Name)
$($Database.RecoveryModel)
$($Database.LastBackupDate)
$($Database.LastDifferentialBackupDate)
$($Database.LastLogBackupDate)
”
}
}
}
}
$HTML += “”
$HTML | Out-File $OutputFile
Its not going to list if service is not available. It will not display anything.
Let me know if you have any further information required
–Prashanth
LikeLike