PowerShell for Admins

To ping or not to ping..The PowerShell way

Graham Beer
5 min read
Share:

As this is my first blog here, here’s a bit about me. I’m a current lead SCCM Admin in the UK, and have found this great enjoyment for PowerShell in the last 18 months. I’ve started my own blog, http://www.get-configmgr-content.co.uk/, to share my passion. The chance to blog on Powershell.org was too exciting not to do!
The inspiration for this blog came from a forum post on Powershell.org that I helped contributed on. The question asked was, how to display the name of failed ping, i.e. $computer is offline.
There were some great responses, the one I most liked which I slightly amended into a function was:

function test-ping { $args | % {[pscustomobject]@{online = test-connection $_ -Count 1 -quiet;computername = $_}} } The simplicity and power is brilliant. (Credit to Dan Potter!)
I expanded on this and came up with a way to use the results in several different ways. All this by the power of advanced functions.
I have two advanced functions ‘ValueFromPipeline’ and ‘ValidateSet’ in this script:

  1. ‘ValueFromPipeline’ gives the capability to pass more than one object to our script. Perfect for passing one or many devices.
    Other than the message “Online: PC1”, I wanted to be able to use the ping status to pass to another cmdlet, collate all online or offline devices and display the results in a table.
  2. Using ‘ValidateSet’ I could define my options, “Online”,“Offline” and “ObjectTable”. But by not setting the parameter to mandatory, you don’t have to use the additional options.
    To continue using the ping response, I needed to hold them somewhere. I did this by creating an empty array in the Begin block and append each ping response to it.
    Regardless of what option I choose, if any, the below block of code will always run:

$device| foreach { if (Test-Connection $_ -Count 1 -Quiet) { if(-not($GetObject)){write-host -ForegroundColor green "Online: $_ "} $Hash = $Hash += @{Online="$_"} }else{ if(-not($GetObject)){write-host -ForegroundColor Red "Offline: $_ "} $Hash = $Hash += @{Offline="$_"} } } Devices in the variable, $device, will each be ‘pinged’ then passed through a ‘if’ statement depending on offline or online status and get added into the $hash array variable.
DISCLAIMER: I should apologies to Don here for killing the puppies with write-host. I wanted to just push out some colored output to the host only!
Before I go any further, let me briefly explain how I am ‘pinging’ the devices. I am using the cmdlet ‘Test-Connection’. The synopsis on ‘get-help’ for test-connection states, ‘Sends ICMP echo request packets (“pings”) to one or more computers.’ A nice feature of this cmdlet is the ‘-quiet’ syntax. This is cool as it gives a Boolean result (True or False) of the ‘ping’ status. By adding a ‘-count’ as well I can limit the number of times I request a connection check. Now I can pass as many devices through the pipeline to my function and get an online or offline message pretty quickly.
The second half of the script only runs if you add the ‘$getObject’ option from the function. The use of the ‘validateSet’ allows me to make sure the three options I defined are used only.
The data collected in the $hash array variable is passed through a foreach statement and creates customobjects. The final part is use of a ‘Switch’. Depending on what was chosen in the $getObject parameter is the output at the end of the script.
The advantage to this switch is I can pass all the online PC’s to something else via the pipeline. For example, an AD group or a deployment collection:

'PC1','PC2' | Get-PingStatus -GetObject Online | # pass to another cmdlet Capture the ‘online’ PC’s to a variable and use:

$Online = 'PC1','PC2' | Get-PingStatus -GetObject Online Or if you need to report back a list of PC’s which are either on or offline in an object group:

`‘PC1’,‘PC2’, ‘PC3’,‘PC4 | Get-PingStatus -GetObject objectTable DeviceName Online offline


pc4 Online pc1 Offline pc2 Offline pc3 Offline `Again this script has great flexibility in how you pass the device objects.
Say you have a list of PC’s in a txt for CSV file, you can use Get-content and pipe it to Get-PingStatus:

get-content pcs.csv | Get-PingStatus NOTE:
The use of the $Global: variable allowed me to use $Global:Objects once the script has complete. Just something I thought could be useful. The $Script: variable would have worked fine should I not want to use the variable outside the script.
I hope you’ve enjoyed my blog and I welcome any comments. I’ve posted the script on GitHub should you wish to download.
https://github.com/Gbeer7/GetPingStatus.git
The full script:

Function Get-PingStatus { param( [Parameter(ValueFromPipeline=$true)] [string]$device, [validateSet("Online","Offline","ObjectTable")] [String]$getObject ) begin{ $hash = @() } process{ $device| foreach { if (Test-Connection $_ -Count 1 -Quiet) { if(-not($GetObject)){write-host -ForegroundColor green "Online: $_ "} $Hash = $Hash += @{Online="$_"} }else{ if(-not($GetObject)){write-host -ForegroundColor Red "Offline: $_ "} $Hash = $Hash += @{Offline="$_"} } } } end { if($GetObject) { $Global:Objects = $Hash | foreach { [PSCustomObject]@{ DeviceName = $_.Values| foreach { "$_" } Online = $_.Keys| where {$_ -eq "Online"} offline = $_.Keys| where {$_ -eq "Offline"} } } Switch -Exact ($GetObject) { 'Online' { $Global:Objects| where 'online'| select -ExpandProperty DeviceName } 'Offline' { $Global:Objects| where 'offline'| select -ExpandProperty DeviceName } 'ObjectTable' { return $Global:Objects } } } } }

Related Articles

Sep 15, 2023

PowerShell Escape Room

PowerShell Escape Room by Michiel Hamers by Michiel Hamers https://about.me/michielhamers/ Why on earth you want to create an Escape Room with PowerShell as backend? I’ve always been a fan of escape rooms, so I decided to create my own for my kids. I wanted to make it something that would be challenging and fun for them, but also educational. I decided to use PowerShell as the backend for the escape room, as I’m a PowerShell developer and I thought it would be a great way to learn more about the language.

Sep 15, 2023

Microsoft Graph PowerShell Module: Getting Started Guide

Microsoft Graph PowerShell Module: Getting Started Guide by Jeff Brown Microsoft is retiring the Azure AD Graph API sometime after June 30, 2023 (announcement). This retirement includes the Azure AD PowerShell module. In its place, Microsoft has released the Microsoft Graph PowerShell module. The Microsoft Graph PowerShell module is the next-generation way of managing Microsoft cloud services using PowerShell. If you have used MSOnline or Azure AD PowerShell in the past, you’ll need to read on to learn about this new module.

Oct 8, 2021

ICYMI: PowerShell Week of 08-October-2021

Topics include VMWare, Windows 11, Web Reports and more… Special thanks to Robin Dadswell, Prasoon Karunan V, Kiran Patnayakuni and Kevin Laux How to gather your vCenter inventory data with this VMware PowerShell script by Scott Matteson on 7th October Inventory reports are a common request when administering a VMware vCenter environment. Learn how this VMware PowerShell script can make such requests quick and easy Building a Web Report in PowerShell, use the -Force Luke by Chris Noring on 8th October