Windows双网卡自动切换脚本实战:路由表、DNS与批处理/PowerShell实现 📅 发布时间:2026/9/16 20:58:13 👁 浏览次数: 1. 双网卡切换为什么值得写个脚本1.1 最常见的几类双网卡场景我做了多年桌面运维和网络支持遇到“双网卡”的频率比想象中高得多。最常见的是三类场景。第一类是内网和外网隔离。办公网里存着内部系统、文件服务器、打印机另一张网卡接的是宽带或手机开的热点用于互联网访问。有些团队为了安全要求明确规定这两条链路不能同时在线员工每天要在两种模式之间来回切。第二类是研发和测试环境。机器一台连着办公网络另一张无线网卡要连到设备调试网段或者连到一台临时搭的路由器上每次切换都涉及 IP、网关、DNS 全套参数。第三类是有线和无线互为备份。无线信号不稳定时切到有线有线被拔掉时切回无线虽然不频繁但一旦要切通常都是赶时间的时候。不管是哪类场景本质问题都一样一台电脑上有两张可用网卡但同一时刻只能以其中一种网络配置作为主链路。命令行脚本存在的意义就是把“禁用一块网卡、启用另一块、重置路由、刷新 DNS、验证连通性”这一连串操作合并成一次执行。1.2 手动切网到底慢在哪在图形界面里手动切换一次步骤大致是这样的右键网络图标、进入网络适配器选项、找到目标网卡、右键禁用或启用、再进入 IPv4 属性、改 IP 和网关、有时还要改 DNS、最后打开命令行执行ipconfig /flushdns。整套流程顺利的话也要一分钟稍微一犹豫或者系统网络服务卡一下三五分钟都很正常。比慢更麻烦的是容易出错。公司内部网络如果用的静态 IP你得记住那串数字如果 DHCP 获取还要等它超时。最恼火的是两张网卡都处于启用状态时系统会同时看到两个默认网关它可能继续走旧的网卡结果就是你感觉自己切过去了实际上访问内网资源还是不通。这种状态特别难排查因为你刚改完 IP桌面右下角的网络图标看起来是正常的但路由表里早就乱套了。1.3 脚本化能解决什么把切换动作写进脚本后解决的问题不只是快。更关键的是确定性。每次执行都是同一套参数、同一个顺序不会因为手抖改错一位 IP切换完还能自动验证通了就在屏幕上显示结果没通则提示失败。再有就是可以交给别人执行。很多同事对网络设置并不熟他们只需要双击一个切换入口然后告诉我切完了剩下的事由脚本保证。所以我不建议用临时的“手输命令”来应对高频切换。整理成脚本本质上是把一次性的操作变成可重复、可维护、可交接的资产。2. 动手前先搞懂路由表和网络优先级2.1 电脑是怎么决定数据走哪张网卡的要理解双网卡切换必须先看路由表。很多人以为切换网卡就是“启用哪块用哪块”实际上操作系统是查路由表来决定数据包交给哪块网卡的。在命令行里输入route print -4你会看到一张 IPv4 路由表核心是这么几列网络目标 网络掩码 网关 接口 跃点数 0.0.0.0 0.0.0.0 192.168.1.1 192.168.1.100 35 0.0.0.0 0.0.0.0 10.10.20.1 10.10.20.5 30 10.10.20.0 255.255.255.0 On-link 10.10.20.5 276 192.168.1.0 255.255.255.0 On-link 192.168.1.100 291其中0.0.0.0那两条是默认路由代表“所有不知道往哪走的数据包都交给它”。如果两条默认路由同时存在系统会优先选择“跃点数”更小的那条。比如上面表格里走内网网关的默认路由跃点数是 30走外网网关的是 35那么所有上网流量会优先走内网。听起来可能没问题但假如你现在想访问互联网流量却被送往内网网关内网网关没有互联网出口数据就丢了。所以双网卡切换脚本里的一项重要工作就是管理默认路由。要么把不需要的默认路由删掉要么把目标网卡的默认路由跃点数调成最小确保切完之后默认流量只会走当前想要走的那张网卡。2.2 网卡状态、IP 配置、路由跃点有什么关系三者其实是联动的。禁用一块网卡后它的所有路由条目都会从路由表里消失启用网卡后系统会根据网卡上配置的 IP、子网掩码、网关自动生成直连路由和默认路由。也就是说只改路由理论上是可行的但网卡状态不改变系统可能会在某个时刻因为 DHCP 续租或网络状态变化重新生成一条你不想看到的路由。手动切换最容易漏掉的就是这一点。你在网络连接面板里把有线网卡禁用了但无线网卡迟迟没拿到地址或者默认路由还残留着有线网卡的信息网络状态就会很混乱。脚本的做法通常是一套组合拳先禁用当前不需要的网卡再启用目标网卡然后清理默认路由最后手动添加一条稳定的默认路由并指定它的跃点数。顺带说一下移动网络的自动跃点机制。Windows 默认会给接口开启自动跃点系统根据链路速度等参数自动计算。这很方便但在双网卡场景下自动计算的结果不一定符合你的期望所以脚本里最好手动指定跃点数。跃点数只表示优先级数字不一定是越小越“快”它只是让系统知道哪条路由优先使用。2.3 为什么切换后经常出现“网络假通”最常见的“假通”现象是右下角网络图标显示已连接但访问公司内网服务器超时。原因多半是默认路由还指在不该指的网卡上或者 DNS 用的还是另一张网卡下发的地址。DNS 这个问题很隐蔽。即使你把默认路由切过去了如果网卡上配置的 DNS 还是旧网络下的地址解析域名时还是会失败。所以我的脚本里一般都会顺手把 DNS 也设好或者至少执行一次ipconfig /flushdns清理缓存。切换后验证不要只 ping 网关还要同时验证 DNS 解析和实际访问才能真正确认“切换成功”。3. 方案选型批处理还是 PowerShell3.1 两种脚本怎么选写 Windows 下的命令行脚本主要就两个选择传统批处理.bat/.cmd和 PowerShell.ps1。我做过一个对比方便你按自己的环境来选对比项批处理PowerShell系统兼容性Windows 7 到 11 都很好Windows 7 SP1 之后可用但越新的系统越友好语法复杂度简单直接容易上手初看比较复杂但逻辑更清晰错误处理弱出错继续往下走强可以 catch 异常网卡操作靠netsh间接操作有专门的NetAdapter模块适合人群老运维、快速写小工具有条件写更复杂逻辑的人如果你只是需要“双击运行、马上切换”批处理完全够用。但如果你想做更复杂的判断比如“先 ping 网关通了才切换”或者“切换失败自动回滚”PowerShell 写起来更顺手。我的建议是老机器、老系统上部署优先批处理自己维护的机器或者公司标准环境是 Windows 10 以上直接上 PowerShell后续扩展空间更大。3.2 先把环境信息摸清楚写脚本之前必须先确认三件事网卡叫什么名字、当前 IP 网段是什么、路由表和接口索引长什么样。看网卡名称最直接的方式是Get-NetAdapterGet-NetAdapter | Format-Table Name, InterfaceDescription, Status, LinkSpeed中文系统里有线网卡通常叫“以太网”无线网卡通常叫“WLAN”英文系统一般叫Ethernet和Wi-Fi。这个名字不固定取决于网卡驱动和系统设置。建议在脚本里写成变量方便以后改。查看路由表和接口索引用route print -4开头部分会列出所有接口列表里面会有每个接口的 IDX 编号比如接口列表 12...a1 b2 c3 d4 e5 f6 ......Intel(R) Ethernet Connection 8...11 22 33 44 55 66 ......Intel(R) Dual Band Wireless-AC 8265这个 IDX 编号在后面指定路由时必须用到。3.3 权限和脚本执行策略提前准备好修改网卡状态和路由表必须要有管理员权限。直接双击批处理通常会用普通权限跑所以脚本内部最好第一件事就检查权限没有权限就直接退出别让它执行到一半报一堆不明不白的错。PowerShell 还有一层执行策略限制。默认情况下.ps1文件可能会被系统拦截运行报错“因为在此系统上禁止运行脚本”。解决办法是给当前用户放开限制但没必要改成不受限制用这个命令就够了Set-ExecutionPolicy RemoteSigned -Scope CurrentUser设置完以后本地创建的脚本可以运行从网上下载的脚本如果没签名则会被拦截兼顾安全和便利。这些前置工作都说清楚以后就可以进入正题写脚本了。4. 完整脚本实现与关键参数说明4.1 批处理版适合快速部署的一键切换脚本先给出一个可以直接用的批处理版本。这个脚本实现“内网模式”和“外网模式”的切换假设有线网卡叫“以太网”无线网卡叫“WLAN”内网网关是 10.10.20.1外网网关是 192.168.1.1。保存时注意中文系统下批处理建议用 GBK 编码保存避免注释和提示文字乱码。echo off chcp 65001 nul net session nul 21 if %errorlevel% neq 0 ( echo 请以管理员身份运行本脚本。 pause exit /b 1 ) set MODE%1 if %MODE% ( echo 用法: switch-net.bat [intranet^|internet] pause exit /b 1 ) if /i %MODE%intranet ( echo 正在切换到内网模式... netsh interface set interface WLAN disabled netsh interface set interface 以太网 enabled route delete 0.0.0.0 mask 0.0.0.0 route add 0.0.0.0 mask 0.0.0.0 10.10.20.1 metric 20 ipconfig /flushdns nul echo 内网模式切换完成。 ) else if /i %MODE%internet ( echo 正在切换到外网模式... netsh interface set interface 以太网 disabled netsh interface set interface WLAN enabled route delete 0.0.0.0 mask 0.0.0.0 route add 0.0.0.0 mask 0.0.0.0 192.168.1.1 metric 20 ipconfig /flushdns nul echo 外网模式切换完成。 ) else ( echo 未知模式: %MODE% echo 用法: switch-net.bat [intranet^|internet] ) pause这里有两处关键点。第一处是route delete 0.0.0.0 mask 0.0.0.0它会删掉当前所有默认路由。注意如果你有多张网卡同时在线删除默认路由后所有网卡的默认路由都会被删掉然后再统一添加一条我们想要的。第二处是route add 0.0.0.0 mask 0.0.0.0 10.10.20.1 metric 20这里的metric 20会让这条路由有比较高的优先级。如果你还需要同时保留另一张网卡的直连网段访问可以追加静态路由但大多数人只是切主链路所以默认路由覆盖掉就够了。4.2 PowerShell 版逻辑更清晰适合扩展PowerShell 版本对初学者稍难一点但可读性和可维护性明显更好。脚本同样实现两种模式并把网卡名和路由参数抽成变量以后改起来不用翻到命令中间去找。param( [Parameter(Mandatory$true)] [ValidateSet(intranet, internet)] [string]$Mode ) $ErrorActionPreference Stop $admin ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole( [Security.Principal.WindowsBuiltInRole]::Administrator ) if (-not $admin) { Write-Host 请以管理员身份运行 -ForegroundColor Red exit 1 } $Ethernet 以太网 $Wlan WLAN switch ($Mode) { intranet { Disable-NetAdapter -Name $Wlan -Confirm:$false Enable-NetAdapter -Name $Ethernet -Confirm:$false Get-NetRoute -DestinationPrefix 0.0.0.0/0 | Remove-NetRoute -Confirm:$false New-NetRoute -DestinationPrefix 0.0.0.0/0 -InterfaceAlias $Ethernet -NextHop 10.10.20.1 -RouteMetric 20 Set-DnsClientServerAddress -InterfaceAlias $Ethernet -ServerAddresses 10.10.20.1 Clear-DnsClientCache Write-Host 已切换到内网模式 -ForegroundColor Green } internet { Disable-NetAdapter -Name $Ethernet -Confirm:$false Enable-NetAdapter -Name $Wlan -Confirm:$false Get-NetRoute -DestinationPrefix 0.0.0.0/0 | Remove-NetRoute -Confirm:$false New-NetRoute -DestinationPrefix 0.0.0.0/0 -InterfaceAlias $Wlan -NextHop 192.168.1.1 -RouteMetric 20 Set-DnsClientServerAddress -InterfaceAlias $Wlan -ServerAddresses 223.5.5.5 Clear-DnsClientCache Write-Host 已切换到外网模式 -ForegroundColor Green } }PowerShell 的优势集中在三处ValidateSet限制了参数只能填intranet或internet少敲错一个字母Disable-NetAdapter和Enable-NetAdapter这类命令比netsh interface set更直观$ErrorActionPreference Stop让脚本在出错时停下而不是蒙着头继续跑。有一点需要特别说明如果脚本要放在共享位置或者作为计划任务运行注意网卡名的空格和中文-InterfaceAlias直接用字符串就行不用转义。另外New-NetRoute的-NextHop是网关地址-RouteMetric是跃点数这两个参数和批处理版里的route add是对应的。4.3 route add 里的 if 和 metric 到底怎么填很多人第一次看route add的帮助文档会被if参数弄晕。它的作用是指定路由绑定到哪个接口。在某些情况下不写if也可以但那是系统有明确的“最优接口”时才可靠在双网卡竞争时一定要显式指定否则即使网关是对的系统也可能把数据包交给错误的网卡。怎么看接口索引执行route print -4最上方就有接口列表。假设有线网卡接口索引是 12那么添加内网默认路由的命令可以写成route add 0.0.0.0 mask 0.0.0.0 10.10.20.1 if 12 metric 20metric在 Windows 中默认是自动计算的但手动指定能确保优先级。逻辑上你想要用的网卡跃点数设小一点不常用的网卡跃点数设大一点。这样即使两块网卡都开着系统也会优先走你要的那条默认路由。如果觉得接口索引在重启后可能变化可以在批处理里先用netsh interface ip show config查看当前名称再配合route print人工核对。更一劳永逸的做法是直接给网卡命名固定比如把有线网卡改名为LAN无线网卡改名为WIFI脚本里就用这两个名称。4.4 加日志、加提示、加隐藏运行脚本跑起来没有反馈是最容易被忽略的问题。我习惯在批处理里输出一条时间戳日志echo [%date% %time%] 切换到内网模式 D:\scripts\net-switch.logPowerShell 版本可以用Add-ContentAdd-Content -Path D:\scripts\net-switch.log -Value [$(Get-Date)] 切换到 $Mode 模式日志不用写得很复杂记录“什么时候、切到了什么模式”就够了。万一以后有人问你“网络是谁弄坏的”翻一下日志立刻能定位。再有一个实用技巧是隐藏运行窗口。如果脚本是通过计划任务触发或者你想做成一个完全无感的双击工具不希望命令行窗口一直弹出来可以用一个 VBS 脚本包裹执行窗口模式设为 0Set ws CreateObject(Wscript.Shell) ws.Run powershell -NoProfile -ExecutionPolicy Bypass -File D:\scripts\switch-net.ps1 intranet, 0, True把这段存成switch-intranet.vbs双击时 PowerShell 窗口不会闪出来但会静默执行。注意这里用了0表示隐藏窗口True表示等待执行完成后再退出。缺点是一旦出错你也不知道发生了什么所以隐藏运行的方案最好搭配日志一起用。5. 实战操作流程从部署到验证5.1 一个典型测试环境为了把整个流程讲清楚我以手头一台测试笔记本为例它的环境长这样网卡网络类型IP 配置网关DNS以太网内网办公静态 IP 10.10.20.5/2410.10.20.110.10.20.1WLAN互联网DHCP 自动获取192.168.1.1223.5.5.5目标模式也很清晰切到“内网模式”时停用无线网卡启用有线网卡默认路由指到内网网关切到“外网模式”时停用有线网卡启用无线网卡默认路由指到路由器网关。这样设计模式的好处是不会冲突因为同时只有一张网卡在线。5.2 部署脚本的具体步骤第一步在D:\scripts目录下创建switch-net.ps1把上面的 PowerShell 脚本保存进去。第二步给当前用户开放执行策略Set-ExecutionPolicy RemoteSigned -Scope CurrentUser第三步建一个桌面快捷方式目标填powershell -NoProfile -ExecutionPolicy Bypass -File D:\scripts\switch-net.ps1 intranet第四步快捷方式属性里勾选“以管理员身份运行”。这一步很容易漏如果你不想每次弹 UAC可以在计划任务里创建一个“交互式登录时运行”的任务用最高权限运行再在快捷方式里直接指向这个计划任务。这样体验最顺滑但配置成本稍微高一点。给同事使用时我会再顺手做一个“外网模式”的快捷方式对应internet参数两个入口清清楚楚。5.3 切换后的验证别只 ping 一下脚本跑完不代表一定成功验证要分层做。我一般按顺序执行这几条命令ipconfig /all route print -4 ping 10.10.20.1 ping 223.5.5.5 nslookup www.example.com第一次验证是看网卡状态确认目标网卡已经启用IP 和网关对不对。第二次是看默认路由确保0.0.0.0指向我们想要的网关并且只有一条默认路由。第三次验证网关连通性第四次验证互联网连通性。最后再用nslookup验证 DNS 解析。如果ping网关通了但nslookup失败问题多半出在 DNS 上回到脚本里检查Set-DnsClientServerAddress这段。如果你在公司内部内网访问往往不只是通过默认路由还可能需要访问多个内网网段。这时候就要在脚本里追加静态路由比如route add 172.16.0.0 mask 255.240.0.0 10.10.20.1 metric 20追加之后不仅内网网关所在网段可以通整个 172.16.0.0/12 网段也能通过内网网关访问不影响默认路由指向互联网。5.4 切换失败时怎么快速回退脚本执行到一半报错最怕的是网卡被禁用后无法恢复。我的经验是准备一个“恢复出厂”小脚本里面只有两行命令netsh interface set interface 以太网 enabled netsh interface set interface WLAN enabled不管当前处于什么状态先把两块网卡都启用然后重新进入图形界面检查 IP 和网关至少能保证设备从一个可操作的状态重新开始。如果是因为手动配置了错误的静态 IP 导致无法上网可以直接把网卡改成 DHCP 获取再让它重新拿地址。另外提醒一句如果你通过远程桌面或 SSH 连接到那台机器千万别贸然禁用当前正在使用的网卡否则远程连接会立刻断开。脚本里加一个确认提示也行或者明确告诉使用者“切换后远程连接会断一下需要用另一张网卡的地址重新连接”。6. 常见问题与排查技巧实录6.1 问题速查表把实践中高频出现的问题整理成一张速查表比抱着文档翻舒服得多。问题现象常见原因排查与解决办法提示需要管理员权限脚本没有用管理员身份运行右键脚本选择“以管理员身份运行”或检查计划任务最高权限网卡名称识别不了系统中网卡名不是“以太网”/“WLAN”执行Get-NetAdapter确认实际名称修改脚本变量route add 报参数错误网关不可达或缺少 if 参数先确认网关地址再用route print -4找到接口索引并显式填写切换后网页打不开默认路由残留或 DNS 配置错误执行route print -4检查默认路由重新设置 DNSipconfig /flushdns远程连接突然断开脚本禁用了当前正在使用的网卡不要禁用远程会话所在的网卡改用另一张网卡地址重新连接PowerShell 提示禁止运行脚本执行策略限制执行Set-ExecutionPolicy RemoteSigned -Scope CurrentUser杀毒软件拦截 netsh/route安全软件对系统命令敏感添加白名单或改用权限更细分的 PowerShell 命令6.2 我踩过的几个坑第一个坑是批处理编码。中文系统下如果脚本用 UTF-8 保存运行时的中文提示会出现乱码。解决办法是把文件开头写成chcp 65001 nul同时用 UTF-8 编码保存或者干脆保持系统默认的 GBK 编码去掉chcp那行。两种方式都能用最怕的是编码和代码页不匹配。第二个坑是 DHCP 重新分配路由。有的环境里无线网卡启用的瞬间会从路由器拿到默认网关自动生成一条默认路由即使你后面执行了route delete 0.0.0.0 mask 0.0.0.0它可能在几秒后又冒出来。应对办法是脚本最后加一次验证发现多余默认路由再删一次。第三个坑是网卡名里有空格或者怪异字符尤其是某些 USB 无线网卡名字可能叫“Wireless LAN adapter WLAN 2”。在批处理里双引号括起来问题不大但如果写进 PowerShell 命令里一定要用变量统一管理避免手滑打错。6.3 进一步自动化检测网络质量以后自动切换脚本写好了还可以更进一步。有些人希望“断开无线就自动切有线有线断了就自动切无线”这时候单个切换脚本是不够的需要加一个检测循环。思路很简单脚本先 ping 当前主链路的网关如果连续失败就自动调用另一个模式的切换函数。在 PowerShell 里可以用一个while循环加Test-Connection实现但注意不要写得太激进否则网卡频繁切换反而会影响使用。以我的经验每 30 秒检测一次连续失败 3 次再触发切换体验比较稳定。这个方案适合对网络可用性要求不高的办公场景如果业务系统依赖固定 IP 和固定网关自动切换可能带来更多问题还是手动点一下更可靠。最后再分享一个很小的实战习惯我在脚本开头都会加一句echo 当前时间: %date% %time%窗口里留下执行痕迹。下次任何人问“你是不是切过网络”只要把命令行历史或者日志拉出来一眼就能确认。工具再自动化也得保留可追踪的记录这是团队协作里最值钱的一环。