Windows下 DDNS会获取到已失效IP地址的解决方案
家庭宽带下 IPV6公网地址经常由于运营商等原因被弃用,这时我们可以使用DDNS解决。
但Windows会因为传输稳定等考虑,不会立刻弃用IPV6地址,这就造成了IPconfig可以查到那个地址,但是在公网的IPV6ping服务已经无法ping通这个地址。
我们只需要一个简单的脚本,定期监测被标记为被废弃的地址,并立即清除即可。
禁止在生产环境中使用,这样会导致长连接的中断!
# --- 自动提权代码开始 ---
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
if (-not $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
$arguments = "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`""
Start-Process pwsh.exe -ArgumentList $arguments -Verb RunAs
exit
}
# --- 自动提权代码结束 ---
# 这里放你原本的脚本逻辑
Write-Host "正在以管理员身份刷新 IPv6..."
# 2. 隐藏窗口逻辑 (针对已经提权后的进程)
# 这一段调用 Windows API 来彻底隐藏当前运行的窗口
$showWindowAsync = '[DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);'
$type = Add-Type -MemberDefinition $showWindowAsync -Name "Win32ShowWindowAsync" -Namespace "Win32" -PassThru
$hwnd = (Get-Process -Id $PID).MainWindowHandle
if ($hwnd -ne [IntPtr]::Zero) {
# 0 代表 SW_HIDE (隐藏)
$type::ShowWindowAsync($hwnd, 0)
}
# 获取桌面路径
$DesktopPath = [Environment]::GetFolderPath("Desktop")
$LogFile = "$DesktopPath\IPv6_Switch_Log.txt"
# 设置检测频率(秒)
$Interval = 5
Write-Host "------------------------------------------------" -ForegroundColor Cyan
Write-Host "IPv6 僵尸地址清理监控已启动..." -ForegroundColor Cyan
Write-Host "监控频率: 每 $Interval 秒一次"
Write-Host "日志路径: $LogFile"
Write-Host "提示: 如果检测到废弃地址,将在此处和桌面日志同步输出。"
Write-Host "------------------------------------------------" -ForegroundColor Cyan
while ($true) {
try {
# 1. 扫描所有状态为 Deprecated (弃用) 的 240x 开头公网 IPv6
$Zombies = Get-NetIPAddress -AddressFamily IPv6 -ErrorAction SilentlyContinue |
Where-Object {
($_.IPAddress -match "^240") -and
($_.AddressState -eq "Deprecated")
}
if ($Zombies) {
foreach ($OldIP in $Zombies) {
# 2. 寻找同一个接口上的接班人 (Preferred IP)
$NewIPObj = Get-NetIPAddress -AddressFamily IPv6 -InterfaceIndex $OldIP.InterfaceIndex -AddressState Preferred -ErrorAction SilentlyContinue |
Where-Object { $_.IPAddress -match "^240" } |
Select-Object -First 1
$NewIPStr = if ($NewIPObj) { $NewIPObj.IPAddress } else { "未检测到新IP" }
$TimeStr = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$InterfaceName = $OldIP.InterfaceAlias
# 3. 构造输出信息
$LogContent = "[$TimeStr] 发生切换 | 接口: $InterfaceName | 废弃旧IP: $($OldIP.IPAddress) | 启用新IP: $NewIPStr"
# --- 屏幕输出 (彩色) ---
Write-Host "`n[!] 检测到地址废弃!" -ForegroundColor Yellow
Write-Host "时间: $TimeStr"
Write-Host "网卡: $InterfaceName"
Write-Host "清理: $($OldIP.IPAddress)" -ForegroundColor Red
Write-Host "新推: $NewIPStr" -ForegroundColor Green
# --- 写入桌面日志 ---
Add-Content -Path $LogFile -Value $LogContent -Encoding UTF8
# 4. 执行清理
Remove-NetIPAddress -InputObject $OldIP -Confirm:$false -ErrorAction SilentlyContinue
# 刷新 DNS 缓存
Clear-DnsClientCache
Write-Host "清理完成,网络栈已刷新。" -ForegroundColor Gray
}
}
}
catch {
# 保持静默不死
}
Start-Sleep -Seconds $Interval
}