Ad Space here

Direct Link: 9/27/2019Destination Host Unreachable


A really neat thing about working in a new environment is learning details that you just didn't know before.  I often get asked why I don't use Test-Connection from PowerShell to see if a machine is online.   I always used ping from PowerShell because I was confident in the return codes, etc.  For example:

Code:
## CHECK PING STATUS - RETURN IF OFFLINE
$pingStatus = ping -n 1 -4 $computer
if ($?) {
     $Obj.Online = $true
} else {
     $Obj.Online = $false
     return $Obj
}

What I learned today is that ping returns an exit code of 0 if the machine is on your local subnet.


Reply from xxx.xxx.x.xx Destination host unreachable. 

I had to change my code to this:

Code:
    ## CHECK PING STATUS - RETURN IF OFFLINE
    $pingStatus = ping -n 1 -4 $computer
    if ($?) {
        if ($pingStatus -match "unreachable" -or $pingStatus -match "could not find host" -or $pingStatus -match "timed out") {
            $Obj.Online = $false
            return $Obj
        } else {
            $Obj.Online = $true
        }
    } else {
        $Obj.Online = $false
        return $Obj
    }

Test-Connection for the same machine comes back with a cryptic error:

Code:
Test-Connection : Testing connection to computer 'PC-Name' failed: A non-recoverable error occurred during a
database lookup
At line:1 char:1
+ Test-Connection -ComputerName PC-Name -Count 1
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ResourceUnavailable: (PC-Name:String) [Test-Connection], PingException
    + FullyQualifiedErrorId : TestConnectionException,Microsoft.PowerShell.Commands.TestConnectionCommand

I guess the Test-Connection could be wrapped in a try/catch or -ErrorAction SilentlyContinue.  I generally just don't like hiding errors.

The main point is: 

The beauty of System Administration and PowerShell is that there are multiple ways to get to the same answer.  Pick one, learn it inside and out, and be confident.

-Dustin

First two comments:


Mike Merola

I too have run into the "Destination host unreachable" or "Destination net unreachable" replies to ping that triggered false positives in scripts. I still use Ping, but now I test its output for the word "unreachable" and have over time condensed my check down into just a few lines.

First, I ping the computer and store the results to a variable, including and StdErr output

Code:
$ThePingItself = ping -n 1 -4 $Computer 2>&1


Then save off the current value of whether the last command finished successfully

Code:
$PingResult = $?


Now my thought process here is that the target computer is online if 2 conditions are met:

  1. the ping command returned successfully
  2. the ping command didn't return a false positive in the event of a "Reply from x.x.x.x: Destination host/net unreachable"

"could not find host" and "timed out" do not trigger Ping false positives

So I am essentially looking for (Condition1 -and Condition2) where condition1 and condition2 evaluate to True/False

Condition1 is straightforward, it's just $PingResult

Condition2 is taking the output of the ping command and looking for the word "unreachable", but finding that is actually a FALSE scenario, so we flip the result. 

Code:
(!($ThePingItself -match "unreachable"))


Searching for ($ThePingItself -notmatch "unreachable") will always return true because there are other characters and words always in the output, which is why we have to explicitly look for it and flip the result.

Now I put it all together into one logical statement

Code:
$IsOnline = ($PingResult -and (!($ThePingItself -match "unreachable")))


The whole code all put together is just 3 lines:

Code:
$ThePingItself = ping -n 1 -4 $Computer 2>&1
$PingResult = $?

$IsOnline = ($PingResult -and (!($ThePingItself -match "unreachable")))


The logical operators evaluate the individual components and if both conditions are true, the $IsOnline is TRUE, otherwise it is false.

Like you said, Dustin, there are so many ways to get to the same results, the diversity in solutions and thought processes is truly fascinating and the blending together of different schools of thought leads to some wild results. This is why we will never stop learning :)

--Mike



jimmer2880

If it's a win box, I like test-secureconnection.  It basically ensures the machine is able to open an secure session.  I use this as a quick test if the computer is healthy in AD and on the network.  If that fails, then I do other tests, including the traceroute option.



Available Blog posts:






If you like this site, help us out.
Spread the word and share it with others!