Alright, so when I run script and am doing just general mayhem in my powershell session I always find a need to know which computers are online before running a script against them. Mainly because it is faster and I get less errors from my script not being able to reach a computer.

So yes, one could use Test-Connection, which is a native powershell cmdlet which will test if computers are online for you. However, I hate Test-Connection. I understand some people like it and use it all the time and whatnot, and I don’t mean any offense….but I don’t like Test-Connection. I have always felt it is very clunky and takes forever to run. With that thought mind I decided to write my own function which would do this testing of online computers for me.


Function Filter-Online{
<#
.Description

This is just a quick little script, but it does some cool things. Mainly I just created it in order to be able to quickly check whether computers are "online" or not.

It does this through a simple ping...so if a computer is On and Not responding to pings, it will not be listed as online.

This script can accept input either from the pipeline OR through the -parameter command

The great thing is that most things you would want to check their online status use the Name property so this works great for most things!

.Parameter Name

The only parameter that matters. Accepts just one or multiple objects

.Parameter NotOn

Used for if you would rather the returned objects be the ones that did Not respond to pings
.Example

get-adcomputer * |filter-online

Will take all of the computers listed in AD and return only the ones which are determined to be online
.Example

Filter-Online -name (get-vm)
Will take all of the computers listed in vCenter and return only the ones which are determined to be online. Yes, VMs have a PoweredOn Property, but that doesnt mean they have network connectivity

.Link
 www.vnoob.com

 .Notes

====================================================================
 Author:
 Conrad Ramos <conrad@vnoob.com> https://www.vnoob.com/

Date: 2012-3-14
 Revision: 1.0

====================================================================
#>

[CmdletBinding()]
param([Parameter(Mandatory=$True, ValueFromPipeline=$True)]$servers,[switch]$noton)

Begin{
$online=@()
$offline=@()

}
Process{
Foreach($server in $servers){
$reply=$null
 $ping = new-object System.Net.NetworkInformation.Ping
 $servername=$server.name
 Write-Verbose "Testing $servername"
try{
 $Reply = $ping.send($servername)
 }
Catch {}
if ($Reply.status –eq “Success”)
{
$online+=$server}
else
{$offline+=$server}
}

}

End{
IF($noton -eq $false){
Write-Verbose "---------------------------------"
Write-Verbose "The following are online"
$online
}
Else{
Write-Verbose "---------------------------------"
Write-Verbose "The following are offline"
$offline
}
}

}

This is an advanced function, or atleast I think it is, I can never remember the criteria for an advanced function. Anyway this will take object given to it by either the pipeline or through parameters, and after it is done it spits back out the objects instead of just the property name. For instance

get-adcomputer * | Filter-online

Will give you all the adcomputer objects that are currently online, or can be pinged.  And

Filter-Online (get-vm)

Will give you all the VM objects that can currently be pinged.

This is great, however it does utilize the Name property so if you have VMs that have different DNS names than their VM names, then it will think those computers are not online.

Sweet HUH!

Also Recently I found out about Filters from Boe sending me this discussion on them . No I am Not talking about a filter like the parameter -filter { }, I am talking about it as a function. So instead of doing

Function verb-noun{

You do

Filter verb-noun{

Crazy huh!

So these kind of filters operate in a very similar way to Functions, except instead of Begin, Process, and End blocks, Filters just have the Process block. In other words they are kind of a light-weight function. Also because of only being a Process block, they automatically accept pipeline input. After finding out about this sweet new (atleast to me) kind of fuction. I had to then do my script above a second time but just as Filter.


filter filtering-online{
$reply=$null
 $ping = new-object System.Net.NetworkInformation.Ping
 $servername=$_.name
 Write-Verbose "Testing $servername"
try{
 $Reply = $ping.send($servername)
 }
Catch {}
if ($Reply.status –eq “Success”)
{$_}
}

As you can see right out of the gate, it can do a $_ since it is already accepting pipeline input. Pretty sweet huh!

So after doing all this, and because I kind of hate Test-Connection, I decided to see how my function and filter stands up to  Test-Connection

image

Sweet SOOO Much faster. Yes, I understand using the Where-Object with the pipeline is possibly slowing down the test connection process. But is it making it like 7 times slower….I doubt it.

So in an effort to give Test-Connection a Chance

image

Still Fail for Test-Connection

Hope this is helpful! Let me know what you think!!!

Also as a side-note…..

TODAY IS MY BIRTHDAY!!!!!!! Hooray! I turn the big 27!!!! I am getting to be an old man!!! 🙁

[wpfilebase tag=file id=2 /]


4 Comments

Tom · November 6, 2013 at 6:53 pm

I guess I’m the ultimate noob! I can’t get any output from your script when executed.

I have a txt file with a list of computers that I’d like to use.

How do I pass the list to the script so the script will check each computer and determine its online status?

Much appreciated…

Tom

    C-Rad · November 8, 2013 at 2:27 pm

    Yeah, Thanks for the question.

    With these functions/filters the first thing you need to do is save the function/filter as a .ps1 file.

    Once saved, you then need to “dot source” the function/filter, for instance:
    “. ./filter-online.ps1”

    What this does is put that filter into the scope that powershell is running, from there you can use the same examples that I demonstrate in the article. I hope this helps.

    Let me know if you have any other questions.

      C-Rad · November 8, 2013 at 2:30 pm

      Also if using a txt file with computer names try something like the “get-content” cmdlet.

      Get-Content ./servernames.txt | Filter-Online

Peter Kriegel · December 3, 2013 at 4:21 am

See my Article on PowerShell Magazin! 😉
#PSTip How to speed up the Test-Connection command
http://www.powershellmagazine.com/2012/10/19/pstip-how-to-speed-up-the-test-connection-command/

Peter Kriegel
http://www.PowerShell-Group.eu

Leave a Reply to C-RadCancel reply