Use PowerShell
Real Admins Script
Real Admins Script
Last week, I defined a number of terms that we’ll be exposed to as we delve into how and why PowerShell is an object oriented shell and how to use it to explore .NET Framework which it is built upon.
Now, let’s take a look at how some of these terms surface themselves in PowerShell.
One of the most common tasks you might encounter is needing to ping a computer. There is ping.exe, which works and has been a common guest in my console sessions for years. You can also get ping information via WMI which provides you with some interesting information.
PS C:\scripts\PowerShell> Get-WmiObject Win32_PingStatus -filter “Address=’google.com’”
My preference is to use a class from the .NET Framework called Ping. Ping lives in the System.Net.NetworkInformation namespace.
To access this in PowerShell, I’ll create an instance of the class and refer to it with a variable, $ping.
PS C:\scripts\PowerShell> $ping = New-Object System.Net.NetworkInformation.Ping
By typing the method name without the parenthesis immediately after it, PowerShell will give us information about the method.
PS C:\scripts\PowerShell> $ping.send
MemberType : Method
OverloadDefinitions : {System.Net.NetworkInformation.PingReply Send(String ho
stNameOrAddress), System.Net.NetworkInformation.PingRep
ly Send(String hostNameOrAddress, Int32 timeout), Syste
m.Net.NetworkInformation.PingReply Send(IPAddress addre
ss), System.Net.NetworkInformation.PingReply Send(IPAdd
ress address, Int32 timeout)…}
TypeNameOfValue : System.Management.Automation.PSMethod
Value : System.Net.NetworkInformation.PingReply Send(String hos
tNameOrAddress), System.Net.NetworkInformation.PingRepl
y Send(String hostNameOrAddress, Int32 timeout), System
.Net.NetworkInformation.PingReply Send(IPAddress addres
s), System.Net.NetworkInformation.PingReply Send(IPAddr
ess address, Int32 timeout), System.Net.NetworkInformat
ion.PingReply Send(String hostNameOrAddress, Int32 time
out, Byte[] buffer), System.Net.NetworkInformation.Ping
Reply Send(IPAddress address, Int32 timeout, Byte[] buf
fer), System.Net.NetworkInformation.PingReply Send(Stri
ng hostNameOrAddress, Int32 timeout, Byte[] buffer, Pin
gOptions options), System.Net.NetworkInformation.PingRe
ply Send(IPAddress address, Int32 timeout, Byte[] buffe
r, PingOptions options)
Name : Send
IsInstance : True
What I am most interested in is the Overload Definitions, which is the explanation of how I can use this method.
PS C:\scripts\PowerShell> $ping.send.overloaddefinitions
System.Net.NetworkInformation.PingReply Send(String hostNameOrAddress)
System.Net.NetworkInformation.PingReply Send(String hostNameOrAddress, Int32 timeout)
System.Net.NetworkInformation.PingReply Send(IPAddress address)
System.Net.NetworkInformation.PingReply Send(IPAddress address, Int32 timeout)
System.Net.NetworkInformation.PingReply Send(String hostNameOrAddress, Int32 timeout, Byte[] buffer)
System.Net.NetworkInformation.PingReply Send(IPAddress address, Int32 timeout, Byte[] buffer)
System.Net.NetworkInformation.PingReply Send(String hostNameOrAddress, Int32 timeout, Byte[] buffer, PingOptions options)
System.Net.NetworkInformation.PingReply Send(IPAddress address, Int32 timeout, Byte[] buffer, PingOptions options)
As we can see from the above output $ping.Send has several different ways that we can call it and it also shows the object that we will get in return, an object of the type System.Net.NetworkInformation.PingReply.
The first overload for $ping.Send is to supply it an object of the type String (remember, in PowerShell, even text is an object) which represents the hostname or IP address of the host we wish to ping.
PS C:\scripts\PowerShell> $ping.send(‘google.com’)
Status : Success
Address : 74.125.45.100
RoundtripTime : 29 ms
BufferSize : 32
Options : TTL=243, DontFragment=False
Here, we called $ping.Send with a argument of the String ‘google.com’ and received back an object of the type PingReply. We can see the textual representation of it’s properties. In my next post, we’ll dig into the return object a bit more and see how we can use its properties to our advantage.
We still have a number of other ways that we can call $ping.Send. Our second option is to provide a String describing the hostname or IP address (as before), but also allows us to specify a timeout by providing an Int32. (Just a quick note, if you specify a really low timeout value, the reply still may be received. It is more of an option to provide a longer than normal, five seconds, timeout period.)
We also see overloads that take an object of the IPAddress type to describe the target of the Ping.
Now, things get a bit more interesting. The next argument we see is of the type Byte[], which means an Array of Byte objects. The quick explanation of an Array is a collection of objects (not 100 percent accurate, but sufficient for right now). This allows us to specify exactly what data will be sent with the ICMP echo message.
The final argument is to supply an object of the PingOptions type. This allows us to specify an Int32 as the TTL (Time To Live) and a Boolean as Don’t Fragment option.
I’m starting to run a bit long here, so I’m going to continue walking through this example in my next post. We’ll create an object of type Ping with some custom options and then dig in to the object that is returned.
June 3, 2009 - 12:29 pm
Excellent article.. one question.. how can we filter this .NET ping script to return only the items wanted.. i.e. Status and IP address..?
June 3, 2009 - 6:26 pm
I would do something like:
$ping.Send(‘google.com’) | Select-Object -Property Status, Address
( or the shorter form $ping.Send(‘google.com’) | select status, address )
June 4, 2009 - 8:59 am
Excellent.. the ‘Select-Object’ addition worked… just need to figure how to filter out just certain IP range next.
Thank you !
June 4, 2009 - 10:23 am
To filter, we can use Where-Object.
‘Server1′, ‘Server2′, ‘Server3′ | Foreach-Object { $ping.Send($_ } | Where-Object { $_.Address -match ‘192\.168\.10\.[1-254]‘ } | Select-Object -Property address, status
Or the shorter version
‘Server1′, ‘Server2′, ‘Server3′ | % { $ping.Send($_ } | ? { $_.Address -match ‘192\.168\.10\.[1-254]‘ } | Select address, status
June 4, 2009 - 11:21 am
Well, when the ‘Where-Object’ piece is added it does not return any values..
Here is what I have that works:
$colComputers = get-content “C:\servers.txt”
foreach ($strComputer in $colComputers)
{
$ping = new-object System.Net.NetworkInformation.Ping
Write-Host Checking server: $strComputer
$Response = $ping.send($strComputer) | Select-Object -Property Address
$Response
}
But when Where-Object is used I get no IP’s returned..?
Where-Object { $_.Address -match ‘10\.223\.42\.[1-254]‘ }