A Quick Ping Solution

Sunday, July 13, 2014
<#

Purpose:    Quickly return Ping results for an array of computers.
Note:        I can't take all of the credit for this one - not much
            at all really.  A colleague of mine wrote the base that I've
            used in this script.  I just modified it for my purposes.
            I'm 110% that my co-worker could have tailored the original
            script to my needs in a more efficient manner than I have
            here; but again - I wanted the challenge.  The script will
            accept parameters though the pipeline, or as standard. 
            ie:
                [String]$Machines | .\FastPing.ps1
                .\FastPinger.ps1 $Machines
            As usual, any feedback is greatly appreciated!
Notes:        As you can see in the first usage example that I provided,
            when piping and array to the script, you have to first cast
            it as a string.  I'm not entirely sure why that is.  Ideas? 

#>

Param(
    [Parameter(ValueFromPipeline=$True)][String[]]$InputList
     )

$InputList = $InputList.split()

$ScriptBlock = {
    Param(
        $Machine
           )
    
    [int]$Timeout = 200
    $Options = New-Object System.Net.NetworkInformation.PingOptions
    $Options.TTL = 128
    $Options.DontFragment = $false
    $Buffer=([System.Text.Encoding]::ASCII).GetBytes('a'*32)
    $Ping = New-Object System.Net.NetworkInformation.Ping
    $Reply = $Ping.Send($Machine,$Timeout,$Buffer,$Options)

    Try{
        [Void][System.Net.Dns]::GetHostEntry($Hostname)
        }
    Catch{
        $Ping_Result = 'DNS Issue'
        }

    if($reply.status -eq 'Success'){
        $Ping_Result = 'Online'
        }
    else{
        $Ping_Result = 'Offline'
        }

    [PSCustomObject]@{
        Machine = $Machine
        Ping    = $Ping_Result
        }
    }

#Create a RunspacePool with a maximum size of 100
$RunspacePool = [RunspaceFactory]::CreateRunspacePool(1,100)
$RunspacePool.Open()

#Create a job for each Machine in the InputList, and send it to the RunspacePool
$Jobs = ForEach($Machine in $InputList){
    $Job = [PowerShell]::Create().AddScript($ScriptBlock).AddArgument($Machine)
     $Job.RunspacePool = $RunspacePool
    #Create an object 
    [PSCustomObject]@{
        Pipe = $Job
        Result = $Job.BeginInvoke()
        }
    }

$Results = $(ForEach ($Job in $Jobs){
    $Job.Pipe.EndInvoke($Job.Result)
    })

Return $Results

$RunspacePool.Close()
$RunspacePool.Dispose()

No comments:

Post a Comment

Please keep all comments clean!