Network Monitoring Powershell Script

Introduction

This Network Monitoring Powershell script was written to use in a Windows network environment to do some simple (ping test) network monitoring. The script will ping a list of devices (IP addresses) that you provide the script and e-mail the results of the ping tests to a specified e-mail address. This is an extremely simple way to do network monitoring and for many small locations is more than sufficient for the needs. I use this script in an office of approximately 15 people. Mostly I use this script to monitor wireless routers and printers. But it also works to monitor the redundant internet connections, servers, VPN connections and I have found that I can even determine when there is a power outage at the office as many of the main network devices, including the AD server this script is run on along with our switches, firewalls and modems run off of battery backups. Thus, despite the power outage, the script still runs and is able to get to the internet for about 20 minutes after a power outage.

History

The first iteration of this script would send the network monitoring results e-mail regardless of whether there were failures or not. At this point I had Windows Task Scheduler running the script every hour. The number of e-mails quickly became annoying. I then had the script only send results if there was a ping test failure. I realized the problem with this if a device went down Friday evening and wasn’t needed until the following week and thus didn’t require immediate attention. In this case I would receive notification e-mails every hour all weekend. Still too many e-mails. This is when I added the failure tracking feature to the network monitoring script in that if a device goes down the script notes this using text files. Any continuing failures for the device that is down won’t trigger an e-mail being sent. After adding this tracking I was then able to increase the frequency of the ping tests to every 5 minutes.

Setup

File & Directory: I put my script in a file called “Ping_Test_Script.ps1” in a directory I created c:\Scripts\. I also created the directory for failure tracking as c:\Scripts\Failure_Tracking\.
Script Customization: The script will have to be customized with your e-mail information, network IP addresses to monitor, section headings (I use “Firewalls”, “Servers”, “Printers” etc).
Task Scheduler: There are many pages with instructions on how to schedule powershell scripts. The process is extremely easy but I will list the steps very briefly here.
1. Open Task Scheduler.
2. Left click “Task Scheduler Library” in the left pane.
3. Right click in the right pane and left click “Create Basic Task”.
4. Give the task/script a name and description.
5. Set it up with a daily schedule. In my Task Scheduler I am unable to set a recurring schedule of less than one day at this point.
6. For action select “Start a program” and click next.
7. In the Program/script box enter powershell -file “c:\Scripts\Daily_Ping_Check.ps1”
8. A Task Scheduler window will pop up asking if you want to run the following program: powershell. Click yes.
9. Now that the task is created you can now edit the task to change the schedule to suit your needs.

(For more in depth instructions on scheduling a powershell script please visit this very detailed page.)

Future Versions

Since creating this script I have just added to it as needed and didn’t pay much attention to ease of (re)use or anyone having to understand it but myself. As such, the script is pretty messy as programming standards go. Going through the process of preparing it to post online I have seen many areas that could use some improvement, specifically just cleaning it up and making better use of variables to keep all customizable options at the beginning for the implementation of the script to be more user friendly. Expect a cleaned up version (1.0) of this script to be here soon.

Network Monitoring Screenshots

Network Monitoring Pass

Network Monitoring Example Success E-mail. Subject shows that the test was successful.

Network Monitoring Failure

Network Monitoring Example Failure E-mail. Subject shows which device(s) failed and the device is highlighted in red in the e-mail with the downtime shown.

Network Monitoring Fixed

Network Monitoring Example Fixed E-mail. Subject shows which device(s) are now back online and the devices are highlighted in green in the e-mail with the downtime shown.


Network Monitoring Powershell Script was last modified: October 20th, 2016 by Mike Page
Posted in Free, IT Management, Network Monitoring, Powershell and tagged , , , , , .

9 Comments

  1. Hi Mike

    Is there is further development on the script, we tried using the script in our environment to minitor all our network links, like ILL and MPLS however are facing some problems with the same, any help from your end will be appreciated.

  2. Hello Sachin,

    It is definitely on my list of things to do. I have recently upgraded the server that this is running on to Windows Server 2016 and I am finding some minor issues. However, I think this is more of an OS issue than a script issue.

    If you can describe your issues maybe I can help. Have you tried just running the script in powershell to see what is happening?

  3. Hello Mike,

    kindly find below modification in your script as per our requirement, all the below mention IP are dump IPs of Internet Service Provider & MPLS service providers for our Organisation.We are trying to achieve to get email alerts in case of any failure in any of the services. When we run the script with the changes we are not getting any output inspite of the services are down. We have tried running your default script and it did generated an alert but the alerts were divided in to 3 section of WAN , Firewall, Switch. I have attached the Alert for your reference.

    Modified Script
    #==================================================================================================================
    #title :Ping_Test_Script.ps1 (rename from .txt to .ps1)
    #description :Monitor network devices using Powershell and Windows Task Scheduler.
    #author :Mike Page (www.builtbymike.ca)
    #date :20160216
    #version :0.9
    #usage :Powershell> ./Ping_Test_Script.ps1 (or Windows Task Scheduler)
    #notes :See http://www.builtbymike.ca for more information and more in depth description.
    #disclaimer :This script needs a lot of work to look nice, but functions fine. Further updates to come.
    #==================================================================================================================

    # Set e-mail properties
    $smtpServer = “192.178.14.40”;
    $smtpFrom = “ithelpdesk@testlab.com”;
    $smtpTo = “sachinb@testlab.com”;

    # Create an Array to store the destination hosts to ping
    [Array] $PingHosts = “10.10.1.178”, “172.30.5.14”, “172.4.1.10”, “173.54.206.88”, “115.192.5.134”, “109.48.40.88”, “168.25.233.130”, “198.34.81.190”, “172.34.80.242”, “172.33.80.74”, “172.39.6.70”, “172.80.106.6”
    $HostsTitles = @((“10.10.1.178”, “HO Airtel ILL”), (“172.30.5.14”, “HO RIL ILL”), (“172.4.1.10”, “Daman ILL”), (“173.54.206.88”, “Chennai ILL”), (“115.192.5.134”, “Turbe ILL”), (“109.48.40.88”, “Rorkee ILL”), (“168.25.233.130”, “Jesons.net”), (“198.34.81.190”, “HO Mpls”), (“172.34.80.242”, “Daman Mpls”), (“172.33.80.74”, “Rorkee Mpls”), (“172.39.6.70”, “ChennaiFac Mpls”), (“172.80.106.6”, “ChennaiOff Mpls”) )

    # Initialize body (This is the very top section header)
    $body = “WAN“;

    # Create counter
    $counter = 0;

    #Error counter
    $passerrorcounter = 0;
    $errorcounter = 0;

    # Error variables
    $PingFailure = “false”;
    $NewPingFailure = “false”;

    # Fixed variable
    $PingFixed = “false”;

    # Start subject
    $subject = “”;
    $Fixedsubject = “”;

    # Run Get-WmiObject using the Win32_PingStatus class against every host in the Array
    $WmiPingStatus = {Get-WmiObject -Class Win32_PingStatus -Filter (“Address='” + $_ + “‘”) -ComputerName .}
    $PingHosts | ForEach-Object -Process $WmiPingStatus | Select-Object -Property Address,StatusCode |
    foreach {
    #These are the various section headings for what is being ping checked.
    #Add more -Or $HostsTitles[$counter][1] -match “Switch ” for the various section headings you would like to use.
    If ($HostsTitles[$counter][1] -match “HO Airtel ILL ” -Or $HostsTitles[$counter][1] -match “HO RIL ILL ” -Or $HostsTitles[$counter][1] -match “Daman ILL ” -Or $HostsTitles[$counter][1] -match “Chennai ILL ” -Or $HostsTitles[$counter][1] -match “Turbe ILL ” -Or $HostsTitles[$counter][1] -match “Rorkee ILL ” -Or $HostsTitles[$counter][1] -match “Jesons.net ” -Or $HostsTitles[$counter][1] -match “HO Mpls ” -Or $HostsTitles[$counter][1] -match “Daman Mpls ” -Or $HostsTitles[$counter][1] -match “Rorkee Mpls ” -Or $HostsTitles[$counter][1] -match “ChennaiFac Mpls ” -Or $HostsTitles[$counter][1] -match “ChennaiOff Mpls “)
    {
    $body = $body + “” + $HostsTitles[$counter][1] + ““;}{$body + “” + $HostsTitles[$counter][1] + ““;
    }
    else//
    {

    # Get hostname
    $hostname = [System.Net.Dns]::GetHostbyAddress($_.Address)
    $tempHostName = $hostname.HostName.ToLower()

    # Create failure tracking path for this device
    $path = “c:\Scripts\Failure_tracking\” + $tempHostName.Replace(“.yourdomain.local”,””) + “.txt”;

    # If StatusCode is equal to 0 then do nothing (since 0 = success)
    If ($_.StatusCode -eq 0)
    {

    # Check to see if there is a failure file for this, if so then it has now come back online, highlight accordingly
    if (Test-Path $path)
    {

    # See how long device was down for
    $str = Get-Content $path;
    $i = [System.Decimal]::Parse($str);
    $i=$i*5;

    # There was previously a failure but now online. Mark green to show this in the e-mail.
    $body = $body + “” + $HostsTitles[$counter][1] + ” (” + $_.Address + ” | ” + $tempHostName.Replace(“.yourdomain.local”,””) + ” | ” + $i + ” minutes)

    # Since there is no longer a failure, delete the tracking file
    Remove-Item $path;

    # Set variable so that we know something is fixed
    $PingFixed = “true”;

    if ($passerrorcounter -eq 0)
    {
    $Fixedsubject = $Fixedsubject + $tempHostName.Replace(“.yourdomain.local”,””);
    }
    else
    {
    $Fixedsubject = $Fixedsubject + “, ” + $tempHostName.Replace(“.yourdomain.local”,””);
    }

    $passerrorcounter = 1;

    }
    else
    {
    # There was no previous failure
    $body = $body + $HostsTitles[$counter][1] + ” (” + $_.Address + ” | ” + $tempHostName.Replace(“.yourdomain.local”,””) + “)”
    }

    }
    # Else, if StatusCode is NOT equal to 0 then do something
    Else
    {
    # Set e-mail subject and body using details of non-responsive host

    if(Test-Connection -computer $_.Address -quiet)
    {
    $PingWarning = “true”;

    if (Test-Path $path)
    {
    # See how long device was down for
    $str = Get-Content $path;
    $i = [System.Decimal]::Parse($str);
    $i=$i*5;

    # There was previously a failure
    $body = $body + “” + $HostsTitles[$counter][1] + ” (” + $_.Address + ” | ” + $tempHostName.Replace(“.yourdomain.local”,””) + ” | ” + $i + ” minutes)

    # Since there is no longer a failure, delete the file
    Remove-Item $path;

    # Set variable so that we know something is fixed
    $PingFixed = “true”;

    if ($passerrorcounter -eq 0)
    {
    $Fixedsubject = $Fixedsubject + $tempHostName.Replace(“.yourdomain.local”,””);
    }
    else
    {
    $Fixedsubject = $Fixedsubject + “, ” + $tempHostName.Replace(“.yourdomain.local”,””);
    }

    $passerrorcounter = 1;
    }
    else
    {
    # There was NOT previously a failure
    $body = $body + “” + $HostsTitles[$counter][1] + ” (” + $_.Address + ” | ” + $tempHostName.Replace(“.yourdomain.local”,””) + “)

    }

    }
    else
    {

    # Check to see if there is a failure file for this, failure is continuing so increment it
    if (Test-Path $path)
    {

    # See how long device was down for
    $str = Get-Content $path;
    $i = [System.Decimal]::Parse($str);
    $i=$i*5;

    # There was previously a failure
    $OldPingFailure = “true”;
    $body = $body + “” + $HostsTitles[$counter][1] + ” (” + $_.Address + ” | ” + $tempHostName.Replace(“.yourdomain.local”,””) + ” | ” + $i + ” minutes)

    # Increase failure file integer
    $str = Get-Content $path;
    $i = [System.Decimal]::Parse($str)
    $i++
    Set-Content $path $i

    }
    else
    {
    # There was no previous failure, this is a new failure. Must mark for e-mail to be sent.
    $NewPingFailure = “true”;
    $body = $body + “” + $HostsTitles[$counter][1] + ” (” + $_.Address + ” | ” + $tempHostName.Replace(“.yourdomain.local”,””) + ” | 0 to 5 minutes)

    # Create a failure file
    $text = ‘1’;
    $text | Out-File $path;
    $text > $path;
    }

    }

    if ($errorcounter -eq 0)
    {
    $subject = $subject + $tempHostName.Replace(“.yourdomain.local”,””);
    }
    else
    {
    $subject = $subject + “, ” + $tempHostName.Replace(“.yourdomain.local”,””);
    }

    $errorcounter = 1;
    }
    }
    $counter = $counter+1;
    }

    # Set e-mail objects and send e-mail
    If($NewPingFailure -match “true” -Or $OldPingFailure -match “true”)
    {
    If($NewPingFailure -match “true”)
    {
    #New device failure. Send notification e-mail.

    $subject = “Ping Test Failure: ” + $subject;
    $smtpClient = New-Object Net.Mail.SmtpClient($smtpServer, 25);
    $emailFrom = New-Object Net.Mail.MailAddress $smtpFrom, $smtpFrom;
    $emailTo = New-Object Net.Mail.MailAddress $smtpTo, $smtpTo;
    $mailMsg = New-Object Net.Mail.MailMessage($emailFrom, $emailTo, $subject, $body);
    $mailMsg.IsBodyHTML = $true
    $smtpClient.Send($mailMsg)
    }
    else
    {
    #Getting to this point means that there isn’t a new failure. There still could be a previous device that has been down.
    #The ‘Warning’ signifies that a device didn’t respond to at least one of its pings. The ping test sends three or four
    #pings to each device. This does happen on occasion but I write it off as network congestion.

    #$subject = “Ping Test Warning: ” + $subject;

    #$smtpClient = New-Object Net.Mail.SmtpClient($smtpServer, 25);
    #$emailFrom = New-Object Net.Mail.MailAddress $smtpFrom, $smtpFrom;
    #$emailTo = New-Object Net.Mail.MailAddress $smtpTo, $smtpTo;
    #$mailMsg = New-Object Net.Mail.MailMessage($emailFrom, $emailTo, $subject, $body);
    #$mailMsg.IsBodyHTML = $true
    #$smtpClient.Send($mailMsg)
    }

    }
    else
    {
    if($PingFixed -match “true”)
    {
    #A device that was down is now up. Send an e-mail to notify.

    $subject = “Ping Test Pass (Fixed): ” + $Fixedsubject;

    $smtpClient = New-Object Net.Mail.SmtpClient($smtpServer, 25);
    $emailFrom = New-Object Net.Mail.MailAddress $smtpFrom, $smtpFrom;
    $emailTo = New-Object Net.Mail.MailAddress $smtpTo, $smtpTo;
    $mailMsg = New-Object Net.Mail.MailMessage($emailFrom, $emailTo, $subject, $body);
    $mailMsg.IsBodyHTML = $true
    $smtpClient.Send($mailMsg)
    }
    else
    {
    #I didn’t want to receive pass e-mails so this section is commented out.
    #These e-mails denote success.

    #$subject = “Ping Test Pass”;

    #$smtpClient = New-Object Net.Mail.SmtpClient($smtpServer, 25);
    #$emailFrom = New-Object Net.Mail.MailAddress $smtpFrom, $smtpFrom;
    #$emailTo = New-Object Net.Mail.MailAddress $smtpTo, $smtpTo;
    #$mailMsg = New-Object Net.Mail.MailMessage($emailFrom, $emailTo, $subject, $body);
    #$mailMsg.IsBodyHTML = $true
    #$smtpClient.Send($mailMsg)
    }
    # There are no failures.
    # Double check to make sure failure folder is emptied.
    Remove-Item c:\Scripts\Failure_tracking\*
    }

    Exit

    Email Alert Received.

    WAN
    DSL (10.243.185.105 | qcpl-105-185.243.103.qcplnet.com)
    HSA (16.53.206.68 | qcpl-105-185.243.103.qcplnet.com | 0 to 5 minutes)

    Firewall
    Firewall
    Fortigate (198.167.1.1 | qcpl-105-185.243.103.qcplnet.com | 5 minutes)

    Switch
    Switch
    Cisco 2900-01 (195.169.1.2 | qcpl-105-185.243.103.qcplnet.com)
    Cisco 2900-02 (199.168.4.3 | smb)

  4. Hello Mike,

    kindly find below modification in your script as per our requirement, all the below mention IP are dump IPs of Internet Service Provider & MPLS service providers for our Organisation.We are trying to achieve to get email alerts in case of any failure in any of the services. When we run the script without the changes we are not getting any output inspite of the services are down. We have tried running your default script and it did generated an alert but the alerts were divided in to 3 section of WAN , Firewall, Switch. I have attached the Alert for your reference.

    Modified Script
    #==================================================================================================================
    #title :Ping_Test_Script.ps1 (rename from .txt to .ps1)
    #description :Monitor network devices using Powershell and Windows Task Scheduler.
    #author :Mike Page (www.builtbymike.ca)
    #date :20160216
    #version :0.9
    #usage :Powershell> ./Ping_Test_Script.ps1 (or Windows Task Scheduler)
    #notes :See http://www.builtbymike.ca for more information and more in depth description.
    #disclaimer :This script needs a lot of work to look nice, but functions fine. Further updates to come.
    #==================================================================================================================

    # Set e-mail properties
    $smtpServer = “192.178.14.40”;
    $smtpFrom = “ithelpdesk@testlab.com”;
    $smtpTo = “sachinb@testlab.com”;

    # Create an Array to store the destination hosts to ping
    [Array] $PingHosts = “10.10.1.178”, “172.30.5.14”, “172.4.1.10”, “173.54.206.88”, “115.192.5.134”, “109.48.40.88”, “168.25.233.130”, “198.34.81.190”, “172.34.80.242”, “172.33.80.74”, “172.39.6.70”, “172.80.106.6”
    $HostsTitles = @((“10.10.1.178”, “HO Airtel ILL”), (“172.30.5.14”, “HO RIL ILL”), (“172.4.1.10”, “Daman ILL”), (“173.54.206.88”, “Chennai ILL”), (“115.192.5.134”, “Turbe ILL”), (“109.48.40.88”, “Rorkee ILL”), (“168.25.233.130”, “Jesons.net”), (“198.34.81.190”, “HO Mpls”), (“172.34.80.242”, “Daman Mpls”), (“172.33.80.74”, “Rorkee Mpls”), (“172.39.6.70”, “ChennaiFac Mpls”), (“172.80.106.6”, “ChennaiOff Mpls”) )

    # Initialize body (This is the very top section header)
    $body = “WAN“;

    # Create counter
    $counter = 0;

    #Error counter
    $passerrorcounter = 0;
    $errorcounter = 0;

    # Error variables
    $PingFailure = “false”;
    $NewPingFailure = “false”;

    # Fixed variable
    $PingFixed = “false”;

    # Start subject
    $subject = “”;
    $Fixedsubject = “”;

    # Run Get-WmiObject using the Win32_PingStatus class against every host in the Array
    $WmiPingStatus = {Get-WmiObject -Class Win32_PingStatus -Filter (“Address='” + $_ + “‘”) -ComputerName .}
    $PingHosts | ForEach-Object -Process $WmiPingStatus | Select-Object -Property Address,StatusCode |
    foreach {
    #These are the various section headings for what is being ping checked.
    #Add more -Or $HostsTitles[$counter][1] -match “Switch ” for the various section headings you would like to use.
    If ($HostsTitles[$counter][1] -match “HO Airtel ILL ” -Or $HostsTitles[$counter][1] -match “HO RIL ILL ” -Or $HostsTitles[$counter][1] -match “Daman ILL ” -Or $HostsTitles[$counter][1] -match “Chennai ILL ” -Or $HostsTitles[$counter][1] -match “Turbe ILL ” -Or $HostsTitles[$counter][1] -match “Rorkee ILL ” -Or $HostsTitles[$counter][1] -match “Jesons.net ” -Or $HostsTitles[$counter][1] -match “HO Mpls ” -Or $HostsTitles[$counter][1] -match “Daman Mpls ” -Or $HostsTitles[$counter][1] -match “Rorkee Mpls ” -Or $HostsTitles[$counter][1] -match “ChennaiFac Mpls ” -Or $HostsTitles[$counter][1] -match “ChennaiOff Mpls “)
    {
    $body = $body + “” + $HostsTitles[$counter][1] + ““;}{$body + “” + $HostsTitles[$counter][1] + ““;
    }
    else//
    {

    # Get hostname
    $hostname = [System.Net.Dns]::GetHostbyAddress($_.Address)
    $tempHostName = $hostname.HostName.ToLower()

    # Create failure tracking path for this device
    $path = “c:\Scripts\Failure_tracking\” + $tempHostName.Replace(“.yourdomain.local”,””) + “.txt”;

    # If StatusCode is equal to 0 then do nothing (since 0 = success)
    If ($_.StatusCode -eq 0)
    {

    # Check to see if there is a failure file for this, if so then it has now come back online, highlight accordingly
    if (Test-Path $path)
    {

    Same Script ……
    }

    Exit

    Email Alert Received.

    WAN
    DSL (10.243.185.105 | qcpl-105-185.243.103.qcplnet.com)
    HSA (16.53.206.68 | qcpl-105-185.243.103.qcplnet.com | 0 to 5 minutes)

    Firewall
    Firewall
    Fortigate (198.167.1.1 | qcpl-105-185.243.103.qcplnet.com | 5 minutes)

    Switch
    Switch
    Cisco 2900-01 (195.169.1.2 | qcpl-105-185.243.103.qcplnet.com)
    Cisco 2900-02 (199.168.4.3 | smb)

  5. Hello Mike,

    kindly find below modification in your script as per our requirement, all the below mention IP are dump IPs of Internet Service Provider & MPLS service providers for our Organisation.We are trying to achieve to get email alerts in case of any failure in any of the services. When we run the script without the changes we are not getting any output inspite of the services are down. We have tried running your default script and it did generated an alert but the alerts were divided in to 3 section of WAN , Firewall, Switch. I have attached the Alert for your reference.

    Modified Script
    #==================================================================================================================
    #title :Ping_Test_Script.ps1 (rename from .txt to .ps1)
    #description :Monitor network devices using Powershell and Windows Task Scheduler.
    #author :Mike Page (www.builtbymike.ca)
    #date :20160216
    #version :0.9
    #usage :Powershell> ./Ping_Test_Script.ps1 (or Windows Task Scheduler)
    #notes :See http://www.builtbymike.ca for more information and more in depth description.
    #disclaimer :This script needs a lot of work to look nice, but functions fine. Further updates to come.
    #==================================================================================================================

    # Set e-mail properties
    $smtpServer = “192.178.14.40”;
    $smtpFrom = “ithelpdesk@testlab.com”;
    $smtpTo = “sachinb@testlab.com”;

    # Create an Array to store the destination hosts to ping
    [Array] $PingHosts = “10.10.1.178”, “172.30.5.14”, “172.4.1.10”, “173.54.206.88”, “115.192.5.134”, “109.48.40.88”, “168.25.233.130”, “198.34.81.190”, “172.34.80.242”, “172.33.80.74”, “172.39.6.70”, “172.80.106.6”
    $HostsTitles = @((“10.10.1.178”, “HO Airtel ILL”), (“172.30.5.14”, “HO RIL ILL”), (“172.4.1.10”, “Daman ILL”), (“173.54.206.88”, “Chennai ILL”), (“115.192.5.134”, “Turbe ILL”), (“109.48.40.88”, “Rorkee ILL”), (“168.25.233.130”, “Jesons.net”), (“198.34.81.190”, “HO Mpls”), (“172.34.80.242”, “Daman Mpls”), (“172.33.80.74”, “Rorkee Mpls”), (“172.39.6.70”, “ChennaiFac Mpls”), (“172.80.106.6”, “ChennaiOff Mpls”) )

    # Initialize body (This is the very top section header)
    $body = “WAN“;

    # Create counter
    $counter = 0;

    #Error counter
    $passerrorcounter = 0;
    $errorcounter = 0;

    # Error variables
    $PingFailure = “false”;
    $NewPingFailure = “false”;

    # Fixed variable
    $PingFixed = “false”;

    # Start subject
    $subject = “”;
    $Fixedsubject = “”;

    # Run Get-WmiObject using the Win32_PingStatus class against every host in the Array
    $WmiPingStatus = {Get-WmiObject -Class Win32_PingStatus -Filter (“Address='” + $_ + “‘”) -ComputerName .}
    $PingHosts | ForEach-Object -Process $WmiPingStatus | Select-Object -Property Address,StatusCode |
    foreach {
    #These are the various section headings for what is being ping checked.
    #Add more -Or $HostsTitles[$counter][1] -match “Switch ” for the various section headings you would like to use.
    If ($HostsTitles[$counter][1] -match “HO Airtel ILL ” -Or $HostsTitles[$counter][1] -match “HO RIL ILL ” -Or $HostsTitles[$counter][1] -match “Daman ILL ” -Or $HostsTitles[$counter][1] -match “Chennai ILL ” -Or $HostsTitles[$counter][1] -match “Turbe ILL ” -Or $HostsTitles[$counter][1] -match “Rorkee ILL ” -Or $HostsTitles[$counter][1] -match “Jesons.net ” -Or $HostsTitles[$counter][1] -match “HO Mpls ” -Or $HostsTitles[$counter][1] -match “Daman Mpls ” -Or $HostsTitles[$counter][1] -match “Rorkee Mpls ” -Or $HostsTitles[$counter][1] -match “ChennaiFac Mpls ” -Or $HostsTitles[$counter][1] -match “ChennaiOff Mpls “)
    {
    $body = $body + “” + $HostsTitles[$counter][1] + ““;}{$body + “” + $HostsTitles[$counter][1] + ““;
    }
    else//
    {

    # Get hostname
    $hostname = [System.Net.Dns]::GetHostbyAddress($_.Address)
    $tempHostName = $hostname.HostName.ToLower()

    # Create failure tracking path for this device
    $path = “c:\Scripts\Failure_tracking\” + $tempHostName.Replace(“.yourdomain.local”,””) + “.txt”;

    # If StatusCode is equal to 0 then do nothing (since 0 = success)
    If ($_.StatusCode -eq 0)
    {

    # Check to see if there is a failure file for this, if so then it has now come back online, highlight accordingly
    if (Test-Path $path)
    {

    # See how long device was down for
    $str = Get-Content $path;
    $i = [System.Decimal]::Parse($str);
    $i=$i*5;

    # There was previously a failure but now online. Mark green to show this in the e-mail.
    $body = $body + “” + $HostsTitles[$counter][1] + ” (” + $_.Address + ” | ” + $tempHostName.Replace(“.yourdomain.local”,””) + ” | ” + $i + ” minutes)

    # Since there is no longer a failure, delete the tracking file
    Remove-Item $path;

    # Set variable so that we know something is fixed
    $PingFixed = “true”;

    if ($passerrorcounter -eq 0)
    {
    $Fixedsubject = $Fixedsubject + $tempHostName.Replace(“.yourdomain.local”,””);
    }
    else
    {
    $Fixedsubject = $Fixedsubject + “, ” + $tempHostName.Replace(“.yourdomain.local”,””);
    }

    $passerrorcounter = 1;

    }
    else
    {
    # There was no previous failure
    $body = $body + $HostsTitles[$counter][1] + ” (” + $_.Address + ” | ” + $tempHostName.Replace(“.yourdomain.local”,””) + “)”
    }

    }
    # Else, if StatusCode is NOT equal to 0 then do something
    Else
    {
    # Set e-mail subject and body using details of non-responsive host

    if(Test-Connection -computer $_.Address -quiet)
    {
    $PingWarning = “true”;

    if (Test-Path $path)
    {
    # See how long device was down for
    $str = Get-Content $path;
    $i = [System.Decimal]::Parse($str);
    $i=$i*5;

    # There was previously a failure
    $body = $body + “” + $HostsTitles[$counter][1] + ” (” + $_.Address + ” | ” + $tempHostName.Replace(“.yourdomain.local”,””) + ” | ” + $i + ” minutes)

    # Since there is no longer a failure, delete the file
    Remove-Item $path;

    # Set variable so that we know something is fixed
    $PingFixed = “true”;

    if ($passerrorcounter -eq 0)
    {
    $Fixedsubject = $Fixedsubject + $tempHostName.Replace(“.yourdomain.local”,””);
    }
    else
    {
    $Fixedsubject = $Fixedsubject + “, ” + $tempHostName.Replace(“.yourdomain.local”,””);
    }

    $passerrorcounter = 1;
    }
    else
    {
    # There was NOT previously a failure
    $body = $body + “” + $HostsTitles[$counter][1] + ” (” + $_.Address + ” | ” + $tempHostName.Replace(“.yourdomain.local”,””) + “)

    }

    }
    else
    {

    # Check to see if there is a failure file for this, failure is continuing so increment it
    if (Test-Path $path)
    {

    # See how long device was down for
    $str = Get-Content $path;
    $i = [System.Decimal]::Parse($str);
    $i=$i*5;

    # There was previously a failure
    $OldPingFailure = “true”;
    $body = $body + “” + $HostsTitles[$counter][1] + ” (” + $_.Address + ” | ” + $tempHostName.Replace(“.yourdomain.local”,””) + ” | ” + $i + ” minutes)

    # Increase failure file integer
    $str = Get-Content $path;
    $i = [System.Decimal]::Parse($str)
    $i++
    Set-Content $path $i

    }
    else
    {
    # There was no previous failure, this is a new failure. Must mark for e-mail to be sent.
    $NewPingFailure = “true”;
    $body = $body + “” + $HostsTitles[$counter][1] + ” (” + $_.Address + ” | ” + $tempHostName.Replace(“.yourdomain.local”,””) + ” | 0 to 5 minutes)

    # Create a failure file
    $text = ‘1’;
    $text | Out-File $path;
    $text > $path;
    }

    }

    if ($errorcounter -eq 0)
    {
    $subject = $subject + $tempHostName.Replace(“.yourdomain.local”,””);
    }
    else
    {
    $subject = $subject + “, ” + $tempHostName.Replace(“.yourdomain.local”,””);
    }

    $errorcounter = 1;
    }
    }
    $counter = $counter+1;
    }

    # Set e-mail objects and send e-mail
    If($NewPingFailure -match “true” -Or $OldPingFailure -match “true”)
    {
    If($NewPingFailure -match “true”)
    {
    #New device failure. Send notification e-mail.

    $subject = “Ping Test Failure: ” + $subject;
    $smtpClient = New-Object Net.Mail.SmtpClient($smtpServer, 25);
    $emailFrom = New-Object Net.Mail.MailAddress $smtpFrom, $smtpFrom;
    $emailTo = New-Object Net.Mail.MailAddress $smtpTo, $smtpTo;
    $mailMsg = New-Object Net.Mail.MailMessage($emailFrom, $emailTo, $subject, $body);
    $mailMsg.IsBodyHTML = $true
    $smtpClient.Send($mailMsg)
    }
    else
    {
    #Getting to this point means that there isn’t a new failure. There still could be a previous device that has been down.
    #The ‘Warning’ signifies that a device didn’t respond to at least one of its pings. The ping test sends three or four
    #pings to each device. This does happen on occasion but I write it off as network congestion.

    #$subject = “Ping Test Warning: ” + $subject;

    #$smtpClient = New-Object Net.Mail.SmtpClient($smtpServer, 25);
    #$emailFrom = New-Object Net.Mail.MailAddress $smtpFrom, $smtpFrom;
    #$emailTo = New-Object Net.Mail.MailAddress $smtpTo, $smtpTo;
    #$mailMsg = New-Object Net.Mail.MailMessage($emailFrom, $emailTo, $subject, $body);
    #$mailMsg.IsBodyHTML = $true
    #$smtpClient.Send($mailMsg)
    }

    }
    else
    {
    if($PingFixed -match “true”)
    {
    #A device that was down is now up. Send an e-mail to notify.

    $subject = “Ping Test Pass (Fixed): ” + $Fixedsubject;

    $smtpClient = New-Object Net.Mail.SmtpClient($smtpServer, 25);
    $emailFrom = New-Object Net.Mail.MailAddress $smtpFrom, $smtpFrom;
    $emailTo = New-Object Net.Mail.MailAddress $smtpTo, $smtpTo;
    $mailMsg = New-Object Net.Mail.MailMessage($emailFrom, $emailTo, $subject, $body);
    $mailMsg.IsBodyHTML = $true
    $smtpClient.Send($mailMsg)
    }
    else
    {
    #I didn’t want to receive pass e-mails so this section is commented out.
    #These e-mails denote success.

    #$subject = “Ping Test Pass”;

    #$smtpClient = New-Object Net.Mail.SmtpClient($smtpServer, 25);
    #$emailFrom = New-Object Net.Mail.MailAddress $smtpFrom, $smtpFrom;
    #$emailTo = New-Object Net.Mail.MailAddress $smtpTo, $smtpTo;
    #$mailMsg = New-Object Net.Mail.MailMessage($emailFrom, $emailTo, $subject, $body);
    #$mailMsg.IsBodyHTML = $true
    #$smtpClient.Send($mailMsg)
    }
    # There are no failures.
    # Double check to make sure failure folder is emptied.
    Remove-Item c:\Scripts\Failure_tracking\*
    }

    Exit

    Email Alert Received.

    WAN
    DSL (10.243.185.105 | qcpl-105-185.243.103.qcplnet.com)
    HSA (16.53.206.68 | qcpl-105-185.243.103.qcplnet.com | 0 to 5 minutes)

    Firewall
    Firewall
    Fortigate (198.167.1.1 | qcpl-105-185.243.103.qcplnet.com | 5 minutes)

    Switch
    Switch
    Cisco 2900-01 (195.169.1.2 | qcpl-105-185.243.103.qcplnet.com)
    Cisco 2900-02 (199.168.4.3 | smb)

  6. Hello Mike,

    kindly find below modification in your script as per our requirement, all the below mention IP are dump IPs of Internet Service Provider & MPLS service providers for our Organisation.We are trying to achieve to get email alerts in case of any failure in any of the services. When we run the script without the changes we are not getting any output inspite of the services are down. We have tried running your default script and it did generated an alert but the alerts were divided in to 3 section of WAN , Firewall, Switch. I have attached the Alert for your reference.

    Modified Script
    #==================================================================================================================
    #title :Ping_Test_Script.ps1 (rename from .txt to .ps1)
    #description :Monitor network devices using Powershell and Windows Task Scheduler.
    #author :Mike Page (www.builtbymike.ca)
    #date :20160216
    #version :0.9
    #usage :Powershell> ./Ping_Test_Script.ps1 (or Windows Task Scheduler)
    #notes :See http://www.builtbymike.ca for more information and more in depth description.
    #disclaimer :This script needs a lot of work to look nice, but functions fine. Further updates to come.
    #==================================================================================================================

    # Set e-mail properties
    $smtpServer = “192.178.14.40”;
    $smtpFrom = “ithelpdesk@testlab.com”;
    $smtpTo = “sachinb@testlab.com”;

    # Create an Array to store the destination hosts to ping
    [Array] $PingHosts = “10.10.1.178”, “172.30.5.14”, “172.4.1.10”, “173.54.206.88”, “115.192.5.134”, “109.48.40.88”, “168.25.233.130”, “198.34.81.190”, “172.34.80.242”, “172.33.80.74”, “172.39.6.70”, “172.80.106.6”
    $HostsTitles = @((“10.10.1.178”, “HO Airtel ILL”), (“172.30.5.14”, “HO RIL ILL”), (“172.4.1.10”, “Daman ILL”), (“173.54.206.88”, “Chennai ILL”), (“115.192.5.134”, “Turbe ILL”), (“109.48.40.88”, “Rorkee ILL”), (“168.25.233.130”, “Jesons.net”), (“198.34.81.190”, “HO Mpls”), (“172.34.80.242”, “Daman Mpls”), (“172.33.80.74”, “Rorkee Mpls”), (“172.39.6.70”, “ChennaiFac Mpls”), (“172.80.106.6”, “ChennaiOff Mpls”) )

    # Initialize body (This is the very top section header)
    $body = “WAN“;

    # Create counter

    Same script..

    }

    Exit

    Email Alert Received.

    WAN
    DSL (10.243.185.105 | qcpl-105-185.243.103.qcplnet.com)
    HSA (16.53.206.68 | qcpl-105-185.243.103.qcplnet.com | 0 to 5 minutes)

    Firewall
    Firewall
    Fortigate (198.167.1.1 | qcpl-105-185.243.103.qcplnet.com | 5 minutes)

    Switch
    Switch
    Cisco 2900-01 (195.169.1.2 | qcpl-105-185.243.103.qcplnet.com)
    Cisco 2900-02 (199.168.4.3 | smb)

  7. Hello mike

    I have posted the modified script not posting. Can you please share me your email address so that we can email you and explain the whole scenario. Kind co-operation from you is highly appreciated. Expecting a positive reply from your side.

    Thankyou

  8. Hello Mike,

    kindly find below modification in your script as per our requirement, all the below mention IP are dump IPs of Internet Service Provider & MPLS service providers for our Organisation.We are trying to achieve to get email alerts in case of any failure in any of the services. When we run the script with the changes we are not getting any output inspite of the services are down. We have tried running your default script and it did generated an alert but the alerts were divided in to 3 section of WAN , Firewall, Switch. I have attached the Alert for your reference.

    Modified Script
    #==================================================================================================================
    #title :Ping_Test_Script.ps1 (rename from .txt to .ps1)
    #description :Monitor network devices using Powershell and Windows Task Scheduler.
    #author :Mike Page (www.builtbymike.ca)
    #date :20160216
    #version :0.9
    #usage :Powershell> ./Ping_Test_Script.ps1 (or Windows Task Scheduler)
    #notes :See http://www.builtbymike.ca for more information and more in depth description.
    #disclaimer :This script needs a lot of work to look nice, but functions fine. Further updates to come.
    #==================================================================================================================

    # Set e-mail properties
    $smtpServer = “192.178.14.40”;
    $smtpFrom = “ithelpdesk@testlab.com”;
    $smtpTo = “sachinb@testlab.com”;

    # Create an Array to store the destination hosts to ping
    [Array] $PingHosts = “10.10.1.178”, “172.30.5.14”, “172.4.1.10”, “173.54.206.88”, “115.192.5.134”, “109.48.40.88”, “168.25.233.130”, “198.34.81.190”, “172.34.80.242”, “172.33.80.74”, “172.39.6.70”, “172.80.106.6”
    $HostsTitles = @((“10.10.1.178”, “HO Airtel ILL”), (“172.30.5.14”, “HO RIL ILL”), (“172.4.1.10”, “Daman ILL”), (“173.54.206.88”, “Chennai ILL”), (“115.192.5.134”, “Turbe ILL”), (“109.48.40.88”, “Rorkee ILL”), (“168.25.233.130”, “Jesons.net”), (“198.34.81.190”, “HO Mpls”), (“172.34.80.242”, “Daman Mpls”), (“172.33.80.74”, “Rorkee Mpls”), (“172.39.6.70”, “ChennaiFac Mpls”), (“172.80.106.6”, “ChennaiOff Mpls”) )

    # Initialize body (This is the very top section header)
    $body = “WAN“;

    # Create counter
    $counter = 0;

    #Error counter
    $passerrorcounter = 0;
    $errorcounter = 0;

    # Error variables
    $PingFailure = “false”;
    $NewPingFailure = “false”;

    # Fixed variable
    $PingFixed = “false”;

    # Start subject
    $subject = “”;
    $Fixedsubject = “”;

    # Run Get-WmiObject using the Win32_PingStatus class against every host in the Array
    $WmiPingStatus = {Get-WmiObject -Class Win32_PingStatus -Filter (“Address=’” + $_ + “‘”) -ComputerName .}
    $PingHosts | ForEach-Object -Process $WmiPingStatus | Select-Object -Property Address,StatusCode |
    foreach {
    #These are the various section headings for what is being ping checked.
    #Add more -Or $HostsTitles[$counter][1] -match “Switch ” for the various section headings you would like to use.
    If ($HostsTitles[$counter][1] -match “HO Airtel ILL ” -Or $HostsTitles[$counter][1] -match “HO RIL ILL ” -Or $HostsTitles[$counter][1] -match “Daman ILL ” -Or $HostsTitles[$counter][1] -match “Chennai ILL ” -Or $HostsTitles[$counter][1] -match “Turbe ILL ” -Or $HostsTitles[$counter][1] -match “Rorkee ILL ” -Or $HostsTitles[$counter][1] -match “Jesons.net ” -Or $HostsTitles[$counter][1] -match “HO Mpls ” -Or $HostsTitles[$counter][1] -match “Daman Mpls ” -Or $HostsTitles[$counter][1] -match “Rorkee Mpls ” -Or $HostsTitles[$counter][1] -match “ChennaiFac Mpls ” -Or $HostsTitles[$counter][1] -match “ChennaiOff Mpls “)
    {
    $body = $body + “” + $HostsTitles[$counter][1] + ““;}{$body + “” + $HostsTitles[$counter][1] + ““;
    }
    else//
    {

    # Get hostname
    $hostname = [System.Net.Dns]::GetHostbyAddress($_.Address)
    $tempHostName = $hostname.HostName.ToLower()

    # Create failure tracking path for this device
    $path = “c:\Scripts\Failure_tracking\” + $tempHostName.Replace(“.yourdomain.local”,””) + “.txt”;

    # If StatusCode is equal to 0 then do nothing (since 0 = success)
    If ($_.StatusCode -eq 0)
    {

    # Check to see if there is a failure file for this, if so then it has now come back online, highlight accordingly
    if (Test-Path $path)
    {

    # See how long device was down for
    $str = Get-Content $path;
    $i = [System.Decimal]::Parse($str);
    $i=$i*5;

    # There was previously a failure but now online. Mark green to show this in the e-mail.
    $body = $body + “” + $HostsTitles[$counter][1] + ” (” + $_.Address + ” | ” + $tempHostName.Replace(“.yourdomain.local”,””) + ” | ” + $i + ” minutes)”

    # Since there is no longer a failure, delete the tracking file
    Remove-Item $path;

    # Set variable so that we know something is fixed
    $PingFixed = “true”;

    if ($passerrorcounter -eq 0)
    {
    $Fixedsubject = $Fixedsubject + $tempHostName.Replace(“.yourdomain.local”,””);
    }
    else
    {
    $Fixedsubject = $Fixedsubject + “, ” + $tempHostName.Replace(“.yourdomain.local”,””);
    }

    $passerrorcounter = 1;

    }
    else
    {
    # There was no previous failure
    $body = $body + $HostsTitles[$counter][1] + ” (” + $_.Address + ” | ” + $tempHostName.Replace(“.yourdomain.local”,””) + “)”
    }

    }
    # Else, if StatusCode is NOT equal to 0 then do something
    Else
    {
    # Set e-mail subject and body using details of non-responsive host

    if(Test-Connection -computer $_.Address -quiet)
    {
    $PingWarning = “true”;

    if (Test-Path $path)
    {
    # See how long device was down for
    $str = Get-Content $path;
    $i = [System.Decimal]::Parse($str);
    $i=$i*5;

    # There was previously a failure
    $body = $body + “” + $HostsTitles[$counter][1] + ” (” + $_.Address + ” | ” + $tempHostName.Replace(“.yourdomain.local”,””) + ” | ” + $i + ” minutes)”

    # Since there is no longer a failure, delete the file
    Remove-Item $path;

    # Set variable so that we know something is fixed
    $PingFixed = “true”;

    if ($passerrorcounter -eq 0)
    {
    $Fixedsubject = $Fixedsubject + $tempHostName.Replace(“.yourdomain.local”,””);
    }
    else
    {
    $Fixedsubject = $Fixedsubject + “, ” + $tempHostName.Replace(“.yourdomain.local”,””);
    }

    $passerrorcounter = 1;
    }
    else
    {
    # There was NOT previously a failure
    $body = $body + “” + $HostsTitles[$counter][1] + ” (” + $_.Address + ” | ” + $tempHostName.Replace(“.yourdomain.local”,””) + “)”

    }

    }
    else
    {

    # Check to see if there is a failure file for this, failure is continuing so increment it
    if (Test-Path $path)
    {

    # See how long device was down for
    $str = Get-Content $path;
    $i = [System.Decimal]::Parse($str);
    $i=$i*5;

    # There was previously a failure
    $OldPingFailure = “true”;
    $body = $body + “” + $HostsTitles[$counter][1] + ” (” + $_.Address + ” | ” + $tempHostName.Replace(“.yourdomain.local”,””) + ” | ” + $i + ” minutes)”

    # Increase failure file integer
    $str = Get-Content $path;
    $i = [System.Decimal]::Parse($str)
    $i++
    Set-Content $path $i

    }
    else
    {
    # There was no previous failure, this is a new failure. Must mark for e-mail to be sent.
    $NewPingFailure = “true”;
    $body = $body + “” + $HostsTitles[$counter][1] + ” (” + $_.Address + ” | ” + $tempHostName.Replace(“.yourdomain.local”,””) + ” | 0 to 5 minutes)”

    # Create a failure file
    $text = ‘1’;
    $text | Out-File $path;
    $text > $path;
    }

    }

    if ($errorcounter -eq 0)
    {
    $subject = $subject + $tempHostName.Replace(“.yourdomain.local”,””);
    }
    else
    {
    $subject = $subject + “, ” + $tempHostName.Replace(“.yourdomain.local”,””);
    }

    $errorcounter = 1;
    }
    }
    $counter = $counter+1;
    }

    # Set e-mail objects and send e-mail
    If($NewPingFailure -match “true” -Or $OldPingFailure -match “true”)
    {
    If($NewPingFailure -match “true”)
    {
    #New device failure. Send notification e-mail.

    $subject = “Ping Test Failure: ” + $subject;
    $smtpClient = New-Object Net.Mail.SmtpClient($smtpServer, 25);
    $emailFrom = New-Object Net.Mail.MailAddress $smtpFrom, $smtpFrom;
    $emailTo = New-Object Net.Mail.MailAddress $smtpTo, $smtpTo;
    $mailMsg = New-Object Net.Mail.MailMessage($emailFrom, $emailTo, $subject, $body);
    $mailMsg.IsBodyHTML = $true
    $smtpClient.Send($mailMsg)
    }
    else
    {
    #Getting to this point means that there isn’t a new failure. There still could be a previous device that has been down.
    #The ‘Warning’ signifies that a device didn’t respond to at least one of its pings. The ping test sends three or four
    #pings to each device. This does happen on occasion but I write it off as network congestion.

    #$subject = “Ping Test Warning: ” + $subject;

    #$smtpClient = New-Object Net.Mail.SmtpClient($smtpServer, 25);
    #$emailFrom = New-Object Net.Mail.MailAddress $smtpFrom, $smtpFrom;
    #$emailTo = New-Object Net.Mail.MailAddress $smtpTo, $smtpTo;
    #$mailMsg = New-Object Net.Mail.MailMessage($emailFrom, $emailTo, $subject, $body);
    #$mailMsg.IsBodyHTML = $true
    #$smtpClient.Send($mailMsg)
    }

    }
    else
    {
    if($PingFixed -match “true”)
    {
    #A device that was down is now up. Send an e-mail to notify.

    $subject = “Ping Test Pass (Fixed): ” + $Fixedsubject;

    $smtpClient = New-Object Net.Mail.SmtpClient($smtpServer, 25);
    $emailFrom = New-Object Net.Mail.MailAddress $smtpFrom, $smtpFrom;
    $emailTo = New-Object Net.Mail.MailAddress $smtpTo, $smtpTo;
    $mailMsg = New-Object Net.Mail.MailMessage($emailFrom, $emailTo, $subject, $body);
    $mailMsg.IsBodyHTML = $true
    $smtpClient.Send($mailMsg)
    }
    else
    {
    #I didn’t want to receive pass e-mails so this section is commented out.
    #These e-mails denote success.

    #$subject = “Ping Test Pass”;

    #$smtpClient = New-Object Net.Mail.SmtpClient($smtpServer, 25);
    #$emailFrom = New-Object Net.Mail.MailAddress $smtpFrom, $smtpFrom;
    #$emailTo = New-Object Net.Mail.MailAddress $smtpTo, $smtpTo;
    #$mailMsg = New-Object Net.Mail.MailMessage($emailFrom, $emailTo, $subject, $body);
    #$mailMsg.IsBodyHTML = $true
    #$smtpClient.Send($mailMsg)
    }
    # There are no failures.
    # Double check to make sure failure folder is emptied.
    Remove-Item c:\Scripts\Failure_tracking\*
    }

    Exit

    Email Alert Received.

    WAN
    DSL (10.243.185.105 | qcpl-105-185.243.103.qcplnet.com)
    HSA (16.53.206.68 | qcpl-105-185.243.103.qcplnet.com | 0 to 5 minutes)

    Firewall
    Firewall
    Fortigate (198.167.1.1 | qcpl-105-185.243.103.qcplnet.com | 5 minutes)

    Switch
    Switch
    Cisco 2900-01 (195.169.1.2 | qcpl-105-185.243.103.qcplnet.com)
    Cisco 2900-02 (199.168.4.3 | smb)

  9. One thing that I’m noticing (on my end at least) is that there seems to be some errors because the reverse lookup of those IP addresses doesn’t return anything. I’m not sure that by itself would be causing issues. Please e-mail me at mikepage@builtbymike.ca with your latest script and I will try running it. It does look like you have at least gotten some results in the e-mail alert.

    Thanks

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.