Skip to content

Instantly share code, notes, and snippets.

@dotkebi
Forked from composite/wsl2-network.ps1
Created June 10, 2024 02:10
Show Gist options
  • Save dotkebi/3c26164c26f38d48daf9f8fb75f20c63 to your computer and use it in GitHub Desktop.
Save dotkebi/3c26164c26f38d48daf9f8fb75f20c63 to your computer and use it in GitHub Desktop.
WSL 2 TCP NETWORK FORWARDING, IMPROVED FOR TASK SCHEDULER! ALSO WORKS ON WINDOWS SERVER 2022!
# WSL2 network port forwarding script v1
# for enable script, 'Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope CurrentUser' in Powershell,
# for delete exist rules and ports use 'delete' as parameter, for show ports use 'list' as parameter.
# written by Daehyuk Ahn, Aug-1-2020
# edited by Ukjin Yang, Jun-7-2022 (Windows Server 2022 also works!)
# Improved features: more detailed logs for Task Scheduler, saved IP check, etc.
If ($Args[0] -eq "list") {
netsh interface portproxy show v4tov4;
exit;
}
# If elevation needed, start new process
If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))
{
# Relaunch as an elevated process:
Start-Process powershell.exe "-File",('"{0}"' -f $MyInvocation.MyCommand.Path),"$Args runas" -Verb RunAs
exit
}
# You should modify '$Ports' for your applications
$Ports = (22,80,443,8080)
# log file and saving IP file
$today = [System.DateTime]::Today.ToString("yyyyMMdd")
$logdir = "$PSScriptRoot\logs"
$logfile = "$logdir\wsl2ip_$today.log"
$lastfile = "$logdir\wsl2ip.txt"
# mkdir log folder if not exists
if (-not (Test-Path $logdir -PathType Container)) {
New-Item -Path "$logdir" -ItemType "directory" | Out-Null
}
# Log helper function
function Log-Append {
[CmdletBinding()]
param(
[Parameter()]
[string] $Text
)
$now = [System.DateTime]::Now.ToString("yyyy-MM-dd HH:mm:ss.fff")
Tee-Object -FilePath "$logfile" -Append -InputObject "WSL2IP: [$now] $Text"
}
# Get WSL Interface IP, and get only first IP. (I don't know why multiple IPs registered)
wsl hostname -I | Set-Variable -Name "WslIp"
$WslIp = $WslIp.split(" ")[0]
$found = $WslIp -match '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}';
if (-not $found) {
Log-Append "WSL2 cannot be found. Terminate script."
exit;
}
# Get saved IP for prevent unexpected running.
$OldIp = ""
if (Test-Path $lastfile -PathType Leaf) {
$OldIp = Get-Content "$lastfile"
}
$OldIp = $OldIp.Trim()
if ($WslIp -eq $OldIp) {
Log-Append "WSL2 IP ($WslIp) already bound in port proxy. Terminate script."
exit;
}
# If you got new WSL IP, Go ahead!
Log-Append "Applying WSL IP to port proxy."
# Remove and Create NetFireWallRule
Log-Append "Replacing Firewall rules..."
Remove-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' | Tee-Object -FilePath "$logfile" -Append;
if ($Args[0] -ne "delete") {
New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Outbound -LocalPort $Ports -Action Allow -Protocol TCP | Tee-Object -FilePath "$logfile" -Append;
New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Inbound -LocalPort $Ports -Action Allow -Protocol TCP | Tee-Object -FilePath "$logfile" -Append;
New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Outbound -LocalPort $Ports -Action Allow -Protocol UDP | Tee-Object -FilePath "$logfile" -Append;
New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Inbound -LocalPort $Ports -Action Allow -Protocol UDP | Tee-Object -FilePath "$logfile" -Append;
}
# Add each port into portproxy
Log-Append "Replacing port forwarding any to WSL2 Port..."
$Addr = "0.0.0.0"
Foreach ($Port in $Ports) {
iex "netsh interface portproxy delete v4tov4 listenaddress=$Addr listenport=$Port | Out-Null";
if ($Args[0] -ne "delete") {
iex "netsh interface portproxy add v4tov4 listenaddress=$Addr listenport=$Port connectaddress=$WslIp connectport=$Port | Out-Null";
}
}
# Display all portproxy information
Log-Append "Retrieving port forwarding table..."
netsh interface portproxy show v4tov4 | Tee-Object -FilePath "$logfile" -Append;
# Give user to chance to see above list when relaunched start
If ($Args[0] -eq "runas" -Or $Args[1] -eq "runas") {
Write-Host -NoNewLine 'Press any key to close! ';
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');
}
# Save successful WSL IP to file.
Log-Append "Saving successful IP $WslIp to $lastfile ..."
$WslIp | Out-File -FilePath "$lastfile"
# Preserve WSL service scripts here.
Log-Append "Executing WSL Startup scripts..."
iex "wsl sudo service ssh start" | Tee-Object -FilePath "$logfile" -Append
iex "wsl sudo service cron start" | Tee-Object -FilePath "$logfile" -Append
Log-Append "Done."
Add-Content "$logfile" ""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment