As the headline says, it’s all about port scanning today. When a computer sends SYN to another computer, the remote computer will usually answer with SYN + ACK or RST. By this fact, we can test if a port is open or not.
Different port scanners can be used to test whether a port is open or not. Or Test-NetConnection or a self-created script. Remember Test NetConnection:
But if you try to test multiple computers and multiple ports you are faced with an error message.
The following function addresses this issue. Test-OpenPort allows testing multiple computers and multiple ports at once.
Test-OpenPort
Before we get to the function itself, I would like to show my function in action. The function has two parameters: Target and Port.
Test-OpenPort -Target 192.168.0.1 -Port 80
These parameters are not named, so therefore you can omit the parameter names.
Test-OpenPort 192.168.0.1 80
You can also omit the Target. The default value for this parameter is localhost.
Test-OpenPort -Port 80,443
Running on multiple computers and ports requires the use of a comma.
Test-OpenPort 192.168.0.1,sid-500.com -Port 80,443
The screen’s output is an object. Therefore you are able to customize this object with Select-Object or the Format-Commands (Format-Table …)
Test-OpenPort 192.168.0.1,sid-500.com -Port 80,443,53 | Sort-Object Status
For a more sweeter view:
Test-OpenPort 192.168.0.1,sid-500.com -Port 80,443,53 | Sort-Object Status | Out-GridView
The Function
Copy this function into your PowerShell ISE session and press the green start button.
function Test-OpenPort { <# .SYNOPSIS Test-OpenPort is an advanced Powershell function. Test-OpenPort acts like a port scanner. .DESCRIPTION Uses Test-NetConnection. Define multiple targets and multiple ports. .PARAMETER Target Define the target by hostname or IP-Address. Separate them by comma. Default: localhost .PARAMETER Port Mandatory. Define the TCP port. Separate them by comma. .EXAMPLE Test-OpenPort -Target sid-500.com,cnn.com,10.0.0.1 -Port 80,443 .NOTES Author: Patrick Gruenauer Web: https://sid-500.com .LINK None. .INPUTS None. .OUTPUTS None. #> [CmdletBinding()] param ( [Parameter(Position=0)] $Target='localhost', [Parameter(Mandatory=$true, Position=1, Helpmessage = 'Enter Port Numbers. Separate them by comma.')] $Port ) $result=@() foreach ($t in $Target) { foreach ($p in $Port) { $a=Test-NetConnection -ComputerName $t -Port $p -WarningAction SilentlyContinue $result+=New-Object -TypeName PSObject -Property ([ordered]@{ 'Target'=$a.ComputerName; 'RemoteAddress'=$a.RemoteAddress; 'Port'=$a.RemotePort; 'Status'=$a.tcpTestSucceeded }) } } Write-Output $result }
Make it permanent
If you like my approach open PowerShell ISE. Copy the function into your ISE session. Create a folder in C:\Program Files\Windows PowerShell\Modules and save the code as psm1 file. Make sure that your file name and folder name match.
Close PowerShell. Open PowerShell again. The command is now available for all users. Have fun with Test-OpenPort!
Categories: Cyber Security, PowerShell
Hi Patrick.. Must have been awesome solution but nothing working.
I followed all the mentioned steps. It is not getting imported & even cannot run it as ps1 by commenting function declaration..
LikeLike
Hi, it is a psm1 file. Test-Openport can also be installed via Powershell Gallery. Best
LikeLike
Can it scan RDP port? Port 3389? I would like the results of just the False connections.
Get-Content -path \Device-Check_PS1\devices\devicelist.txt | Test-NetConnection -CommonTCPPort RDP | Select ComputerName,PingSucceeded | Out-File -FilePath \Device-Check_PS1\Logs\errorLog_$today.txt
LikeLike
Hi, you are refering to Test-NetConnection, not to Test-OpenPort. I would recommend reading the help for Test-NetConnection.
LikeLike
how to test the port from a range of 1000 to 2000 with this script?
LikeLike
Unfortunately not possible with this script.
LikeLike
Its under “Make it permanent”
LikeLike
Good morning
I am running the command and it returns an a new prompt with no result. What’s happening?
PS C:\Users\adrian\Downloads> .\Test-OpenPort.ps1 10.7.40.16 80
PS C:\Users\adrian\Downloads>
LikeLike
Please follow my guide on how to implenent the function at the end of the blog post. Best, P
LikeLike
Good morning
I am running the command and it returns an a new prompt with no result. What’s happening?
PS C:\Users\adrian\Downloads> .\Test-OpenPort.ps1 10.7.40.16 80
PS C:\Users\adrian\Downloads>I didnt find
LikeLike
Sorry. I didn’t find it. Where is it?
LikeLike
thank you i changed it slightly to scan a port range, it was very useful although is kinda slow.
LikeLiked by 1 person
Hi Patrick,
Thanks so much for writing & sharing this script, I’m hoping it’s able to assist in testing within our network. I’m confused about one crucial aspect:
The Target & RemoteAddress appear to be the same IP address. Is your script testing open port connectivity locally on each IP address listed?
I would expect those to be different as in a Source IP & Destination IP, and testing port connectivity between those two IP addresses.
I’m attempting to use your function to test a list of open ports between a source IP of 192.168.2.10 and a destination IP of 192.168.2.12, but not clear on how to do so.
Can you shed some light on this by chance?
LikeLike
Thank you for the kind words. If no target is provided, localhost is the default value.
LikeLike
Thanks for the response Patrick.
I’m still confused as to why the Target & RemoteAddress are the same exact IP address in your screenshots above. It looks like you’re testing port connectivity between 192.168.0.1 and 192.168.0.1 (same IP address).
Is your script capable of testing port connectivity between 2 different IP addresses?
If so, I’m not understanding how your output is demonstrating that. Can you help me understand how to specify a Source IP and a different Destination IP, while testing whether port 25 is open?
Thank you once again good sir!
LikeLike
Ah, I see. Note that remote address shows the IP Address and the Target show the DNS name if any. If not the up is shown in the target table.
LikeLike
You can either test open ports by ip or dns name. Try it out and you will see what I mean.
LikeLike
Hi Patrick,
To demonstrate what I’m seeing, I’m running this command from a server with the IP address of 192.188.1.10 and getting the subsequent output:
Test-OpenPort -Target 192.188.1.12 -Port 25, 2525, 443, 445, 135, 808,587
Target RemoteAddress Port Status
—— ————- —- ——
192.188.1.12 192.188.1.12 25 True
192.188.1.12 192.188.1.12 2525 True
192.188.1.12 192.188.1.12 443 True
192.188.1.12 192.188.1.12 445 True
192.188.1.12 192.188.1.12 135 True
192.188.1.12 192.188.1.12 808 True
192.188.1.12 192.188.1.12 587 True
Is the output indicating that the test is between 192.188.1.10 and 192.188.1.12?
If so, I now understand, although the output is somewhat confusing with listing the same exact “Destination IP” twice. Would the output not be more clear if it listed the Source IP (.10) and the Destination IP (.12), along with the Port & Port Status?
Thanks again for sharing your wisdom here, I really appreciate it!
LikeLiked by 2 people
Target and remote address can be different. Consider that cnn.com is reachable via multiple ip addresses, huh?
LikeLike
Sorry. I didn’t find it., Can you send the link?
LikeLike
Remember that my script cannot replace more comprehensive tools like nmap.
LikeLike
apologies for all the newbie questions – PowerShell isn’t my strong suit, obviously 😉
You mention that the Target & Remote addresses can be different. Can you share the command that you would use to specify different IP addresses?
In your example: Test-OpenPort -Target 192.168.0.1 -Port 80
I understand how to specify the -Target, but I don’t understand how to specify the Remote IP. Trying to enter -Remote and tabbing out doesn’t seem to allow me to specify a Remote IP.
For example, I tried entering: Test-OpenPort -Target 192.168.1.10 -RemoteAddress 192.168.1.12 -Port 80, but that’s an invalid command.
LikeLike
There are only two parameter Target and port. Target can be IP or name. That’s It. No more options. If you need more possibilities better go for nmap. It is more user friendly.
LikeLike
Thanks again, Patrick – last question for you:
Can you share the command that you would use to test port connectivity (port 25) between 192.168.1.10 & 192.168.1.12, using your script?
LikeLike
Not possible. Only localhost to remote ip as shown in the screens.
LikeLike
Hi Patrick, This was a great function & helped me with testing multiple servers, Thank you, However, is there a way that I can put the IPs into a variable & then run it? i have 753 Ips that i have to run a port test against, is there a way to make it simpler instead of just ip1,ip2,ip3?
LikeLike
You should be able to run it against your variable or text file (Get-Content)
LikeLike
I mean port on target is open.
LikeLike
Thank you for taking the time to create and share this script!! When this reports that a port is “True” does that mean that communication between the source and target can use the port in both directions (e.g. of port 139 is reporting true source server can send information to the target on port 139 and also the target server can send information back to the source server on the same port. Also can this be used for UDP ports? THANK YOU AGAIN!!!!
LikeLike
That only means that the port is open. No UDP Scan.
LikeLike