You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

双默认网关自动切换批处理脚本优化及命令行输出读取方法问询

双默认网关自动切换批处理脚本优化及命令行输出读取方法问询

首先得说你的原脚本存在几个核心问题:比如没正确捕获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

火山引擎 最新活动