双默认网关自动切换批处理脚本优化及命令行输出读取方法问询
双默认网关自动切换批处理脚本优化及命令行输出读取方法问询
首先得说你的原脚本存在几个核心问题:比如没正确捕获ping命令的输出结果(%~1是脚本的参数,根本拿不到ping的返回内容),也没做主网关恢复后切回去的逻辑,而且修改网关时完全没必要重置整个静态IP配置,只需要单独调整默认网关即可。下面给你优化后的实用方案,还有更贴合Windows服务器规范的进阶思路:
一、优化后的批处理脚本
这个脚本会循环检测当前网关的连通性,主网关故障时自动切到副网关,主网关恢复后再切回来,还能避免重复执行无意义的网关修改操作:
@echo off setlocal enableextensions enabledelayedexpansion :: 定义核心网络参数,根据实际环境修改 set "INTERFACE_NAME=Ethernet" set "PRIMARY_GW=172.20.0.1" set "SECONDARY_GW=172.20.0.254" set "PING_COUNT=3" set "CHECK_INTERVAL=10" :: 获取当前默认网关(避免硬编码判断) for /f "tokens=2 delims=:" %%g in ('netsh interface ipv4 show address "%INTERFACE_NAME%" ^| findstr /i "Default Gateway"') do ( set "CURRENT_GW=%%g" :: 去除字符串里的空格 set "CURRENT_GW=!CURRENT_GW: =!" ) :loop echo 当前默认网关: !CURRENT_GW! echo 正在检测网关连通性... :: 用ping结果里的"TTL="判断连通性,通过errorlevel返回值判断是否匹配成功 ping -n %PING_COUNT% !CURRENT_GW! | findstr /i "TTL=" >nul if !errorlevel! equ 0 ( echo 网关!CURRENT_GW!连通正常,保持当前配置 ) else ( echo 网关!CURRENT_GW!连通失败,准备切换到备用网关... :: 判断当前网关类型,切换到另一个 if "!CURRENT_GW!" == "%PRIMARY_GW%" ( netsh interface ipv4 set address "%INTERFACE_NAME%" gateway=%SECONDARY_GW% gwmetric=1 set "CURRENT_GW=%SECONDARY_GW%" echo 已切换到备用网关: %SECONDARY_GW% ) else ( netsh interface ipv4 set address "%INTERFACE_NAME%" gateway=%PRIMARY_GW% gwmetric=1 set "CURRENT_GW=%PRIMARY_GW%" echo 已切换回主网关: %PRIMARY_GW% ) ) echo 等待%CHECK_INTERVAL%秒后再次检测... timeout /t %CHECK_INTERVAL% /nobreak >nul goto loop
脚本关键改进点:
- 自动获取当前默认网关,不用硬编码判断状态
- 通过
findstr匹配TTL=并结合errorlevel判断连通性,比字符串替换更可靠 - 只修改默认网关参数,不重置整个IP配置,操作更轻量化
- 实现双向切换逻辑,主网关恢复后自动切回
二、更专业的服务器端替代方案
如果追求更稳定、更符合Windows服务器网络管理规范的方案,推荐以下两种思路:
1. 静态路由+Metric优先级配置
给两个网关设置不同的Metric值(数值越小优先级越高),主网关设为1,副网关设为10,正常情况下系统会优先使用主网关。脚本只需要监控主网关状态,故障时临时调高主网关的Metric(比如改成20),系统会自动切换到副网关;主网关恢复后再把Metric改回1即可。
示例核心命令:
:: 初始配置:添加双默认路由,主网关优先级更高 route add 0.0.0.0 mask 0.0.0.0 %PRIMARY_GW% metric 1 route add 0.0.0.0 mask 0.0.0.0 %SECONDARY_GW% metric 10 :: 主网关故障时,调高其Metric让系统自动切换 route change 0.0.0.0 mask 0.0.0.0 %PRIMARY_GW% metric 20 :: 主网关恢复后,改回原Metric优先级 route change 0.0.0.0 mask 0.0.0.0 %PRIMARY_GW% metric 1
这种方式不用修改网卡的默认网关配置,只是调整路由优先级,对系统影响极小,稳定性更高。
2. 使用PowerShell脚本替代批处理
PowerShell处理命令输出和逻辑判断比批处理更灵活可靠,比如可以直接解析网络命令的结果对象,不用靠字符串匹配:
$interfaceName = "Ethernet" $primaryGw = "172.20.0.1" $secondaryGw = "172.20.0.254" $pingCount = 3 $checkInterval = 10 while($true){ # 获取当前默认网关 $currentGw = (Get-NetRoute -InterfaceAlias $interfaceName -DestinationPrefix "0.0.0.0/0").NextHop Write-Host "当前默认网关: $currentGw" # 检测网关连通性 $pingResult = Test-Connection -ComputerName $currentGw -Count $pingCount -Quiet if($pingResult){ Write-Host "网关$currentGw 连通正常" } else { Write-Host "网关$currentGw 连通失败,切换到备用网关" if($currentGw -eq $primaryGw){ Set-NetRoute -InterfaceAlias $interfaceName -DestinationPrefix "0.0.0.0/0" -NextHop $secondaryGw -RouteMetric 1 } else { Set-NetRoute -InterfaceAlias $interfaceName -DestinationPrefix "0.0.0.0/0" -NextHop $primaryGw -RouteMetric 1 } } Start-Sleep -Seconds $checkInterval }
PowerShell脚本的可读性和可维护性更强,适合复杂的网络监控场景。
备注:内容来源于stack exchange,提问作者Leul Melaku




