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.



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?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Qlemo"Batchelor", 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.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
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...
Qlemo"Batchelor", 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.
Redefine Your Security with AI & Machine Learning

The implications of AI and machine learning in cyber security are massive and constantly growing, creating both efficiencies and new challenges across the board. Check out our on-demand webinar to learn more about how AI can help your organization!

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)
Qlemo"Batchelor", 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.
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....
Qlemo"Batchelor", Developer and EE Topic AdvisorCommented:
You are correct, in the "up" case it should be -contains.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.