Skip to content

Instantly share code, notes, and snippets.

@hunandy14
Last active September 29, 2025 14:03
Show Gist options
  • Save hunandy14/01fca30548ec12a6d733931c6a2083d8 to your computer and use it in GitHub Desktop.
Save hunandy14/01fca30548ec12a6d733931c6a2083d8 to your computer and use it in GitHub Desktop.
建立 Windows 到 WSL 的端口轉發
<#
.SYNOPSIS
建立 Windows 到 WSL 的端口轉發
.DESCRIPTION
此函數會建立從 Windows IP 到 WSL IP 的端口轉發規則,
允許外部連線透過 Windows 主機連接到 WSL 內的服務。
.PARAMETER ListenPort
Windows 端監聽的端口號
.PARAMETER ConnectPort
WSL 端連接的端口號
.PARAMETER Force
跳過確認提示,直接執行
.EXAMPLE
Set-WSLPortForward -ListenPort 22 -ConnectPort 22
建立 SSH 轉發 (22 → 22)
.EXAMPLE
Set-WSLPortForward -ListenPort 8080 -ConnectPort 80 -Force
建立 HTTP 轉發 (8080 → 80) 並跳過確認提示
.NOTES
需要以管理員權限執行
#>
function Set-WSLPortForward {
[CmdletBinding()]
param(
[Parameter(
Position = 0,
HelpMessage = "Port number for Windows to listen on"
)] [ValidateRange(1, 65535)] [Alias("LP", "Listen")]
[int]$ListenPort,
[Parameter(
Position = 1,
HelpMessage = "Port number to connect to in WSL"
)] [ValidateRange(1, 65535)] [Alias("CP", "Connect")]
[int]$ConnectPort = 22,
[Parameter(
HelpMessage = "Skip confirmation prompt"
)] [Alias("F")]
[switch]$Force
)
# 取得 WSL 主機名稱和 IP 地址
$w = (wsl hostname -I).Split()[0]
$e = (Get-NetIPConfiguration | Where-Object { $_.IPv4DefaultGateway -and $_.NetAdapter.Status -eq "Up" }).IPv4Address.IPAddress | Select-Object -First 1
# 如果 WSL 和 Windows 使用相同的 IP 地址,則不需要轉發
if (!$e -or $w -eq $e) { Write-Host "WSL and Windows share the same IP, no port forwarding needed" -ForegroundColor Yellow; return }
# 顯示轉發規則
Write-Host "`nSetting up port forwarding:" -ForegroundColor Yellow
Write-Host " External connection ${e}:${ListenPort} → Forward to WSL ${w}:${ConnectPort}"
# 等待確認執行 (除非使用 -Force 參數)
if ($Force -or (Read-Host "`nConfirm execution? (Y/N)") -eq 'Y') {
# netsh 透明代理函數
function Invoke-Netsh {
param(
[Parameter(ValueFromRemainingArguments)]
[string[]]$Arguments
)
# 保存原始編碼
$originalEncoding = $global:OutputEncoding
$originalInputEncoding = [console]::InputEncoding
$originalOutputEncoding = [console]::OutputEncoding
# 切換為原始編碼
$global:OutputEncoding=[console]::InputEncoding=[console]::OutputEncoding = [Text.Encoding]::UTF8
# 執行 netsh 命令
try {
$result = & netsh @Arguments 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Error ($result -join "`n"); return
} else { Write-Output $result }
}
# 恢復原始編碼
finally {
$global:OutputEncoding = $originalEncoding
[console]::InputEncoding = $originalInputEncoding
[console]::OutputEncoding = $originalOutputEncoding
}
}
try {
# 刪除現有規則
Invoke-Netsh interface portproxy delete v4tov4 "listenaddress=$e" "listenport=$ListenPort" -ErrorAction Stop
# 建立新的轉發規則
Invoke-Netsh interface portproxy add v4tov4 "listenaddress=$e" "listenport=$ListenPort" "connectaddress=$w" "connectport=$ConnectPort" -ErrorAction Stop
# 顯示轉發規則
Invoke-Netsh interface portproxy show v4tov4
} catch { Write-Error $_ }
} else {
Write-Host "`nOperation cancelled" -ForegroundColor Yellow
}
} # Set-WSLPortForward -ListenPort 22 -ConnectPort 22 -Force
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment