How to get a free/open local port on Win10 / powerhsell for ssh forwarding

Question:

I come from a Unix world and want to do ssh port forwarding ssh -L on a Windows 10 machine.
I have a working solution with a python one-liner.
Now I wanted to ask the Powershell-users how to elegantly do this on pure powershell

$LOCALPORT=$(python -c "import socket; s=socket.socket(); s.bind(('',0)); print(s.getsockname()[1]); s.close()")

To give you some framing, it would run in a script like this:

$USER="USERNAME"
$REMOTEHOST="REMOTEHOST"
$LOCALIP=$(Get-NetAdapter -Name "WiFi" | Get-NetIPAddress).IPv4Address
$LOCALPORT=$(python -c "import socket; s=socket.socket(); s.bind(('',0)); print(s.getsockname()[1]); s.close()")
$REMOTEIP=ssh $USER@$REMOTEHOST "cat `$HOME/var/ip|cut -d`':`' -f1"
$REMOTEPORT=ssh $USER@$REMOTEHOST "cat `$HOME/var/ip|cut -d`':`' -f2"
Start-Job ssh -L $LOCALIP`:$LOCALPORT`:$REMOTEIP`:$REMOTEPORT $USER@$REMOTEHOST -N -v -v -v
sleep 5
Asked By: Jona Engel

||

Answers:

You can try this:

$usedPorts = (Get-NetTCPConnection | select -ExpandProperty LocalPort) + (Get-NetUDPEndpoint | select -ExpandProperty LocalPort)
5000..60000 | where { $usedPorts -notcontains $_ } | select -first 1

Get-NetTCPConnection and Get-NetUDPEndpoint both return current connections and we just need LocalPort.
Next line iterates from 5000 to 60000 and checks if the port number is not used. Last part of the pipe returns the first result.

EDIT

I just found out that you can also use this to get currently used ports:

$usedPorts = (Get-NetTCPConnection).LocalPort + (Get-NetUDPEndpoint).LocalPort

This syntax is called member enumeration and is available since PowerShell v3.
You can read more about it here: https://stackoverflow.com/a/48888108/5805327

Answered By: mcbr
Categories: questions Tags: , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.