How to check open ports using powershell?

Sidney Harris picture Sidney Harris · Oct 6, 2013 · Viewed 16.8k times · Source

I would like to write a script to check radom IP or hostname to see if ports are open. Here is what I have so far. The scripts name is checkports.

foreach ($xhost in $computername){
    Write-Host $xhost
    foreach ($port in $ports) {
        $Socket = New-Object System.Net.Sockets.TCPClient            
        $Connection = $Socket.BeginConnect($xhost,$port,$null,$null) 

        $Connection.AsyncWaitHandle.WaitOne(5000,$false) | out-null

        if ($Connection -eq $true)
            { write-host = "$xhost port $port is open" }
        else
            { write-host = "port $port is closed" }      

        $Socket.EndConnect($Connection)
        $Socket.Close()
   }
}

I would like to input values in the following way: .\checkport '192.186.1.5' or '192.168.1.5', '192.168.1.105', 192.168.1.110' | checkport

It doesn't seem to be reading IP address or displaying results.

I was wondering if anyone could point out there could show me what I am doing wrong in with this script?

Answer

schelljw picture schelljw · Nov 2, 2013

I've been able to use the 'Test-Port' function from Boe Prox for similar scan/ reporting functions, the code is available on PoshCode:

http://poshcode.org/2514

When I needed to test ports for Directory health, I built a csv with 'port' and 'protocol' columns, then added the port number/ protocol for each port to check. This was used in the following script:

. .\test-port.ps1

$computersToCheck = get-content .\computers.txt
$portList = Import-CSV .\portList.csv

foreach($entry in $portList)
{
    $testPortParams = @{
        port = $($entry.port)
    }   
    if( $($entry.protocol) -eq "tcp")
    { $testPortParams += @{ TCP = $true } }
    else
    { $testPortParams += @{ UDP = $true } }

    $outLog = "portTest-$($entry.port)-$($entry.protocol).txt"

    $computersToCheck | 
        Test-Port @testPortParams |
        Sort-Object -Property open,name -descending | 
        format-table -auto -outVariable status
    Add-Content -path $outLog -value $status 
}

You could certainly build a feeder script to build the range of IP addresses and ports to scan.