Forum Discussion

Adamzter81's avatar
Adamzter81
Copper Contributor
Jul 31, 2024

Powershell to Monitor Services

Hello,

 

I have specific services that I would like to monitor on specific servers and send out alert if service is stopped.  Below is a script that works for monitoring one service on a specific server.

 

Ideally, I would like to do this to monitor multiple services on multiple servers.  Not all servic names are going to be same for all servers.  I am trying to think how to do it.  Any guidance would be appreciated.

 

 

 

#All Variables are defined below
$servername = 'InternalServerName'
$ServiceName = 'InternalServiceName'
$ServiceStatus = Get-Service -ComputerName "$servername" -Name "$ServiceName"
$ServiceState = $ServiceStatus.Status
#All Variables are defined above

# All functions are defined below
Function ServiceCheck
{
if 
    ($ServiceStatus.Status -eq 'Running') {Write-Host 'Running'}
Else
   {Sendmail("Alert Triggered")}
}
Function sendMail ($message)
{
    "Sending Email"

    #SMTP server name
    $smtpServer = "smtp.office365.com"

    #Creating a Mail object
    $msg = new-object Net.Mail.MailMessage

    $emailPassword = "HiddenPassword"
    $emailCredential = New-Object System.Net.NetworkCredential("email address removed for privacy reasons", $emailPassword)

    #Creating SMTP server object
    $smtp = new-object Net.Mail.SmtpClient($smtpServer)
    $smtp.Port = 587
    
    $smtp.EnableSSl = $true
    $smtp.Credentials = $emailCredential

    #Email structure
    $msg.From = "email address removed for privacy reasons"
    $msg.To.add("email address removed for privacy reasons")
    $msg.subject = "Alert - $ServiceName on $servername is $ServiceState" 
    $msg.body = "$ServiceName on $servername is $ServiceState"

    #Sending email
    $smtp.Send($msg)

    "Email Sent"

}

# All functions are defined Above


#All functions are called below
cls
ServiceCheck
#All functions are called above

 

 

  • #Loop through all servers and services for each server
    foreach ($servername in $servernames)
    foreach ($ServiceName in $ServiceNames) {
    If (Get-Service -ComputerName "$servername" -Name "$ServiceName") {
    $ServiceStatus = Get-Service -ComputerName "$servername" -Name "$ServiceName"
    $ServiceState = $ServiceStatus.Status
    ServiceCheck
    }
    }
    }

    This checks if service is there, then checks status

  • Adamzter81 You could use it like this: (Not tested)

     

    #All Variables are defined below
    $servernames = 'Server1', 'Server2'
    $ServiceNames = 'InternalServiceName1', 'InternalServiceName1'
    
    # All functions are defined below
    Function ServiceCheck {
        if 
        ($ServiceStatus.Status -eq 'Running') { Write-Host 'Running' }
        Else
        { Sendmail("Alert Triggered") }
    }
    Function sendMail ($message) {
        "Sending Email"
    
        #SMTP server name
        $smtpServer = "smtp.office365.com"
    
        #Creating a Mail object
        $msg = new-object Net.Mail.MailMessage
    
        $emailPassword = "HiddenPassword"
        $emailCredential = New-Object System.Net.NetworkCredential("email address removed for privacy reasons", $emailPassword)
    
        #Creating SMTP server object
        $smtp = new-object Net.Mail.SmtpClient($smtpServer)
        $smtp.Port = 587
        
        $smtp.EnableSSl = $true
        $smtp.Credentials = $emailCredential
    
        #Email structure
        $msg.From = "email address removed for privacy reasons"
        $msg.To.add("email address removed for privacy reasons")
        $msg.subject = "Alert - $ServiceName on $servername is $ServiceState" 
        $msg.body = "$ServiceName on $servername is $ServiceState"
    
        #Sending email
        $smtp.Send($msg)
    
        "Email Sent"
    
    }
    
    #Loop through all servers and services for each server
    foreach ($servername in $servernames) {
        foreach ($ServiceName in $ServiceNames) {
            $ServiceStatus = Get-Service -ComputerName "$servername" -Name "$ServiceName"
            $ServiceState = $ServiceStatus.Status
            ServiceCheck
        }
    }



    Please click Mark as Best Response & Like if my post helped you to solve your issue.
    This will help others to find the correct solution easily. It also closes the item.

    If one of the posts was helpful in other ways, please consider giving it a Like.

    • Adamzter81's avatar
      Adamzter81
      Copper Contributor
      Thanks Harm. The problem is not all services are running on all servers. For example ADDS service may not be running on an App server so if we go with above solution, it will generate false alerts maybe, I will still test it out.
      • Harm_Veenstra's avatar
        Harm_Veenstra
        MVP

        #Loop through all servers and services for each server
        foreach ($servername in $servernames)
        foreach ($ServiceName in $ServiceNames) {
        If (Get-Service -ComputerName "$servername" -Name "$ServiceName") {
        $ServiceStatus = Get-Service -ComputerName "$servername" -Name "$ServiceName"
        $ServiceState = $ServiceStatus.Status
        ServiceCheck
        }
        }
        }

        This checks if service is there, then checks status

Resources