public/interface/portproxy/Add-PortProxy.ps1
#Requires -RunAsAdministrator function Add-PortProxy { <# .SYNOPSIS Adds a new v4tov4 portproxy entry using 'netsh interface portproxy' .DESCRIPTION Adds a new portproxy using netsh. The portproxy feature in Windows enables you to accept TCP connections on a specific interface (or all interfaces) and a specific port, then redirect that connection to another IP and optionally a different port. Effectively this turns your Windows PC into a very simple proxy server. It's important to note that there is no authentication or security associated with the portproxy feature, so all inbound TCP traffic will be sent out to the supplied ConnectAddress unless you have created firewall rules to limit the allowed sources for inbound connections. .EXAMPLE PS C:\> Add-PortProxy -ListenPort 8000 -ConnectAddress 10.1.1.101 Sets up a portproxy in Windows so all connections to all local interfaces on TCP port 8000 will be proxied to 10.1.1.101 on port 8000. .EXAMPLE PS C:\> Add-PortProxy -ListenPort 8000 -ConnectAddress 10.1.1.101 -ConnectPort 8001 -ListenAddress 10.1.1.100 Sets up a portproxy in Windows so all connections to the local interface 10.1.1.100 on TCP port 8000 will be proxied to 10.1.1.101 on port 8001. .EXAMPLE PS C:\> Add-PortProxy -ListenPort 25 -ConnectAddress mail.example.com -ConnectPort 587 -ListenAddress 127.0.0.1 Sets up a portproxy in Windows so all connections to localhost on TCP port 25 will be proxied to mail.example.com on TCP port 587. .OUTPUTS When supplying the PassThru parameter switch, the output will be [PortProxy] with properties 'InternetProtocol', 'ListenAddress', 'ListenPort', 'ConnectAddress', 'ConnectPort' #> [CmdletBinding(SupportsShouldProcess)] [OutputType([PortProxy])] param( # Specifies the TCP port on which to listen for incoming connections. [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateRange(0,65535)] [int] $ListenPort, # Specifies the IP or hostname to which incoming connections should be proxied. [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $ConnectAddress, # Specifies the TCP port to which connections should be proxied. The default will match ListenPort. [Parameter(ValueFromPipelineByPropertyName)] [ValidateRange(0,65535)] [int] $ConnectPort, # Specifies the IP or hostname on which incoming connections should be accepted. The default is '*' which is effectively 0.0.0.0, meaning "listen on all interfaces". [Parameter(ValueFromPipelineByPropertyName)] [string] $ListenAddress, # Pass the newly added portproxy parameters into the pipeline as a [PortProxy] [Parameter()] [switch] $PassThru ) process { if ([string]::IsNullOrWhiteSpace($ListenAddress)) { $ListenAddress = "*" } if (!$PSBoundParameters.ContainsKey('ConnectPort')) { $ConnectPort = $ListenPort } Write-Verbose "Checking existing portproxy entries. . ." foreach ($entry in Get-PortProxy) { if ($entry.ListenAddress -eq $ListenAddress -and $entry.ListenPort -eq $ListenPort) { Write-Error "PortProxy already configured for ListenAddress=$ListenAddress, ListenPort=$ListenPort" return } } Write-Verbose "Checking whether the socket is already in use by another application. . ." $netTcpConnection = Get-NetTCPConnection -LocalAddress $ListenAddress -LocalPort $ListenPort -State Listen -ErrorAction SilentlyContinue if ($null -ne $netTcpConnection) { Write-Error "The socket $($ListenAddress):$($ListenPort) is already in use by PID $($netTcpConnection.OwningProcess)" } $command = "netsh.exe interface portproxy add v4tov4 listenport=$ListenPort connectaddress=$ConnectAddress" if ($PSBoundParameters.ContainsKey("ListenAddress")){ $command += " listenaddress=$ListenAddress" } if ($PSBoundParameters.ContainsKey("ConnectPort")){ $command += " connectport=$ConnectPort" } Write-Verbose "Executing the command '$command'" if ($PSCmdlet.ShouldProcess((hostname), $command)) { $output = Invoke-Expression -Command $command $success = $LASTEXITCODE -eq 0 $output = [string]::Join("`r`n", $output).Trim() if ($success) { Write-Information $output if ($PassThru) { [PortProxy]@{ InternetProtocol = "v4tov4" ListenAddress = $ListenAddress ListenPort = $ListenPort ConnectAddress = $ConnectAddress ConnectPort = $ConnectPort } } } else { Write-Error "Error: $output" } } } } |