<# .SYNOPSIS 双网卡内外网协同管理与一键分流配置工具 .DESCRIPTION 用于同时连接外网(互联网)与内网(单位/医院专网)的自动分流配置。 支持自动提权、自动识别网卡与网关、永久路由写入、代理白名单设置、网络诊断与一键还原。 #> [CmdletBinding()] param ( [Parameter(Mandatory = $false)] [ValidateSet("Setup", "Status", "Restore", "Menu")] [string]$Action = "Menu" ) # 确保控制台支持 UTF-8 编码 try { chcp 65001 | Out-Null [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 $OutputEncoding = [System.Text.Encoding]::UTF8 } catch {} # 引入 MAX 公共函数库(若存在) $Common = "C:\Setup\windows\lib\common.ps1" if (Test-Path $Common) { . $Common } # 兼容备用 UI 输出函数(确保独立运行或无 common.ps1 时依然拥有统一视觉) if (-not (Get-Command Write-Header -ErrorAction SilentlyContinue)) { function Write-Header { param([string]$Title) Clear-Host Write-Host " ╔══════════════════════════════════════════════════╗" -ForegroundColor DarkYellow Write-Host " ║ [ MAX // $Title ]" -ForegroundColor White Write-Host " ╚══════════════════════════════════════════════════╝" -ForegroundColor DarkYellow Write-Host (" > " + (Get-Date).ToString("yyyy-MM-dd HH:mm:ss") + " // SYSTEM_READY") -ForegroundColor White Write-Host "" } function Write-Section { param([string]$Text) Write-Host "" Write-Host " [:: $Text ::] ─────────────────────────────────" -ForegroundColor DarkYellow } function Write-OK { Write-Host " [+] $($args[0])" -ForegroundColor White } function Write-Warn { Write-Host " [!] $($args[0])" -ForegroundColor Yellow } function Write-Err { Write-Host " [X] $($args[0])" -ForegroundColor Red } function Write-Info { Write-Host (" > " + $args[0]) -ForegroundColor White } function Write-Muted { Write-Host " // $($args[0])" -ForegroundColor Gray } function Pause-Max { Write-Host "" Write-Host " [ENTER] 返回控制台..." -ForegroundColor White Read-Host | Out-Null } function Write-Line { Write-Host " ═══════════════════════════════════════════════════" -ForegroundColor DarkYellow } } # 1. 检查并请求管理员权限 function Assert-Administrator { $currentIdentity = [Security.Principal.WindowsIdentity]::GetCurrent() $principal = New-Object Security.Principal.WindowsPrincipal($currentIdentity) $isAdmin = $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) if (-not $isAdmin) { Write-Warn "当前未处于管理员权限,正在请求提升权限..." $scriptPath = $PSCommandPath if (-not $scriptPath) { $scriptPath = $MyInvocation.MyCommand.Definition } if ($scriptPath -and (Test-Path $scriptPath)) { Start-Process powershell.exe -Verb RunAs -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File "$scriptPath" -Action $Action" exit } else { Write-Err "无法自动提权(当前可能通过管道执行),请以管理员身份重新打开 PowerShell!" return $false } } return $true } # 2. 自动检测网卡信息 function Get-NicInfo { $allAdapters = Get-NetAdapter -ErrorAction SilentlyContinue | Where-Object { $_.Status -eq "Up" } # 识别外网网卡(优先 192.168.*) $wanCandidate = Get-NetIPAddress -AddressFamily IPv4 -ErrorAction SilentlyContinue | Where-Object { $_.IPAddress -like "192.168.*" -and $_.InterfaceAlias -notlike "*Loopback*" } | Select-Object -First 1 # 识别内网网卡(优先 172.16.* ~ 172.31.* 或 10.* 专网段) $lanCandidate = Get-NetIPAddress -AddressFamily IPv4 -ErrorAction SilentlyContinue | Where-Object { ($_.IPAddress -like "172.1[6-9].*" -or $_.IPAddress -like "172.2[0-9].*" -or $_.IPAddress -like "172.3[0-1].*" -or $_.IPAddress -like "10.*") -and $_.InterfaceAlias -notlike "*Loopback*" -and (-not $wanCandidate -or $_.InterfaceAlias -ne $wanCandidate.InterfaceAlias) } | Select-Object -First 1 $wanName = if ($wanCandidate) { $wanCandidate.InterfaceAlias } else { "以太网" } $lanName = if ($lanCandidate) { $lanCandidate.InterfaceAlias } else { "以太网 2" } $wanConfig = Get-NetIPConfiguration -InterfaceAlias $wanName -ErrorAction SilentlyContinue $lanConfig = Get-NetIPConfiguration -InterfaceAlias $lanName -ErrorAction SilentlyContinue $wanIP = if ($wanConfig -and $wanConfig.IPv4Address) { ($wanConfig.IPv4Address | Select-Object -First 1).IPAddress } else { "未知" } $lanIP = if ($lanConfig -and $lanConfig.IPv4Address) { ($lanConfig.IPv4Address | Select-Object -First 1).IPAddress } else { "未知" } $wanGw = if ($wanConfig -and $wanConfig.IPv4DefaultGateway) { ($wanConfig.IPv4DefaultGateway | Select-Object -First 1).NextHop } else { "192.168.1.1" } $lanGw = if ($lanConfig -and $lanConfig.IPv4DefaultGateway) { ($lanConfig.IPv4DefaultGateway | Select-Object -First 1).NextHop } else { "172.16.32.254" } return [PSCustomObject]@{ WanName = $wanName WanIP = $wanIP WanGw = $wanGw LanName = $lanName LanIP = $lanIP LanGw = $lanGw } } # 3. 核心功能:一键配置双网卡分流 function Apply-DualNicConfig { $info = Get-NicInfo Write-Header "双网卡分流配置" Write-Section "1/5 识别适配器与网关" Write-Info "外网适配器: $($info.WanName)" Write-Muted "本机 IP: $($info.WanIP) | 网关: $($info.WanGw)" Write-Info "内网适配器: $($info.LanName)" Write-Muted "本机 IP: $($info.LanIP) | 网关: $($info.LanGw)" Write-Section "2/5 调整网卡跃点数优先级" try { Set-NetIPInterface -InterfaceAlias $info.WanName -AddressFamily IPv4 -InterfaceMetric 10 -AutomaticMetric Disabled -ErrorAction Stop Write-OK "外网跃点数设为 10(高优先级,默认上网流量全走外网)" } catch { Write-Err "设置外网跃点数失败: $_" } try { Set-NetIPInterface -InterfaceAlias $info.LanName -AddressFamily IPv4 -InterfaceMetric 50 -AutomaticMetric Disabled -ErrorAction Stop Write-OK "内网跃点数设为 50(低优先级,避免内网默认路由抢占外网)" } catch { Write-Err "设置内网跃点数失败: $_" } Write-Section "3/5 清理旧静态路由" route delete 10.0.0.0 mask 255.0.0.0 >$null 2>&1 route delete 172.16.0.0 mask 255.240.0.0 >$null 2>&1 Write-OK "旧路由规则已清理 (10.0.0.0/8, 172.16.0.0/12)" Write-Section "4/5 写入永久静态路由 (内网专用)" route -p add 10.0.0.0 mask 255.0.0.0 $info.LanGw metric 10 >$null Write-OK "已添加永久路由: 10.0.0.0/8 -> $($info.LanGw) (覆盖 HRP 业务系统及全部 10.x 内网)" route -p add 172.16.0.0 mask 255.240.0.0 $info.LanGw metric 10 >$null Write-OK "已添加永久路由: 172.16.0.0/12 -> $($info.LanGw) (覆盖 172.16.x.x ~ 172.31.x.x 专网段)" Write-Section "5/5 配置代理白名单与刷新缓存" try { $regPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" $override = ";localhost;127.*;10.*;10.0.0.0/8;10.200.5.92;10.49.209.7;172.16.0.0/12;172.16.*;192.168.*" Set-ItemProperty -Path $regPath -Name "ProxyOverride" -Value $override -ErrorAction SilentlyContinue Write-OK "已将内网及专网 IP 段加入代理白名单(防止代理软件拦截内网)" } catch { Write-Warn "配置代理白名单失败: $_" } try { Clear-DnsClientCache Write-OK "系统 DNS 与网络缓存已成功刷新" } catch { Write-Warn "刷新 DNS 缓存失败: $_" } # 执行连通性测试 Test-NetworkHealth -info $info } # 4. 网络连通性诊断 function Test-NetworkHealth { param($info = (Get-NicInfo)) Write-Section "网络连通性测试" # 外网测试 $testWan = Test-Connection -ComputerName 223.5.5.5 -Count 2 -Quiet -ErrorAction SilentlyContinue if ($testWan) { Write-OK "外网互联网连接正常 (可正常访问网页、微信、外部服务)" } else { Write-Err "外网连接失败,请检查外网网线或 WiFi 连接" } # 内网网关测试 $testLanGw = Test-Connection -ComputerName $info.LanGw -Count 2 -Quiet -ErrorAction SilentlyContinue if ($testLanGw) { Write-OK "内网网关通信正常 ($($info.LanGw))" } else { Write-Err "内网网关无法连通 ($($info.LanGw)),请检查内网网线" } # HRP 系统测试 $testHrp = Test-NetConnection -ComputerName 10.200.5.92 -Port 8080 -WarningAction SilentlyContinue -ErrorAction SilentlyContinue if ($testHrp.TcpTestSucceeded) { Write-OK "HRP 业务系统通信正常 (10.200.5.92:8080)!" } else { Write-Err "HRP 业务系统端口未连通 (10.200.5.92:8080)" } } # 5. 查看当前状态 function Show-NetworkStatus { $info = Get-NicInfo Write-Header "当前网络配置与路由状态" Write-Section "网络适配器状态" Get-NetIPConfiguration -ErrorAction SilentlyContinue | Where-Object { $_.IPv4Address } | ForEach-Object { Write-Info "网卡: $($_.InterfaceAlias)" Write-Muted "IPv4 地址 : $($_.IPv4Address.IPAddress -join ', ')" Write-Muted "默认网关 : $($_.IPv4DefaultGateway.NextHop -join ', ')" Write-Muted "DNS 服务器: $($_.DNSServer.ServerAddresses -join ', ')" } Write-Section "当前内网永久路由表 (Persistent Routes)" $routes = route print 10.* 172.16.* $found = $false $routes | Where-Object { $_ -match "^\s+[0-9]" } | ForEach-Object { Write-OK "$($_.Trim())" $found = $true } if (-not $found) { Write-Muted "暂无 10.* 或 172.16.* 相关永久静态路由" } Test-NetworkHealth -info $info } # 6. 恢复系统默认设置 function Restore-DefaultConfig { $info = Get-NicInfo Write-Header "恢复网络默认设置" Write-Section "恢复网卡跃点数" Set-NetIPInterface -InterfaceAlias $info.WanName -AddressFamily IPv4 -AutomaticMetric Enabled -ErrorAction SilentlyContinue Set-NetIPInterface -InterfaceAlias $info.LanName -AddressFamily IPv4 -AutomaticMetric Enabled -ErrorAction SilentlyContinue Write-OK "已恢复两张网卡的自动跃点数 (AutomaticMetric Enabled)" Write-Section "清理专网静态路由" route delete 10.0.0.0 mask 255.0.0.0 >$null 2>&1 route delete 172.16.0.0 mask 255.240.0.0 >$null 2>&1 Write-OK "已删除内网永久静态路由" Write-Section "刷新系统 DNS 缓存" Clear-DnsClientCache Write-OK "系统 DNS 缓存已刷新" Write-Line Write-OK "网络设置已全部恢复为 Windows 默认状态。" } # 7. 主程序菜单与入口 if (-not (Assert-Administrator)) { return } switch ($Action) { "Setup" { Apply-DualNicConfig } "Status" { Show-NetworkStatus } "Restore" { Restore-DefaultConfig } "Menu" { do { $info = Get-NicInfo Write-Header "双网卡内外网协同管理工具 v2.0" Write-Section "当前网络环境识别" Write-Info "[外网网卡] $($info.WanName) : $($info.WanIP) (网关: $($info.WanGw))" Write-Info "[内网网卡] $($info.LanName) : $($info.LanIP) (网关: $($info.LanGw))" Write-Section "操作菜单" Write-Info "1. 一键配置双网卡协同分流 (推荐,外网上网 + 内网专线)" Write-Info "2. 检测当前网络健康状态与路由诊断" Write-Info "3. 恢复网络为默认设置 (撤销分流设置)" Write-Info "0. 退出工具" Write-Host "" $choice = Read-Host " 请输入选项 [默认: 1]" if ([string]::IsNullOrWhiteSpace($choice)) { $choice = "1" } $choice = $choice.Trim() Write-Line switch ($choice) { "1" { Apply-DualNicConfig; Pause-Max } "2" { Show-NetworkStatus; Pause-Max } "3" { Restore-DefaultConfig; Pause-Max } "0" { Write-OK "已退出双网卡管理工具" break } default { Write-Warn "无效选项,请重新输入" Start-Sleep -Seconds 1 } } } while ($choice -ne "0") } } return