PowerShell – Script to Monitor a Service on a Group of servers – HTML Formatted Email Output

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

  1. computerList – List of Servers
  2. ServiceName – Name of Service
  3. SMTPMail – SMTP mail address
  4. FromID – Valid Email ID
  5. 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

Image

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 –

Image

Download the code here ServicesReport

Thanks for reading my space..

Happy Learning!!

About Prashanth Jayaram

DB Technologist, Author, Blogger, Service Delivery Manager at CTS, Automation Expert, Technet WIKI Ninja, MVB and Powershell Geek My Profile: https://social.technet.microsoft.com/profile/prashanth jayaram/ http://www.sqlshack.com/author/prashanth/ http://codingsight.com/author/prashanthjayaram/ https://www.red-gate.com/simple-talk/author/prashanthjayaram/ http://www.sqlservercentral.com/blogs/powersql-by-prashanth-jayaram/ Connect Me: Twitter @prashantjayaram GMAIL powershellsql@gmail.com The articles are published in: http://www.ssas-info.com/analysis-services-articles/ http://db-pub.com/ http://www.sswug.org/sswugresearch/community/
This entry was posted in PowerShell and tagged , , . Bookmark the permalink.

39 Responses to PowerShell – Script to Monitor a Service on a Group of servers – HTML Formatted Email Output

  1. Steven Paulich says:

    What is the layout of c:\computer.txt?
    \\servername\instance
    \\servername\instance

    or
    instancename
    instancename
    ..
    or some other layout?

    Like

  2. Steve Miller says:

    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 🙂

    Like

  3. Patrick says:

    Very nice. Thanks for sharing.

    Like

  4. Shoaib says:

    Exactly what I was looking for.. great work.. thnx!!

    Like

  5. Sam says:

    How can I add multiple services to check?

    Like

  6. Narayanan says:

    Is powershell required for all the servers. From which server we need to run this powershell script

    Please advise

    Like

    • 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

      Like

  7. Narayanan says:

    One more question,..is this will check daily and there is no end date.

    Regards
    Narayanan.

    Like

  8. Amri says:

    Can you modify the script to send email if there are stopped services only?

    Like

  9. hari says:

    Hi Prashanth,

    when I am running it is running as infinite loop. Is there any fix for this. Please help in this regard

    Like

  10. hari says:

    Hi Prashanth,

    I want to get only sql server services only. Is there any way we can do it

    Like

  11. Pushparaj says:

    HI , How to use this script daily using scheduled task, How to call the function in scheduled task, Please help

    Like

  12. Hari says:

    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.

    Like

  13. Dinesh says:

    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.

    Like

  14. Dinesh says:

    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….?

    Like

  15. Dinesh says:

    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.

    Like

  16. GrahamC says:

    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?

    Like

    • 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

      Like

  17. aniruddhak says:

    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

    Like

    • 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

      Like

Leave a comment