Powershell Script to ping few hundred host and send e-mail notfication

Hi, I have a requirement to check few hundred hosts in multiple offices and report the hosts not in network to local site admins.

I have gone through following links and both of them are very close to my requirement.

http://blogs.msdn.com/b/rslaten/archive/2013/07/30/pinging-a-list-of-machines-in-powershell.aspx

http://www.experts-exchange.com/Programming/Languages/Scripting/Powershell/Q_28608907.html


Actually in our case the hostnames input file will be a CSV file the two columns. One obviously the host name and other will be host physical location number (desk number sort of), So whenever the host is down this script should send a e-mail to local admins DL with the hostname and physical location number. By looking at the physical location number, respective site admin can go and check that specific host. We would like to run this script every 15 minutes. Obviously we would like to have only one message for the host down, not every 15 minutes for the same host, We also need host up message once the  host is backup.

Appreciate your help...
Raj TAsked:
Who is Participating?
 
QlemoBatchelor, Developer and EE Topic AdvisorCommented:
I've switched to using Send-MailMessage, because that is the preferred method now. Aside from that, the script logic is unchanged.
The CSV is assumed to have "HostName" and "Location" as column names, but you can change that to your needs, of course. Just make sure to change the code accordingly.
$DownServerFile = "C:\DownServers.txt"
$FullServerFile = "C:\ServerList.csv"

# Create empty arrays for offline server lists
$PreviousDownServers = @()
$CurrentDownServers  = @()

If (Test-Path -Path $DownServerFile) { $PreviousDownServers = Get-Content C:\DownServers.txt }

$MailProp = @{
  SmtpServer = "smtp.domain.com"
  From       = "email@domain.com"
  To         = "recipient@domain.com"
}

Import-Csv $FullServerFile | ForEach {
  $Server   = $_.HostName
  $Location = $_.Location
  $date     = Get-Date -Format MM-dd-yyy-HH::mm

  if (test-Connection $Server -Count 2 -Quiet ) {
    write-Host "$Server is alive and Pinging " -ForegroundColor Green

    #Send email if this server was down previously, but is now up
    if ($PreviousDownServers -notcontains $Server) {
      Send-MailMessage @MailProp -Subject "$server at $location - Ping Monitor success - $date " `
                       -Body "$Server is now responding to ping."
    }
  } else {
    $CurrentDownServers += $Server
    #Send email only if this is the first time the server is down
    if ($PreviousDownServers -notcontains $Server) {
      Send-MailMessage @MailProp -Subject "$server at $location - Ping Monitor failure - $date " `
                       -Body "$Server is not responding to ping."
    }
  }      
}
$CurrentDownServers | Out-File $DownServerFile

Open in new window

Be aware that because the script will always wait at least one second per machine, going thru all machines will last some time. Also, you won't have the down server file updated until the script has been completed.
0
 
Raj TAuthor Commented:
Thanks for your quick response Qlemo. Is there any way we can make this script work faster....I think the below script finds the machine status faster than test-connection....

We might have 8K machines and we would like to check this every 15-30 minutes...
0
 
QlemoBatchelor, Developer and EE Topic AdvisorCommented:
Your new script suggestion is missing.

You can speed up the script in many ways. One is to use an instant, single ping by setting the count of Test-Connection to 1. That will not wait at all if it is successful, but also increase the chance of errornous "down" detection if the machines are on heavy load. That is what I would try first, and measure how long it takes to go thru a subset of machines.

Another way is to use multiple threads (PS jobs), which run at the same time. However, management can get complex.

The best option always is to have each machine actively reporting it is still alive. E.g appending an hostname entry to a file getting removed with each monitor script go. This is, you have one batch on each machine running every 15 minutes, and one batch on a server checking the written file.
0
On-Demand: Securing Your Wi-Fi for Summer Travel

Traveling this summer?Check out our on-demand webinar to learn about the importance of Wi-Fi security and 3 easy measures you can start taking immediately to protect your private data while using public Wi-Fi. Follow us today to learn more!

 
Raj TAuthor Commented:
Thanks Qlemo. I would like to keep Test-Connection 2 for accuracy. May be I can run site specific threads and keep separate files for sites.

We don't want touch anything on the local machine. Hence placing a batch file in a PC might not work well for us.

I have a query though on the current script. In the below line it should be "notcntains" or "contains" ...If it is already there in the downfile and the server is up now then we are sending a message saying it is up now. Please clarify

if ($PreviousDownServers -notcontains $Server)
0
 
QlemoBatchelor, Developer and EE Topic AdvisorCommented:
The server is down when ariving at that condition. The condition now checks if it has been down previously, and only if not sends the mail.

In regard of client machine scripts, you usually run or install that per GPO, so no big issue.
Building smaller blocks of machines to monitor is a good idea and simple approach.
0
 
Raj TAuthor Commented:
Actually If I keep-notcontains it sends mails out for all the servers....When I change it to contains no mails are coming out...I need to test this further....
0
 
QlemoBatchelor, Developer and EE Topic AdvisorCommented:
You are correct, in the "up" case it should be -contains.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.