Ping vs Test-Connection

Hi, I read the Microsoft explanation of Test-Connection, but something still seems off. I have 50 or so IP machines that I have to check weekly if they are on-line. I made a simple code with a sequence of ifs that generally works, but it seems there is a problem.

$ok = 1

If (-Not (Test-Connection 10.0.10.11 -Count 1 -ErrorAction SilentlyContinue))
{
Write-Output "Machine 1 NOK"
$ok = 0

If (-Not (Test-Connection 10.0.10.12 -Count 1 -ErrorAction SilentlyContinue))
{
Write-Output "Machine 2 NOK"
$ok = 0
} 
...

If ($ok -eq 1) 
{
Write-Output "Everything ok"
}


The idea is if an IP doesn’t respond to test-connection it sets my OK variable to 0 and prints wich ones are off, if the variable is still 1 at the end it prints that everything is ok.

Last friday a machine was offline, it got fixed, so they asked me to check, in the 5 minutes later or so if i tried to ping the machine via regular ping I got the response correctly, but my script still said the machine was not OK. Later my script worked well and it said OK, but why there is this delay? If ping is responding shouldn’t test-connection respond as well?

Ty in advance for your time

I suggest you look at the properties of the object that comes out of Test-Connection. That command does not return true/false, but an object with a Status property. Looking at that property is a better way to verify if the test succeeded or not.

If ((Test-Connection 1.2.3.4).Status -ne 'Success')

Some other thoughts on code improvement. I’d make $ok = $true/$false instead of 0/1. I’d also try to put your IP addresses in an array and loop through them to reduce the amount of code.

Thank you for the reply, I tried doing as you suggested, but didn’t quite work.
I didn’t make an array because I don’t mind for it being a bit slow, as long as it executes under a minute it is fine, and by doing the Ifs separately I can better decide the output.

I implemented this in the first line as try (as well as using the $true/$false you suggested):

If ((Test-Connection 10.0.10.11 -Count 1 -ErrorAction SilentlyContinue).Status -ne 'Success')
{
Write-Output "SMachine 1 NOK"
$ok = $false
} 

Even tho the machine is online (and with my initial version it recognized that) now it says NOK

Any idea why?

What is the output of the command?

Test-Connection 10.0.10.11 -Count 1 -ErrorAction SilentlyContinue

It should look something like this:

C:\> test-connection localhost -count 1

   Destination: localhost

Ping Source           Address                   Latency BufferSize Status
                                                   (ms)        (B)
---- ------           -------                   ------- ---------- ------
   1 MYPC             ::1                             0         32 Success

Looking at the output of the command should help you determine why the “if” is not giving you the expected results.

I did notice that for PowerShell 5.1, there is no “Status” property.

I use something like this:

if($null = Test-Connection -ComputerName $System -Count 4 -Quiet -BufferSize 16){Write-Output 'Connection Good'}

I do a similar thing with -count 1. However if that fails I do -count 4. That sometimes picks up machines online that it didnt pick up with -count 1.

1 Like

Sorry for not replying, I was busy in teh lat days, here is my output:

Source        Destination     IPV4Address      IPV6Address                              Bytes    Time(ms) 
------        -----------     -----------      -----------                              -----    -------- 
NBK10067      10.0.10.11                                                                32       9

Br

After a little more looking, Test-Connection has definitely changed between PS5 and PS7.
The object type in PS5 is “System.Management.ManagementObject#root\cimv2\Win32_PingStatus”
The object type in PS7 is “Microsoft.PowerShell.Commands.TestConnectionCommand+PingStatus”

If Test-Connection fails in PS5 it seems to throw an error. Not sure if that’s consistent across all use cases, but the few things I tried did throw errors when failing.
If Test-Connection fails in PS7 (for an IP address or resolvable hostname) it always returns an object with a status.

Is it possible for you to use PS7 for your connection testing? I find that, unless there’s a compelling reason to stay on PS5, it is always preferable to use PS7.

What I posted works fine in both PS5 and 7

FYI.

1 Like

Another method that I ended up using on something is the .NET Ping class. You can tune the TTL via the $Timeout and it can run against a lot of hosts pretty fast.
Here’s an example using your original concept:

$Computers = @(
    "10.0.10.10",
    "10.0.10.11",
    "10.0.10.12"
)


$Timeout = 3000
$Ping = New-Object System.Net.NetworkInformation.Ping

$Results = Foreach ($Computer in $Computers) {
    $Response = $Ping.Send($Computer,$Timeout)
    [PSCustomObject]@{
        TimeStamp = Get-Date
        Address = $Computer
        Status = $Response.Status
        RTT = $Response.RoundtripTime
    }
}
<# Here's examples of what the results would look like if you wanted to do anything with that info
TimeStamp            Address          Status RTT
---------            -------          ------ ---
9/26/2024 9:40:48 AM 10.0.10.10       Success  26
9/26/2024 9:40:48 AM 10.0.10.11       Success  36
9/26/2024 9:40:48 AM 10.0.10.12       Success  25
9/26/2024 9:40:48 AM 10.0.10.13       Success  18
9/26/2024 9:40:51 AM 10.0.10.14       TimedOut   0
#>


$OK = 1
Foreach ($Result in $Results) {
    If ($Result.Status -ne "Success") {
        Write-Output "$($Result.Address) NOK"
        $OK = 0
    }
}
If ($OK -eq 1) {
    Write-Output "Everything is OK"
}