PowerShell

Find out whether a host is really down with Test-ConnectionLocalSubnet (ping,arp)

Is Ping a reliable way to check if a computer is available? Opinions differ … This blog post is all about ping and arp. Of course with PowerShell. The upcoming script could help you figure out whether a host is really up or not. Remember the Windows Firewall. If ping is not successful what does this actually mean? That the host is down? Not really … Let’s dive in …

Introduction

There are many ways to perform a ping. There is superping, the “normal” ping, other pings 😉 and finally the PowerShell cmdlets Test-Connection and Test-NetConnection. All of the above can only tell you whether ping is successful or not. But they don’t tell you whether the host is up or not.

Unbenannt.PNG

The Goal

Last week I had an idea. Some of my ideas are dangerous for me because I know that putting them into practice will bring me a lot of work – but also joy. And this idea is definitely a dangerous one ;-).  I had the idea to create a function which can tell me the reason why a ping is successful or not. So, ARP hast to come into play.

Only if a ping failed but the corresponding ARP request was successful, it’s pretty sure that the target host is up! Provided that both are in the same subnet.

Back to my idea: Why not create a function that shows me that behavior? Here it is:

Host is up (ICMP and ARP successful)

Unbenannt.PNG

Firewall is probably blocking Traffic (ARP successful, but ICMP failed)

Unbenannt.PNG

Host is outside the subnet (ICMP successful, ARP not successful)

It’s possible to ping hosts outside your subnet. That means, that ICMP is successful and ARP is not successful, because the source host will send the ICMP Echo Request to it’s Default Gateway. I do a ping to the IP-Address of cnn.com which is definitely not in my subnet.

Unbenannt.PNG

Host is down (ICMP, ARP failure)

Unbenannt.PNG

Oh, before I forget: Here’s the function. 😉

Function Test-ConnectionLocalSubnet

If you like it copy the Code in your PowerShell ISE session.

function Test-ConnectionLocalSubnet {
param ([Parameter(Mandatory=$True,Position=1)]
[System.Net.IPAddress]$IPAddress)
arp -d
$entry= Write-Host "Testing $IPAddress ..."
$line="_____________________________________________________________"
$ping=Test-Connection -ComputerName $IPAddress -Count 3 -Quiet
$arp=[boolean](arp -a | Select-String "$IPAddress")
If ($ping -and $arp)
{$line; Write-Host "ICMP: successful" -ForegroundColor Green`n; Write-Host "ARP : successful" -ForegroundColor Green`n; $line; Write-Host "Host ${IPAddress} is up" -ForegroundColor Green; Write-Host ""}
elseif ($ping -and !$arp)
{$line; Write-Host "ICMP: successful" -ForegroundColor Green`n; Write-Host "ARP : failure" -ForegroundColor Red`n; $line; Write-Host "Host ${IPAddress} is up, but possibly not on local subnet"; Write-Host ""}
elseif (!$ping -and $arp)
{$line; Write-Host "ICMP: failure" -ForegroundColor Red`n; Write-Host "ARP : successful" -ForegroundColor Green`n; $line; Write-Host "Possible Cause on ${IPAddress}: Windows Firewall is blocking traffic"; Write-Host ""}
else
{$line; Write-Host "ICMP: failure" -ForegroundColor Red`n; Write-Host "ARP : failure" -ForegroundColor Red`n; $line; Write-Host "Host ${IPAddress} is down" -ForegroundColor Red; Write-Host ""
}
}

Notes:

  • This was tested on PowerShell 5.1
  • You can only use IP-Addresses (Parameter: IPAddress), no host names
  • This script is intended for testing reachability of hosts on the local subnet, but also hosts outside the own subnet can be tested

Make it permanent

Create a folder in C:\Program Files\Windows PowerShell\Modules. Name the folder Test-ConnectionLocalSubnet. Save the script there as psm1 file. Make sure the directory name and the file name are equal.

Unbenannt.PNG

Close Windows PowerShell. Open PowerShell again. The command is now available for all users.

Unbenannt.PNG

More about Powershell Moduls here: PowerShell Functions: How to create your first PowerShell Module Command

Have fun with Test-ConnectionLocalSubnet!

7 replies »

  1. Patrick if you don’t mind I added to your script something very important, RDP test, of course this is only working from Powershell 4.0 and beyond, w8 ,w2012. thanks for sharing.

    #iptest for icmp,arp, and rdp protocols
    function Test-ConnectionLocalSubnet {
    param ([Parameter(Mandatory=$True,Position=1)]
    [System.Net.IPAddress]$IPAddress)
    $entry= Write-Host “Testing $IPAddress …”
    $line=”_____________________________________________________________”
    $ping=Test-Connection -ComputerName $IPAddress -Count 3 -Quiet
    $rdp=test-netconnection -computername $ipaddress -CommonTCPPort rdp
    $arp=[boolean](arp -a | Select-String “$IPAddress”)
    #waiting sucess in all three protocols
    If ($ping -and $arp -and $rdp)
    {$line; Write-Host “ICMP: successful” -ForegroundColor Green`n; Write-Host “ARP : successful” -ForegroundColor Green`n; Write-Host “RDP: successful” -ForegroundColor Green`n;$line; Write-Host “Host ${IPAddress} is up” -ForegroundColor Green; Write-Host “”}
    #waiting only icmp success and complement with RDP
    elseif ($ping -and !$arp )
    {$line;write-host “testing also RDP connection”
    $rdp=test-netconnection -computername $IPAddress -CommonTCPPort rdp
    if ($rdp) {write-host “rdp working and enabled” -ForegroundColor green}
    Write-Host “ICMP: successful” -ForegroundColor Green`n; Write-Host “ARP : failure” -ForegroundColor Red`n; Write-Host “RDP : failure” -ForegroundColor Red`n;$line; Write-Host “Host ${IPAddress} is up, but possibly not on local subnet”; Write-Host “”}
    #waiting only arp and complement with RDP
    elseif (!$ping -and $arp)
    {$line;write-host “testing also RDP connection”
    $rdp=test-netconnection -computername $IPAddress -CommonTCPPort rdp
    if ($rdp) {write-host “rdp working and enabled” -ForegroundColor green}
    $line; Write-Host “ICMP: failure” -ForegroundColor Red`n; Write-Host “ARP : successful” -ForegroundColor Green`n; $line; Write-Host “Possible Cause on ${IPAddress}: Firewall is blocking traffic”; Write-Host “”}
    #Waiting failure on icmp and arp but still trying rdp
    elseif (!$ping -and !$arp -and $rdp)
    {$line;write-host “testing also RDP connection”
    $rdp=test-netconnection -computername $IPAddress -CommonTCPPort rdp
    if ($rdp) {write-host “rdp working and enabled” -ForegroundColor green}
    $line; Write-Host “ICMP: failure” -ForegroundColor Red`n; Write-Host “ARP : failure” -ForegroundColor red`n; $line; Write-Host “remote connection to ${IPAddress}: is possible , other ports are closed for ${IPAddress}: on Firewall and blocking traffic”; Write-Host “”}
    #complete failure
    else
    {$line; Write-Host “ICMP: failure” -ForegroundColor Red`n; Write-Host “ARP : failure” -ForegroundColor Red`n; Write-Host “RDP : failure” -ForegroundColor Red`n; $line; Write-Host “Host ${IPAddress} is down” -ForegroundColor Red; Write-Host “”}
    }

    Liked by 1 person

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

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