Saturday, January 8, 2011

ping multiple subnets

# 'ping-multiple_subnets.ps1
# All Rights Reserved Ryan M. Ferris r.10:34 PM 1/7/2011
# Powershell V2 functions to ping multiple-subnets
# Consists of three functions: (ping-subnet, ping-ip , ping-multi)
# ping-subnet : .NET $ping.send - a single (simple) eight byte ICMP packet
# ping-ip : WMI 'test-connection' - a single (wmi info) eight byte ICMP packet
# ping-multi : wrapper function 
    # first create multiple Class C ranges: e.g.: 
    # $IPRange = 0..5 | %{"192.168.$_"}
    # use 'ping-multi' to discover them: e.g.:
    # $IPRange | % {ping-multi $_}
# The .NET $ping.send is much faster than WMI although 'test-connection' returns more
# information and can be configured to do authentication and impersonation
# Essentially, 'ping-subnet' does discovery that it pumps to 'ping-ip' which 
# creates csv files named per subnet per pass.

function global:Ping-Subnet
{
   [CmdletBinding()]
   Param(
       [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
       [string]$Network,
       [array] $subnet=@(0..254),
       [int32] $buffersize=8,
       [Int32] $timeout=10,
       [Int32] $TTL=128,
       [bool]  $fragment=$false,
       [string]$ErrorActionPreference="silentlycontinue"
          )
$ping = new-object System.Net.NetworkInformation.Ping
$pingoptions = new-object System.Net.NetworkInformation.PingOptions
$pingoptions.ttl=$TTL
$pingoptions.dontfragment=$fragment
$Global:SNIPs=( $subnet | % -process  {$Ping.Send("$Network.$_", $timeout, $buffersize, $PingOptions)} | 
                where {$_.Status -eq "Success"})
$Global:IPs= $SNIPs | % {$_.Address.IPAddressToString}
}

function global:Ping-ip 
{
   [CmdletBinding()]
   Param(
       [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
       [string]$computername,
       [int32] $buffersize=8,
       [int32] $count=1,
       [Int32] $TimeToLive=128,
       [Int32] $Delay=1,
       [string] $ErrorActionPreference="silentlycontinue"
          )

        $global:result= Test-connection    -computername $computername `
                        -buffersize $buffersize `
                        -count $count `
                        -TimeToLive $TimeToLive `
                        -Delay $Delay
        $global:icmp_out  = New-Object PSObject -Property @{
            IPv4          = $result.IPv4Address.IPAddressToString
            IPv6          = $result.IPv6Address.IPAddressToString
            BytesSent     = $result.BufferSize
            BytesReturned = $result.ReplySize
            ResponseTime  = $result.ResponseTime
            ReplyInc      = $result.ReplyInconsistency
      } | Select-Object IPv4,IPv6,BytesSent,BytesReturned,Responsetime,ReplyInc
    
if ($icmp_out -ne $null)
    {$ICMP_out | ConvertTo-Csv -NoTypeInformation | out-file -width 120 -append -NoClobber (write "$3OCT.csv")}
}
function ping-multi
{
Param(
       [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
       [string] $Global:3OCT
       )
$3OCT | % {ping-subnet $_}
$IPs  | % {ping-ip $_}
}

Tuesday, January 4, 2011

Using Test-Connection

'Test-Connection' is Powershell V2's GWMI-based icmp test cmdlet that returns considerable amounts of information in object format.  'Test-Connection' also has the ability to authenticate (at various levels) to the computer whose ICMP responses it is testing, but I do not discuss that in this post. 'Test-Connection' can return a number of errors, which I found difficult to trap, throw, or try-catch-finally.  So, like some others (1,2), I punted on error-trapping with:
 [string] $ErrorActionPreference="silentlycontinue"  (Yea, I know...what a wimp...) 
Although, 'Test-Connection' is slower than System.Net.NetworkInformation.Ping will probably ever be, it does return considerable amounts of useful information. Below is the function 'Ping-IP' with the returned object and some statistical results from 'measure-object'. I've created a hash table and renamed six of the properties.  Notice how I can use 'Test-Connection' to check for IPv4 and IPv6 connections simultaneously (if you have an existing IPv6 interface).