Windows 一键切换静态/动态 IP:从 .bat 到 PowerShell + Wi-Fi SSID 联动的现代化方案
笔记本电脑在家用 DHCP 自动获取 IP、到公司又得改成静态固定 IP 才能上内网——切换两个网络环境时手动改 IP/掩码/网关/DNS 6 项设置实在烦。一个 .bat 批处理文件 + 双击就能切换是经典解法,但网传的批处理在 2026 年要更新——Windows 10/11 的网卡名字本地化、UAC 权限、PowerShell 替代 netsh、多网卡同时切、Wi-Fi SSID 关联自动切换等都变了。
这一篇把"Windows 一键切换 IP"从 .bat 时代讲到 PowerShell + 计划任务 + Wi-Fi SSID 自动联动的现代化做法,附 netsh / Powershell / WMI 三套实现对比、UAC 与 ExecutionPolicy 真实坑、多接口同步切换、配置档(profile)模式与 FAQ。
原始 .bat 代码的三个真实坑
原帖代码逻辑没问题,但实战遇到的坑:
网卡名"以太网"在不同语言 / 版本不同
| 系统 | 有线网卡默认名 | Wi-Fi 默认名 |
|---|---|---|
| Win 7 / 8 中文版 | 本地连接 | 无线网络连接 |
| Win 10 中文版 | 以太网 | WLAN |
| Win 11 中文版 | 以太网 | Wi-Fi |
| Win 10/11 英文版 | Ethernet | Wi-Fi |
| 装了多块网卡 | 以太网 / 以太网 2 / 以太网 3 | 同样可能多个 |
脚本里写死 name="以太网" 在英文系统、装了多块网卡、用户改过名字的电脑上都不工作。
UAC 权限不够会无声失败
netsh 改 IP 需要管理员权限。普通双击运行 .bat 默认走非管理员,netsh 命令不报错但不生效——脚本看似跑完,IP 实际没变。
多 DNS / IPv6 没考虑
原代码只设主备 DNS、只针对 IPv4。2026 年很多公司开始走 IPv4+IPv6 双栈,IPv6 没切换会导致部分应用走错路由。
现代化版本:PowerShell + 自动检测网卡
PowerShell 比 netsh 更现代,且支持自动检测当前活跃网卡,不依赖固定中文名:
#Requires -RunAsAdministrator
# switch-ip.ps1 — 一键切换办公/家庭网络配置
param(
[Parameter(Mandatory=$true)]
[ValidateSet('office','home','custom')]
[string]$Mode
)
# 自动找到当前已连接的有线/Wi-Fi 接口
$activeInterface = Get-NetAdapter | Where-Object {
$_.Status -eq 'Up' -and $_.MediaType -in 'Ethernet 802.3', 'Native 802.11'
} | Select-Object -First 1
if (-not $activeInterface) {
Write-Host '[ERR] 没找到活跃的网络适配器' -ForegroundColor Red
exit 1
}
$ifName = $activeInterface.Name
Write-Host "活跃网卡: $ifName ($($activeInterface.InterfaceDescription))"
switch ($Mode) {
'office' {
Write-Host '[INFO] 切换到办公网络(静态 IP)'
# 移除已有 IP 配置
Get-NetIPAddress -InterfaceAlias $ifName -AddressFamily IPv4 -ErrorAction SilentlyContinue | Remove-NetIPAddress -Confirm:$false
Get-NetRoute -InterfaceAlias $ifName -AddressFamily IPv4 -ErrorAction SilentlyContinue | Where-Object DestinationPrefix -eq '0.0.0.0/0' | Remove-NetRoute -Confirm:$false
# 设置静态 IP
New-NetIPAddress -InterfaceAlias $ifName -IPAddress '10.129.34.147' -PrefixLength 22 -DefaultGateway '10.129.32.1'
Set-DnsClientServerAddress -InterfaceAlias $ifName -ServerAddresses ('10.129.32.10','114.114.114.114')
Write-Host '[OK] 办公网络配置完成'
}
'home' {
Write-Host '[INFO] 切换到家庭网络(DHCP)'
# 改回 DHCP
Set-NetIPInterface -InterfaceAlias $ifName -Dhcp Enabled
Set-DnsClientServerAddress -InterfaceAlias $ifName -ResetServerAddresses
# 强制重新拉 IP
ipconfig /release $ifName | Out-Null
ipconfig /renew $ifName | Out-Null
Write-Host '[OK] DHCP 已恢复'
}
'custom' {
$ip = Read-Host '输入 IP 地址'
$prefix = Read-Host '输入子网掩码长度(如 24)'
$gw = Read-Host '输入网关'
$dns = Read-Host '输入 DNS(逗号分隔)'
Get-NetIPAddress -InterfaceAlias $ifName -AddressFamily IPv4 -ErrorAction SilentlyContinue | Remove-NetIPAddress -Confirm:$false
New-NetIPAddress -InterfaceAlias $ifName -IPAddress $ip -PrefixLength $prefix -DefaultGateway $gw
Set-DnsClientServerAddress -InterfaceAlias $ifName -ServerAddresses ($dns -split ',')
Write-Host '[OK] 自定义网络配置完成'
}
}
# 显示当前配置确认
Write-Host "`n当前 IP 配置:"
Get-NetIPAddress -InterfaceAlias $ifName -AddressFamily IPv4 | Format-Table InterfaceAlias, IPAddress, PrefixLength, AddressOrigin
用法
PS> .\switch-ip.ps1 -Mode office
PS> .\switch-ip.ps1 -Mode home
PS> .\switch-ip.ps1 -Mode custom
命令行参数化比 .bat 的菜单选择更适合自动化(计划任务、双击不同快捷方式等)。
PowerShell 优势
- 自动检测活跃网卡:Get-NetAdapter + Status='Up' 不依赖网卡名;
- 无视语言版本:英文系统、中文系统、日文系统都能跑;
- 错误处理:原生 try/catch,失败有明确提示;
- 对象式输出:可以管道继续处理,不像 netsh 输出纯文本;
- 支持 IPv6:Set-NetIPAddress 等 cmdlet 全部支持 -AddressFamily IPv6。
UAC 与执行策略的处理
双击 .ps1 默认不会跑
Windows 默认执行策略是 Restricted——双击 .ps1 文件什么也不发生。要让它能跑,必须改:
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
或者每次用 -ExecutionPolicy Bypass 临时绕过:
powershell -ExecutionPolicy Bypass -File C:\scripts\switch-ip.ps1 -Mode office
自动以管理员身份运行
.ps1 顶部加 #Requires -RunAsAdministrator 让脚本检测权限不够时报错——但仍不会自动提权。要"双击就以管理员跑"必须用一个调用脚本:
REM switch-ip.bat(双击它)
@echo off
powershell -Command "Start-Process powershell -ArgumentList '-NoExit -ExecutionPolicy Bypass -File C:\scripts\switch-ip.ps1 -Mode office' -Verb RunAs"
这段 .bat 用 Start-Process -Verb RunAs 触发 UAC 弹窗,用户点"是"后以管理员跑实际逻辑。比直接 .bat 体验稍差(多一次 UAC 弹窗),但比手动改 ExecutionPolicy 全局更安全。
Wi-Fi SSID 自动联动切换
真正一劳永逸的方案:连接 Wi-Fi 时自动判断是公司网还是家网,自动切换 IP 配置。
用 NetEventSession 监听网络变化
# 监听 Wi-Fi 接口的连接事件
$action = {
$ssid = (netsh wlan show interfaces | Select-String 'SSID\s*:\s*(.+)$').Matches[0].Groups[1].Value.Trim()
if ($ssid -eq 'CompanyWiFi') {
& C:\scripts\switch-ip.ps1 -Mode office
} elseif ($ssid -eq 'HomeWiFi') {
& C:\scripts\switch-ip.ps1 -Mode home
}
}
Register-WmiEvent -Class Win32_NetworkAdapterConfiguration -Action $action
这段在 PowerShell 后台跑,每次网络变化触发回调判断 SSID 自动切配置。
用 Windows Task Scheduler 触发
更稳的做法是用计划任务监听 EventLog 里的网络连接事件:
# 创建计划任务
$Action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -WindowStyle Hidden -File C:\scripts\auto-switch-ip.ps1"
$Trigger = New-ScheduledTaskTrigger -AtLogon # 用户登录时
# 也可以用 EventLog 触发器
$EventTrigger = New-ScheduledTaskTrigger -AtStartup
$Settings = New-ScheduledTaskSettingsSet -StartWhenAvailable -DontStopOnIdleEnd
Register-ScheduledTask -TaskName "AutoSwitchIP" -Action $Action -Trigger $EventTrigger -Settings $Settings -RunLevel Highest
netsh 命令的所有可用变体
原帖只展示了 netsh interface ip set address 一种。netsh 还有更多有用的命令:
REM 查看所有接口的 IP 配置
netsh interface ip show config
REM 设置静态 IP(含网关 metric)
netsh interface ip set address name="以太网" source=static addr=10.0.0.5 mask=255.255.255.0 gateway=10.0.0.1 gwmetric=1
REM 改成 DHCP
netsh interface ip set address name="以太网" source=dhcp
REM 添加额外 IP(同一接口多 IP)
netsh interface ip add address name="以太网" addr=10.0.0.6 mask=255.255.255.0
REM 设置 DNS(覆盖所有)
netsh interface ip set dns name="以太网" source=static addr=8.8.8.8
REM 添加额外 DNS
netsh interface ip add dns name="以太网" addr=1.1.1.1 index=2
REM DHCP 模式 DNS
netsh interface ip set dns name="以太网" source=dhcp
REM 重启接口(强制重连)
netsh interface set interface "以太网" disable
netsh interface set interface "以太网" enable
REM IPv6 设置
netsh interface ipv6 set address interface="以太网" 2001:db8::1/64
REM 备份当前配置
netsh interface ip dump > C:\backup\ip-config.txt
REM 还原配置
netsh -f C:\backup\ip-config.txt
最后一条 netsh -f 还原是救命操作——脚本改坏配置导致没网时,从备份还原比手工敲快得多。建议每次改 IP 前先 dump 一份备份。
一键添加多个网卡 / 多协议
有些办公环境要同时配 IPv4 + IPv6 + 走 VPN,原帖单接口脚本不够。多接口同步处理:
function Set-OfficeNetwork {
$configs = @(
@{ Iface='以太网'; IP='10.0.0.5'; Prefix=24; Gw='10.0.0.1'; DNS=@('8.8.8.8','1.1.1.1') },
@{ Iface='Wi-Fi'; IP='192.168.1.123'; Prefix=24; Gw='192.168.1.1'; DNS=@('8.8.8.8','1.1.1.1') },
@{ Iface='以太网 2'; IP='172.16.0.5'; Prefix=16; Gw='172.16.0.1'; DNS=@('8.8.8.8') }
)
foreach ($cfg in $configs) {
try {
Get-NetIPAddress -InterfaceAlias $cfg.Iface -AddressFamily IPv4 -ErrorAction Stop | Remove-NetIPAddress -Confirm:$false
New-NetIPAddress -InterfaceAlias $cfg.Iface -IPAddress $cfg.IP -PrefixLength $cfg.Prefix -DefaultGateway $cfg.Gw -ErrorAction Stop
Set-DnsClientServerAddress -InterfaceAlias $cfg.Iface -ServerAddresses $cfg.DNS -ErrorAction Stop
Write-Host "[OK] $($cfg.Iface)"
} catch {
Write-Host "[FAIL] $($cfg.Iface): $_" -ForegroundColor Red
}
}
}
网络配置档(Profile)模式
Windows 10/11 自带"网络配置档"概念——每个 Wi-Fi SSID 是一个 profile,profile 里能记录 IP 静态/动态等。但 GUI 里只能给 Wi-Fi 用,不能给以太网。要给以太网用 profile:
REM 导出当前以太网配置为 XML
netsh interface portproxy dump > office-eth.xml
REM 导入应用
netsh interface portproxy reset
netsh -f office-eth.xml
回环测试与验证
切换完后立刻验证:
# 验证 IP 已切换
Get-NetIPAddress -AddressFamily IPv4 | Where-Object IPAddress -Like '10.*'
# 测试网关连通
Test-Connection 10.129.32.1 -Count 2
# 测试 DNS 解析
Resolve-DnsName www.baidu.com
# 测试到外网
Test-Connection 1.1.1.1 -Count 2
四步全过才算切换成功。任何一步失败都可能是配置错或物理链路问题。
常见错误代码与排查
| 错误 | 原因 | 解决 |
|---|---|---|
| "系统找不到指定的文件" | 网卡名错 | Get-NetAdapter 列出实际名称 |
| "对象已存在" | 之前的 IP 没清 | 先 Remove-NetIPAddress 再 New-NetIPAddress |
| 设置成功但 ipconfig 显示空 | UAC 权限不够 | 以管理员身份运行 |
| 切换后无网 | 网关错或子网掩码错 | 核对配置;用 netsh -f 恢复备份 |
| "指定的接口处于禁用状态" | 网卡禁用了 | Enable-NetAdapter 启用 |
Mac / Linux 等价做法
这套思路在其它系统的等价:
- macOS:用
networksetup -setmanual "Ethernet" 10.0.0.5 255.255.255.0 10.0.0.1切换;用"Locations"功能保存多套配置一键切。 - Linux:
ip addr add+ip route add,或用 NetworkManager 的nmcli connection modify。 - iOS / iPadOS:设置 → Wi-Fi → 已连接的网络 → 配置 IP,无脚本能力,只能手动。
- Android:开发者选项里的网络配置,部分 ROM 支持基于 SSID 的自动配置。
常见问题解答
双击 .bat 后弹窗一闪而过看不清错误?
在 .bat 末尾加 pause 让窗口停留,或在每条命令后加 echo %ERRORLEVEL% 看返回码。也可以用 cmd /k 启动窗口:cmd /k C:\path\switch-ip.bat 命令跑完不关闭。
UAC 弹窗每次都问"是否允许",能记住吗?
不能。UAC 是 Windows 安全机制,每次提权都弹窗是设计行为。如果嫌烦:① 改用计划任务,设"以最高权限运行",触发器跑 .ps1,调用方就不需要 UAC;② 关闭 UAC(不推荐,全局降低安全)。最佳实践是接受这次弹窗。
切换后浏览器还显示"无网络"?
浏览器有自己的网络状态缓存。① 关闭重开浏览器;② 或在地址栏 chrome://net-internals/#dns 清 DNS 缓存;③ 命令行 ipconfig /flushdns。最稳的做法是切换脚本最后加这两个命令。
Wi-Fi 切换 SSID 时怎么自动跑脚本?
用文中第四节的 NetEventSession 或 EventLog 触发器。Windows 11 还有更新的 SystemEventsBroker,能更精确监听 Wi-Fi SSID 变化事件。完整方案推荐用 PowerShell 写一个长驻服务(Register-ScheduledTask + AtLogon 触发器)。
切换后还想恢复原来的 DNS 设置怎么办?
切换前先 dump:netsh -c interface dump > C:\backup\original.txt。要恢复 netsh -f C:\backup\original.txt。这是 netsh 自带的备份/还原机制,比记下每条命令再手动跑可靠。
切换 IP 时 VPN 连接会断吗?
看 VPN 走哪个接口。① 如果 VPN 走的是物理网卡,切物理网卡 IP 时 VPN 会断;② 如果 VPN 用虚拟网卡(如 OpenVPN TAP),切物理网卡不影响 VPN。脚本里如果要稳,可以先 rasdial /disconnect 断 VPN → 切 IP → 重连 VPN。
能给不同的 USB 网卡设不同 IP 吗?
能。Get-NetAdapter 会列出所有网卡(包括 USB 转网口),按 InterfaceDescription 或 InterfaceAlias 区分写脚本即可。USB 网卡的命名通常是 "USB Ethernet" 或 "Realtek USB FE Family Controller" 之类。
脚本权限不够能用任务计划绕过 UAC 吗?
能。创建任务计划时勾"以最高权限运行" + "用户登录时触发"。这样脚本直接以管理员身份跑,调用方不需要 UAC。但首次创建任务计划本身需要管理员权限。
多用户共享电脑,每个用户配置不同怎么办?
把脚本放到每个用户的 %USERPROFILE%\AppData\Local\ 下,每个用户有自己的版本。或者在脚本里读取 $env:USERNAME 切换不同配置。共享部分(如管理员权限要求)放到公共位置 C:\ProgramData\。
能不能用 Group Policy(组策略)替代脚本?
能。企业域环境下,AD 域 Group Policy 可以下发"基于位置的网络配置"。家庭/小公司没 AD 域,脚本是最实用方案。Group Policy 的优点是集中管理 + 强制;缺点是要 AD 环境且配置复杂。
因本文不是用Markdown格式的编辑器书写的,转换的页面可能不符合AMP标准。