Posts RSS Comments RSS 253 Posts and 411 Comments till now

Test-Host (WMI Ping -or Port Check)

I often find (specifically when using WMI) the need to ping the machine first before performing any queries. WMI takes FOREVER to timeout. I decided that I should use a script/function to test a host before passing it down the pipe.

There are a couple of problems with this approach that I had to consider.
1) How do I know what to test without corrupting the pipe or using foreach?
– For this I added a “-property” parameter that would allow the user to pick what property to check against, but still output the entire object that was inputted.

2) What about firewalls that block ping?
– Added TestPort function that does a TCP connect and returns $true or $false

3) What if I want a conditional port check.
– Added the ability to Change the Default Port for TCP Connection Test

Here is the script that I came up with and some of things it does.
Parameters
$property: The Property to Ping or Test (Default is none.)
$tport: The Port to test against (Default is 135. Used with -port)
$timeout: The timeout for the connection (Default is 1000 ms, Used with -port)
[switch]$port: Switch to Test a port instead of Ping
[switch]$verbose: Provides Verbose Output.
Features
– Will Ping ‘$_’ by default
– Can pass the property that contains the Host to test using -property
– Can use -port to test a port instead of ping. (Uses TCP)
– Maintains the Object that is tested and passes it down the pipe if connection is passed.

A Demo of the script in action

Best Viewed Full Screen

Get the Flash Player to see this content.


Script CODE

Param($property,$tport=135,$timeout=1000,[switch]$port,[switch]$verbose)
Begin{
    function TestPort {
        Param($srv)
        $error.Clear()
        $ErrorActionPreference = "SilentlyContinue"
        $tcpclient = new-Object system.Net.Sockets.TcpClient
        $iar = $tcpclient.BeginConnect($srv,$tport,$null,$null)
        $wait = $iar.AsyncWaitHandle.WaitOne($timeout,$false)
        # Traps    
        trap {if($verbose){Write-Host "General Exception"};return $false}
        trap [System.Net.Sockets.SocketException]
        {
            if($verbose){Write-Host "Exception: $($_.exception.message)"}
            return $false
        }
        if(!$wait)
        {
            $tcpclient.Close()
            if($verbose){Write-Host "Connection Timeout"}
            return $false
        }
        else
        {
            $tcpclient.EndConnect($iar) | out-Null
            $tcpclient.Close()
        }
        if(!$error[0]){return $true}
    }
    function PingServer {
        Param($MyHost)
        $pingresult = Get-WmiObject win32_pingstatus -f "address=’$MyHost’"
        if($pingresult.statuscode -eq 0) {$true} else {$false}
    }
}
Process{
    if($_)
    {
        if($port)
        {
            if($property)
            {
                if(TestPort $_.$property){$_}  
            }
            else
            {
                if(TestPort $_){$_}
            }
        }
        else
        {
            if($property)
            {
                if(PingServer $_.$property){$_}  
            }
            else
            {
                if(PingServer $_){$_}
            }
        }
    }
}

If you want this as a function use this code

function Test-Host{
Param($property,$tport=135,$timeout=1000,[switch]$port,[switch]$verbose)
Begin{
    function TestPort {
        Param($srv)
        $error.Clear()
        $ErrorActionPreference = "SilentlyContinue"
        $tcpclient = new-Object system.Net.Sockets.TcpClient
        $iar = $tcpclient.BeginConnect($srv,$tport,$null,$null)
        $wait = $iar.AsyncWaitHandle.WaitOne($timeout,$false)
        # Traps    
        trap {if($verbose){Write-Host "General Exception"};return $false}
        trap [System.Net.Sockets.SocketException]
        {
            if($verbose){Write-Host "Exception: $($_.exception.message)"}
            return $false
        }
        if(!$wait)
        {
            $tcpclient.Close()
            if($verbose){Write-Host "Connection Timeout"}
            return $false
        }
        else
        {
            $tcpclient.EndConnect($iar) | out-Null
            $tcpclient.Close()
        }
        if(!$error[0]){return $true}
    }
    function PingServer {
        Param($MyHost)
        $pingresult = Get-WmiObject win32_pingstatus -f "address=’$MyHost’"
        if($pingresult.statuscode -eq 0) {$true} else {$false}
    }
}
Process{
    if($_)
    {
        if($port)
        {
            if($property)
            {
                if(TestPort $_.$property){$_}  
            }
            else
            {
                if(TestPort $_){$_}
            }
        }
        else
        {
            if($property)
            {
                if(PingServer $_.$property){$_}  
            }
            else
            {
                if(PingServer $_){$_}
            }
        }
    }
}}

Trackback this post | Feed on Comments to this post

Leave a Reply

You must be logged in to post a comment.