Create a TCP/UDP port listener using PowerShell

One of our customers is securing his network and firewall changes were made that needed to be tested. In this case, the new servers were not deployed in that specific network yet. But… We did want to test the connections before deploying the servers 🙂 In this blog post, I will show you a way how to create listening ports on a machine in order to test the connection from another network using netcat on Linux or portqry on Windows.

Preparation

In this case, we are using netcat and portqry as our testing tools depending on the Operating System you’re using. Follow the procedure below to install it on your system.

Windows

Download portqry here (Direct link) and save PortQryV2.exe to a temporary location. Run it and extract the files somewhere on the system that you’re going to use to test the ports, it can test both TCP and UDP.

Linux

Depending on what Linux flavor you’re running, the installation could be different than the command line below in which I install it on a Ubuntu machine using apt get

sudo apt install netcat

Starting a listener

After running the command below in a PowerShell prompt from within the directory in which you saved the script, the New-Portlistener PowerShell function is available in your session (Alternatively you could run it from PowerShell ISE)

. .\New-Portlistener

Now that the function is available, you can start a TCP listener on port 9001 for example by running this command:

New-Portlistener -UDPPort 9001

After running, you will see this output on your screen:

You can press Escape to stop the listener and it should show this as output:

Stopped listening on UDP port 9001

If you are trying to start a listener which is already active, it will show an error (In this example I used TCP port 3389 which is the default RDP port)

WARNING: TCP Port 3389 is already listening, aborting...

Note: Windows Firewall could give pop-ups when starting the listener

Checking the ports

If you have a TCP or UDP listener port running on a Windows machine, then you can start testing the connection to it from a Windows or Linux machine in another network.

Linux

UDP

To use netcat for checking a UDP connection, you can use this to test port 9001 on IP address 10.20.30.40:

nc -z -v -u 10.20.30.40 9001

When the connection is successful, the screen output is:

Connection to 10.20.30.40 9001 port [udp/*] succeeded!

TCP

To use netcat for checking a TCP connection, you can use this to test port 9001 on IP address 10.20.30.40:

nc -z -v 10.20.30.40 9001

When the connection is successful, the screen output is:

Connection to 192.168.168.121 9001 port [tcp/*] succeeded!

Windows

UDP

To use PortQry.exe for checking a UDP connection, you can use this to test port 9001 on IP address 10.20.30.40:

portqry -n 10.20.30.40 -e 9001 -p UDP

When the connection is successful, the screen output is:

UDP port 9001 (unknown service): LISTENING or FILTERED

In the PowerShell session, you can also see if the connection was successful. It will show you a PortQry Test Message:

10.20.30.40:61199 PortQry Test Message

TCP

To use PortQry.exe for checking a TCP connection, you can use this to test port 9001 on IP address 10.20.30.40:

portqry -n 10.20.30.40 -e 9001 -p TCP

When the connection is successful, the screen output is:

TCP port 9001 (unknown service): LISTENING

The script

Below is the script, you can save it on the system on which you want to start a TCP or UDP listener on.

function New-Portlistener {
    param (
        [parameter(Mandatory = $false, HelpMessage = "Enter the tcp port you want to use to listen on, for example 3389")]
        [ValidatePattern('^[0-9]+$')]
        [ValidateRange(0, 65535)]
        [int]$TCPPort,

        [parameter(Mandatory = $false, HelpMessage = "Enter the udp port you want to use to listen on, for example 3389")]
        [ValidatePattern('^[0-9]+$')]
        [ValidateRange(0, 65535)]
        [int]$UDPPort
    )
    
    #Exit if both options were used
    if ($TCPPort -and $UDPPort) {
        Write-Warning ("You can only specify one option, use either TCPPort or UDPPort. Aborting...")
        return
    }

    #Test if TCP port is already listening port before starting listener
    if ($TCPPort) {
        $Global:ProgressPreference = 'SilentlyContinue' #Hide GUI output
        $testtcpport = Test-NetConnection -ComputerName localhost -Port $TCPPort -WarningAction SilentlyContinue -ErrorAction Stop
        if ($testtcpport.TcpTestSucceeded -ne $True) {
            Write-Host ("TCP port {0} is available, continuing..." -f $TCPPort) -ForegroundColor Green
        }
        else {
            Write-Warning ("TCP Port {0} is already listening, aborting..." -f $TCPPort)
            return
        }

        #Start TCP Server
        #Used procedure from https://riptutorial.com/powershell/example/18117/tcp-listener
        $ipendpoint = new-object System.Net.IPEndPoint([ipaddress]::any, $TCPPort) 
        $listener = new-object System.Net.Sockets.TcpListener $ipendpoint
        $listener.start()
        Write-Host ("Now listening on TCP port {0}, press Escape to stop listening" -f $TCPPort) -ForegroundColor Green
        while ( $true ) {
            if ($host.ui.RawUi.KeyAvailable) {
                $key = $host.ui.RawUI.ReadKey("NoEcho,IncludeKeyUp,IncludeKeyDown")
                if ($key.VirtualKeyCode -eq 27 ) {	
                    $listener.stop()
                    Write-Host ("Stopped listening on TCP port {0}" -f $TCPPort) -ForegroundColor Green
                    return
                }
            }
        }
    }
        
    
    #Test if UDP port is already listening port before starting listener
    if ($UDPPort) {
        #Used procedure from https://cloudbrothers.info/en/test-udp-connection-powershell/
        try {
            # Create a UDP client object
            $UdpObject = New-Object system.Net.Sockets.Udpclient($UDPPort)
            # Define connect parameters
            $computername = "localhost"
            $UdpObject.Connect($computername, $UDPPort)    
        
            # Convert current time string to byte array
            $ASCIIEncoding = New-Object System.Text.ASCIIEncoding
            $Bytes = $ASCIIEncoding.GetBytes("$(Get-Date -UFormat "%Y-%m-%d %T")")
            # Send data to server
            [void]$UdpObject.Send($Bytes, $Bytes.length)    
        
            # Cleanup
            $UdpObject.Close()
            Write-Host ("UDP port {0} is available, continuing..." -f $UDPPort) -ForegroundColor Green
        }
        catch {
            Write-Warning ("UDP Port {0} is already listening, aborting..." -f $UDPPort)
            return
        }

        #Start UDP Server
        #Used procedure from https://github.com/sperner/PowerShell/blob/master/UdpServer.ps1
        $endpoint = new-object System.Net.IPEndPoint( [IPAddress]::Any, $UDPPort)
        $udpclient = new-object System.Net.Sockets.UdpClient $UDPPort
        Write-Host ("Now listening on UDP port {0}, press Escape to stop listening" -f $UDPPort) -ForegroundColor Green
        while ( $true ) {
            if ($host.ui.RawUi.KeyAvailable) {
                $key = $host.ui.RawUI.ReadKey("NoEcho,IncludeKeyUp,IncludeKeyDown")
                if ($key.VirtualKeyCode -eq 27 ) {	
                    $udpclient.Close()
                    Write-Host ("Stopped listening on UDP port {0}" -f $UDPPort) -ForegroundColor Green
                    return
                }
            }

            if ( $udpclient.Available ) {
                $content = $udpclient.Receive( [ref]$endpoint )
                Write-Host "$($endpoint.Address.IPAddressToString):$($endpoint.Port) $([Text.Encoding]::ASCII.GetString($content))"
            }
        }
    }
}

Download the script(s) from GitHub here

4 thoughts on “Create a TCP/UDP port listener using PowerShell

  1. Pingback: (강추)PowerShell을 사용하여 TCP/UDP 포트 열기(Linux는 netcat 사용) – The PowerShell of Windows

  2. Seems a bit overly complicated to achieve what PS does natively already:
    a) To open/close a Tcp port listner:

    $Listener = [System.Net.Sockets.TcpListener]9999;
    $Listener.Start();
    #wait, try connect from another PC etc.
    $Listener.Stop();

    b) to test port:
    Test-NetConnection <IP/NAME > -port

    • I wanted to create a function to easily create TCP and UDP listeners which you can leave running until done testing and at that point pres Esc to stop.I also added some error handling and that makes the script somewhat larger then just starting a listener 😉

      For me it’s also something that I could give to a colleague with little PowerShell experience, a PowerShell Function is easier for them…

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.