One of the questions that I often get is “How do I know if a
client is online?” Traditionally we would PING the client. PowerShell has a cmdlet called
Test-Connection. It essentially is the
PING command, but gives you an object as the output. Let’s see the difference.
PS C:\> Ping 8.8.8.8
Pinging 8.8.8.8 with 32 bytes of data:
Reply from 8.8.8.8: bytes=32 time=19ms TTL=56
Reply from 8.8.8.8: bytes=32 time=20ms TTL=56
Reply from 8.8.8.8: bytes=32 time=20ms TTL=56
Reply from 8.8.8.8: bytes=32 time=20ms TTL=56
Ping statistics for 8.8.8.8:
Packets: Sent = 4,
Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 19ms,
Maximum = 20ms, Average = 19ms
This is what most IT Pros are seeing. Let’s try to use this information.
As always, we need to see what properties are available to
us to use.
PS C:\> Ping 8.8.8.8 | GM
TypeName:
System.String
Name
MemberType Definition
----
----------
----------
Clone
Method
System.Object Clone(), System.Object ICloneable.Clone()
CompareTo
Method int
CompareTo(System.Object value), int CompareTo(string strB), int
IComparable.CompareTo(System.Object obj), int ICompa...
OK, let’s just stop right here. The TypeName is System.String. In other words, the information returned from
PING is nothing but useless characters. Let’s try Test-Connection.
PS C:\> Test-Connection -ComputerName 8.8.8.8
Source Destination
IPV4Address IPV6Address Bytes Time(ms)
------ ----------- ----------- ----------- ----- --------
JASONPC2 8.8.8.8 8.8.8.8 32
19
JASONPC2 8.8.8.8 8.8.8.8 32 21
JASONPC2 8.8.8.8 8.8.8.8 32 23
JASONPC2 8.8.8.8 8.8.8.8 32 20
Now let’s check the TypeName
TypeName:
System.Management.ManagementObject#root\cimv2\Win32_PingStatus
Name
MemberType Definition
----
---------- ----------
PSComputerName
AliasProperty PSComputerName =
__SERVER
Address
Property string Address
{get;set;}
BufferSize
Property uint32 BufferSize
{get;set;}
Now we are talking.
This give us an object that we can use.
There is just one problem, we are relying on ICMP Echo Requests. If you have PowerShell remoting turned on,
you can actually use it to verify if a client is online. Take a look at the code.
Function Test-Online
{
[CmdletBinding()]
Param (
[parameter(Mandatory=$true,
ValueFromPipeline=$true)]
[String[]]
$Nodes
)
PROCESS {
ForEach
($N in
$Nodes)
{
$Obj
= New-Object
-TypeName PSObject
-Property @{
ComputerName = $N
Online =
$False
DateTime =
(Get-Date)
}
Try
{
$SO
= New-PSSessionOption
-OpenTimeout 500
$S
= New-PSSession
-ComputerName $N
-ErrorAction Stop
-SessionOption $SO
$Obj.Online = $True
$S
| Remove-PSSession
}
Catch
{
}
Write-Output
$Obj
} # END:
ForEach ($N in $Nodes)
}
# END: PROCESS
<#
.SYNOPSIS
Uses PowerShell Remoting to test if a node is online.
.DESCRIPTION
Uses PowerShell Remoting to test if a node is online.
.PARAMETER Nodes
The name of the nodes to be tested.
.Example
"SVR1", "SVR2" | Test-Online
ComputerName
DateTime Online
------------
-------- ------
SVR1 6/7/2016
10:30:59 AM True
SVR2 6/7/2016
10:31:00 AM False
Test to determine if a list ofnodes are online.
.Example
Get-ADComputer -Filter * | Select-Object -ExpandProperty Name
| Test-Online
ComputerName
DateTime Online
------------
-------- ------
SVR1 6/7/2016
10:30:59 AM True
SVR2 6/7/2016
10:31:00 AM False
Test all clients in Active Directory to see if they are
online.
.NOTES
Any node that does not have PowerShell Remoting enabled will
report an online status of False.
.NOTES
===============================================================================
== Cmdlet: Test-Online
==
== Author: Jason A. Yoder
==
== Company: MCTExpert of Arizona ==
== Date: June 7, 2016
==
== Copyright: All rights reserved. ==
== Version: 1.0.0.0
==
== Legal: The user assumes all responsibility and liability
for the usage of ==
== this PowerShell code.
MCTExpert of Arizona, Its officers, shareholders, ==
== owners, and their relatives are not liable for any
damages. As with all ==
== code, review it and understand it prior to usage. It is recommended that ==
== this code be fully tested and validated in a test
environment prior to ==
== usage in a production environment. ==
== ==
== Does this code make changes: NO ==
===============================================================================
#>
}
# END: Function Test-Online
Here is what it looks like when used:
"SVR1", "SVR2" | Test-Online
ComputerName
DateTime Online
------------
-------- ------
SVR1 6/7/2016
10:30:59 AM True
SVR2 6/7/2016
10:31:00 AM False
For every node that we pass to this cmdlet, a custom object
is created. We provide the value on the
ComputerName and the DateTime that we are testing. We also set the value for Online to be $False. Next, we attempt to create a PowerShell
Session to this remote client. If the
connection is made, we set the value of Online to $True and close the session. We then place the object in the
pipeline. If the session does not get established,
then the object is placed in the pipeline with the Online value still set to $False.
PowerShell remoting is already enabled on all Windows Server
2012 and newer. Why not enable it on
your clients? This allows your remote
connections to use WS-MAN as the remoting protocol as opposed to the older
DCOM.
Comments