Test-Connection

I run this script and I want it to tell me the name of the failed ping. Where “$computer is offline” is, I want it to show “pc2 is offline” or whatever pc fails the ping basically. Any ideas?

$csv = Get-Content pclist.csv

foreach ($computer in $csv)
{

try
{
Test-Connection $computer -Count 1 -ErrorAction Stop | Select-Object Address, IPV4Address
}
catch [System.Net.NetworkInformation.PingException]
{
‘$computer is offline.’
}
}
pause

I’ll end with a report that looks like this

Address IPV4Address


pc0 192.168.1.1
pc1 192.168.1.2
$computer is offline.

‘comp1’,‘comp2’ | % {[pscustomobject]@{online = [bool](test-connection $_ -Count 1 -quiet);computername = $_}}

I apologize, I am very new to powershell, is this line replacing something or where specifically am i placing it?

Pinging computers is every beginners favorite thing to do:-) I suggest browsing the the technet script repository here.

https://gallery.technet.microsoft.com/scriptcenter

Thanks! I will look into it. Appreciate the responses. I will see what I can do.

foreach($computer in $computers){

$test = test-connection $computer -Count 1  -ea 'silentlycontinue'

[pscustomobject]@{

status = if($test){'online'}else{'offline'}
ipv4 = $test.ipv4address.ipaddresstostring
name = $computer

}

}

'$computer is offline.'

This would not work if you want variable expansion. You would need to use double quotes for that.

Here’s another example of a one liner…

Get-Content pclist.csv | Foreach-Object { If (Test-Connection -ComputerName $_ -Quiet -Count 1) { Write-Host "$_ is online" -ForegroundColor Green } Else { Write-Host "$_ failed ping" -ForegroundColor Red" } }

You just killed four puppies:-)

Why would you have me do such a thing? lol

Ahhh, Thanks! That was my issue. lol

To make life easier with Dan’s excellent piece of code you can wrap a small function around it:

function test-ping {
    
    $args | % {[pscustomobject]@{online = [bool](test-connection $_ -Count 1 -quiet);computername = $_}}
}

Then you can just type

Test-ping Device1 Device2

“Test-Connection -ComputerName SERVER -Quite” returns a System.Boolean Type,
basically a “True” or “False”

You could use it like;

$Import = Get-Content -Path C:\ServerList.txt

foreach ($a in $Import) {
    if (Test-Connection -ComputerName $a -Count 2 -Quite) { 
            Write-Host "Ping Succeeded" 
            } Else {
              Write-Host "Ping Failed"
            }
}

Yes Nigel you are quite right, no requirement for the [bool] type.

So as a short function :

function test-ping { $args | % {[pscustomobject]@{online = test-connection $_ -Count 1 -quiet;computername = $_}} }

#run
Test-ping Device1 Device2

I really like the output and speed of Grahams edit of Nigel’s script! I wish it could show ipv4 and servicetag info as well. How would I pipe these into the script? Without the need for the txt/csv. Also I noticed it truncates the list of my ipv4 addresses with my original script which was annoying not to see the last octet of the contacted host. The last script listed seems to have a different list view output.

$a = Get-Content “C:\Powershell\Computers.txt”

foreach ($i in $a)
{$i + “`n” + “==========================”; Get-WmiObject win32_SystemEnclosure -computername $i | select serialnumber}

Hi Brad,

This is a bit more code but should do what you require :

function test-ping {
    param([Object[]]$Devices)        
    
            foreach ($Device in $Devices) {

                if (test-connection $Device -Count 1 -quiet) {
    
                    [pscustomobject]@{

                    computername = $Device 
                    online       = "True"
                    IPaddress    = (test-connection $Device -Count 1).IPV4Address.IPAddressToString
                    serialnumber = (Get-WmiObject -ComputerName $device win32_SystemEnclosure).serialnumber
                    }

                } else {
                    
                    [pscustomobject]@{

                    computername = $Device 
                    online       = "false"
                    IPaddress    = " `t- "
                    serialnumber = " `t-"
                    }
                }
        }
}

let me know.

I got it to work by calling the CSV and pointing the foreach to it. The only issues I have are the truncating of the tables and after about 15 down the list is stalls and never moves to the next computer. I don’t see where I would specify the Devices to test-ping on without calling the csv though. Thanks Graham!

Output example

computername online IPaddress serialnumber


Device1 Online 10.10.0.2 None
Device2 Online 10.10.0.3 None
Device3 Online 192.16… 30254V1
Device4 Off… - -
Device5 Online 10.10.0.4 None

Actually after hanging a while it threw this and didn’t display the serial and loaded most of the rest of the list fine. So that’s the issue. May be worthy to note that the errors are only thrown in windows 7 workstations and none of the Servers had the error.

Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)
At C:\Users\user\Desktop\ps\New Text Document (2).ps1:15 char:37

  • … alnumber = (Get-WmiObject -ComputerName $device win32_SystemEnclosure …
  •             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : InvalidOperation: (:slight_smile: [Get-WmiObject], COMException
    • FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

Hi Brad,

So i’ve amended the code to look at WMI class Win32_Bios for the serial number instead of, win32_SystemEnclosure. Win32_Bios might be more generic for you:

function test-ping {
    param([Object[]]$Devices)        
    
            foreach ($Device in $Devices) {

                if (test-connection $Device -Count 1 -quiet) {
    
                    [pscustomobject]@{

                    computername = $Device 
                    online       = "True"
                    IPaddress    = (test-connection $Device -Count 1).IPV4Address.IPAddressToString
                    serialnumber = (Get-WmiObject -ComputerName $device win32_bios).SerialNumber
                    }

                } else {
                    
                    [pscustomobject]@{

                    computername = $Device 
                    online       = "false"
                    IPaddress    = " `t- "
                    serialnumber = " `t-"
                    }
                }
        }
}

Do you have a list of PC’s in a txt or csv file ?

If you have them in a file, you can use whats called a subexpression, $().

So your’s would look like this:

test-ping $(get-content c:\temp\PCs.csv) 

Or if you just want to pass a couple to test-ping:

test-ping PC1, PC2, PC3

Does that help ?