文章

PowerShell 给网卡添加临时 IP

用 PowerShell 给网卡添加或是删除 IP。

PowerShell 给网卡添加临时 IP

背景

调试的时候总会碰到需要手动设置 IP 的情况,每次都是 打开设置,找到网卡,属性。。。 太麻烦了不是,所以整了这个,当然脚本来是 “豆包” 生成的。

添加 IP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
function AdditionalIP {
    <#
    .SYNOPSIS
    为指定网卡添加额外的IPv4地址(需输入IP/子网掩码格式,如10.10.2.2/24)
    
    .DESCRIPTION
    要求IP参数必须为"IP地址/子网掩码位数"格式,从输入中提取子网掩码,支持指定网卡类型或手动选择网卡
    
    .PARAMETER IP
    必需参数,要添加的IPv4地址+子网掩码位数,格式如 192.168.2.100/24
    
    .PARAMETER Adapter
    可选参数,指定网卡类型:WiFi(无线)或 Ethernet(有线)
    #>
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true, HelpMessage = "要添加的IPv4地址+子网掩码位数,格式如 192.168.2.100/24")]
        [ValidatePattern('^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/([1-9]|[1-2][0-9]|3[0-2])$')]
        [string]$IP,

        [Parameter(Mandatory = $false, HelpMessage = "网卡类型:WiFi(无线)或 Ethernet(有线)")]
        [ValidateSet("WiFi", "Ethernet")]
        [string]$AdapterType
    )

    # 全局错误标志
    $script:errorOccurred = $false

    # 函数1:解析IP和子网掩码(从IP/前缀格式中提取)
    function Parse-IPAndPrefix {
        param([string]$IPWithPrefix)
        try {
            # 拆分IP和子网掩码位数
            $parts = $IPWithPrefix -split '/'
            $ipAddress = $parts[0]
            $prefixLength = [int]$parts[1]

            # 验证子网掩码位数范围(1-32)
            if ($prefixLength -lt 1 -or $prefixLength -gt 32) {
                throw "子网掩码位数必须在1-32之间,当前输入:$prefixLength"
            }

            # 验证IP地址有效性
            if (-not [System.Net.IPAddress]::TryParse($ipAddress, [ref]$null)) {
                throw "IP地址格式无效:$ipAddress"
            }

            # 返回解析结果
            return [PSCustomObject]@{
                IPAddress    = $ipAddress
                PrefixLength = $prefixLength
            }
        }
        catch {
            Write-Host "解析IP和子网掩码失败:$($_.Exception.Message)" -ForegroundColor red
            $script:errorOccurred = $true
            return $null
        }
    }

    # 函数2:获取并选择网卡
    function Get-TargetAdapter {
        param([string]$Type)
        try {
            # 检查是否有管理员权限
            $currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
            if (-not $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
                throw "当前PowerShell无管理员权限,无法修改网卡IP配置!"
            }

            if ($Type) {
                # 根据指定类型筛选网卡
                if ($Type -eq "WiFi") {
                    $adapters = Get-NetAdapter -ErrorAction Stop | Where-Object { 
                        $_.PhysicalMediaType -eq 'Native 802.11' -or $_.Name -match 'Wi-Fi|无线' 
                    } | Where-Object { $_.Status -eq 'Up' }
                }
                else { # Ethernet
                    $adapters = Get-NetAdapter -ErrorAction Stop | Where-Object { 
                        $_.PhysicalMediaType -ne 'Native 802.11' -and $_.Name -notmatch 'Wi-Fi|无线' 
                    } | Where-Object { $_.Status -eq 'Up' }
                }

                if (-not $adapters) {
                    throw "未找到可用的$($Type)网卡(需状态为Up)!"
                }
                return $adapters | Select-Object -First 1
            }
            else {
                # 无指定类型时,列出所有可用网卡供选择
                $allAdapters = Get-NetAdapter -ErrorAction Stop | Where-Object { $_.Status -eq 'Up' } | Select-Object Name, InterfaceDescription, Status
                if (-not $allAdapters) {
                    throw "未找到任何状态为Up的网卡!"
                }

                # 显示网卡列表
                Write-Host "`n=== 可用网卡列表 ===" -ForegroundColor Cyan
                for ($i = 0; $i -lt $allAdapters.Count; $i++) {
                    Write-Host "$($i+1). 名称:$($allAdapters[$i].Name) | 描述:$($allAdapters[$i].InterfaceDescription)"
                }

                # 交互选择网卡(修复[ref]变量未定义问题)
                $selectedIndex = -1  # 提前定义变量
                do {
                    $selection = Read-Host "`n请输入要操作的网卡序号 (1-$($allAdapters.Count))"
                    # 验证输入是否为数字
                    if (-not [int]::TryParse($selection, [ref]$selectedIndex)) {
                        Write-Warning "输入无效,请输入数字序号!"
                        $selectedIndex = -1
                        continue
                    }
                    $selectedIndex -= 1  # 转换为数组索引
                } while ($selectedIndex -lt 0 -or $selectedIndex -ge $allAdapters.Count)

                # 返回选中的网卡
                return Get-NetAdapter -Name $allAdapters[$selectedIndex].Name -ErrorAction Stop | Select-Object -First 1
            }
        }
        catch {
            Write-Host "获取网卡失败:$($_.Exception.Message)"  -ForegroundColor red
            $script:errorOccurred = $true
            return $null
        }
    }

    # 主执行逻辑
    try {
        # 1. 解析IP和子网掩码(核心修改点)
        $parsedIP = Parse-IPAndPrefix -IPWithPrefix $IP
        if (-not $parsedIP -or $script:errorOccurred) {
            throw "IP地址解析失败,请检查格式(如 10.10.2.2/24)!"
        }
        $ipAddress = $parsedIP.IPAddress
        $subnetPrefix = $parsedIP.PrefixLength

        Write-Host "`n=== 解析配置信息 ===" -ForegroundColor Cyan
        Write-Host "待添加IP:$ipAddress"
        Write-Host "子网掩码位数:$subnetPrefix"

        # 2. 获取目标网卡
        $targetAdapter = Get-TargetAdapter -Type $AdapterType
        if (-not $targetAdapter) {
            throw "未获取到有效网卡!"
        }
        Write-Host "`n=== 选中网卡信息 ===" -ForegroundColor Cyan
        Write-Host "网卡名称:$($targetAdapter.Name)"
        Write-Host "网卡状态:$($targetAdapter.Status)"

        # 3. 前置检查:该IP是否已存在
        $existingIPs = Get-NetIPAddress -InterfaceAlias $targetAdapter.Name -AddressFamily IPv4 -ErrorAction Stop | Select-Object -ExpandProperty IPAddress
        if ($existingIPs -contains $ipAddress) {
            throw "该IP地址($ipAddress)已存在于网卡 $($targetAdapter.Name) 中,无需重复添加!"
        }

        # 4. 添加额外IP地址(核心操作)
        Write-Host "`n=== 开始添加IP ===" -ForegroundColor Cyan
        $addResult = New-NetIPAddress -InterfaceAlias $targetAdapter.Name `
            -IPAddress $ipAddress `
            -PrefixLength $subnetPrefix `
            -AddressFamily IPv4 `
            -ErrorAction Stop
        
        if ($addResult) {
            Write-Host "✅ 成功为 $($targetAdapter.Name) 添加IP:$ipAddress/$subnetPrefix" -ForegroundColor Green
        }

        # 5. 验证添加结果
        Write-Host "`n=== 验证配置结果 ===" -ForegroundColor Cyan
        $ipConfig = Get-NetIPAddress -InterfaceAlias $targetAdapter.Name -AddressFamily IPv4 -ErrorAction Stop | Select-Object IPAddress, PrefixLength, AddressState
        $ipConfig | Format-Table -AutoSize
    }
    catch [Microsoft.Management.Infrastructure.CimException] {
        $errorMsg = $_.Exception.Message
        if ($errorMsg -match "already exists") {
            Write-Host "`n❌ 错误:IP地址$ipAddress已被占用(可能在其他网卡或本机)!"  -ForegroundColor red
        }
        elseif ($errorMsg -match "access denied") {
            Write-Host "`n❌ 错误:权限不足,请以管理员身份运行PowerShell!"  -ForegroundColor red
        }
        else {
            Write-Host "`n❌ CIM操作失败:$errorMsg" -ForegroundColor red
        }
        $script:errorOccurred = $true
    }
    catch {
        Write-Host "`n❌ 操作失败:$($_.Exception.Message)" -ForegroundColor red
        $script:errorOccurred = $true
    }
    finally {
        # 最终清理/提示(保留Write-Host的颜色参数,因为Write-Host支持)
        if ($script:errorOccurred) {
            Write-Host "`n⚠️  本次IP添加操作未完成,请检查错误信息后重试!" -ForegroundColor Yellow
            Write-Host "💡 提示:IP参数必须为 地址/掩码位数 格式,例如 10.10.2.2/24`n" -ForegroundColor Cyan
        }
        else {
            Write-Host "`n🎉 所有操作完成,IP添加成功!`n" -ForegroundColor Green
        }
    }
}

做为一个 function 方便重复使用,运行时 可以带参数,举个粟子:

删除 IP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
function RemoveIP {
    <#
    .SYNOPSIS
    交互式删除指定网卡的IPv4地址,删除最后一个IP时自动配置DHCP模式
    
    .DESCRIPTION
    可选指定网卡名称,无参数时列出所有可用网卡供选择;选中网卡后循环列出其IP列表,删除一个IP后返回列表(输入0退出);
    删除最后一个静态IP时,自动将网卡切换为DHCP模式,避免无IP导致断连;
    修复网卡别名不一致导致的DHCP配置失败问题
    
    .PARAMETER AdapterName
    可选参数,指定要操作的网卡名称(如"Wi-Fi"),不指定则进入交互选择
    
    .EXAMPLE
    Remove-NetworkIP -AdapterName "Wi-Fi"
    直接操作Wi-Fi网卡,删除IP后自动处理DHCP配置
    
    .EXAMPLE
    RemoveIP
    先选网卡,再循环删除IP
    #>
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [Parameter(Mandatory = $false, HelpMessage = "指定要操作的网卡名称,如'Wi-Fi'")]
        [string]$AdapterName
    )

    # 全局错误标志
    $script:errorOccurred = $false

    # 函数1:获取并选择目标网卡(返回索引+名称,核心修改)
    function Get-TargetNetworkAdapter {
        param([string]$Name)
        
        try {
            # 检查管理员权限
            $currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
            if (-not $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
                throw "必须以管理员身份运行PowerShell才能修改网络配置!"
            }

            # 获取所有可用网卡(状态为Up,包含索引)
            $allAdapters = Get-NetAdapter -ErrorAction Stop | Where-Object { $_.Status -eq 'Up' } | 
                Select-Object Name, InterfaceDescription, InterfaceIndex, InterfaceAlias
            if (-not $allAdapters) {
                throw "未找到任何状态为Up的可用网卡!"
            }

            if ($Name) {
                # 按名称匹配(兼容Alias/Name)
                $targetAdapter = $allAdapters | Where-Object { 
                    $_.Name -eq $Name -or $_.InterfaceAlias -eq $Name 
                } | Select-Object -First 1
                if (-not $targetAdapter) {
                    throw "指定的网卡名称 '$Name' 不存在或不可用!`n可用网卡列表:$($allAdapters.Name -join ', ')"
                }
                return $targetAdapter
            }
            else {
                # 列出网卡供用户选择(显示名称+索引)
                Write-Host "`n=== 可用网卡列表 ===" -ForegroundColor Cyan
                for ($i = 0; $i -lt $allAdapters.Count; $i++) {
                    Write-Host "$($i+1). 名称:$($allAdapters[$i].Name) | 索引:$($allAdapters[$i].InterfaceIndex) | 描述:$($allAdapters[$i].InterfaceDescription)"
                }

                # 交互选择网卡(输入验证)
                $selectedIndex = -1
                do {
                    $selection = Read-Host "`n请输入要操作的网卡序号 (1-$($allAdapters.Count))"
                    if (-not [int]::TryParse($selection, [ref]$selectedIndex)) {
                        Write-Warning "输入无效,请输入数字序号!"
                        $selectedIndex = -1
                        continue
                    }
                    $selectedIndex -= 1
                } while ($selectedIndex -lt 0 -or $selectedIndex -ge $allAdapters.Count)

                return $allAdapters[$selectedIndex]
            }
        }
        catch {
            Write-Error "获取网卡失败:$($_.Exception.Message)"
            $script:errorOccurred = $true
            return $null
        }
    }

    # 函数2:获取网卡的IPv4地址列表并选择要删除的IP(支持退出)
    function Get-IPToRemove {
        param([int]$AdapterIndex)
        
        try {
            # 按索引获取IP(核心修改:用索引替代别名)
            $ipList = Get-NetIPAddress -InterfaceIndex $AdapterIndex -AddressFamily IPv4 -ErrorAction Stop | 
                Where-Object { $_.IPAddress -notlike '127.*' } |
                Select-Object IPAddress, PrefixLength, AddressState, InterfaceIndex, InterfaceAlias

            if (-not $ipList -or $ipList.Count -eq 0) {
                throw "该网卡未配置任何可用的IPv4地址!"
            }

            # 列出IP列表供选择(添加0退出选项)
            Write-Host "`n=== 网卡IPv4地址列表(输入0退出)===" -ForegroundColor Cyan
            for ($i = 0; $i -lt $ipList.Count; $i++) {
                Write-Host "$($i+1). IP:$($ipList[$i].IPAddress)/$($ipList[$i].PrefixLength) | 状态:$($ipList[$i].AddressState)"
            }
            Write-Host "0. 退出操作" -ForegroundColor Gray

            # 交互选择要删除的IP(支持0退出)
            $selectedIPIndex = -2
            do {
                $selection = Read-Host "`n请输入要删除的IP序号 (0-$($ipList.Count))"
                if (-not [int]::TryParse($selection, [ref]$selectedIPIndex)) {
                    Write-Warning "输入无效,请输入数字序号!"
                    $selectedIPIndex = -2
                    continue
                }
                # 输入0则返回null表示退出
                if ($selectedIPIndex -eq 0) {
                    return $null
                }
                $selectedIPIndex -= 1
            } while ($selectedIPIndex -lt 0 -or $selectedIPIndex -ge $ipList.Count)

            # 返回选中的IP+当前IP总数
            return [PSCustomObject]@{
                IPInfo      = $ipList[$selectedIPIndex]
                TotalIPCount = $ipList.Count
            }
        }
        catch {
            Write-Error "获取IP列表失败:$($_.Exception.Message)"
            $script:errorOccurred = $true
            return $null
        }
    }

    # 函数3:将网卡切换为DHCP模式(用索引操作,核心修改)
    function Set-AdapterToDHCP {
        param([int]$AdapterIndex, [string]$AdapterName)
        
        try {
            Write-Host "`n=== 开始配置DHCP模式 ===" -ForegroundColor Cyan
            # 用InterfaceIndex启用DHCP(稳定无兼容问题)
            Set-NetIPInterface -InterfaceIndex $AdapterIndex -DHCP Enabled -ErrorAction Stop
            
            # 释放并重新获取DHCP地址(用名称兼容ipconfig)
            ipconfig /release "$AdapterName" | Out-Null
            ipconfig /renew "$AdapterName" | Out-Null
            
            # 验证DHCP状态(按索引)
            $dhcpStatus = Get-NetIPInterface -InterfaceIndex $AdapterIndex -AddressFamily IPv4 -ErrorAction Stop
            if ($dhcpStatus.DHCP -eq 'Enabled') {
                Write-Host "✅ 网卡 $AdapterName 已成功切换为DHCP模式" -ForegroundColor Green
                # 获取新的DHCP分配的IP
                Start-Sleep -Seconds 2 # 等待DHCP分配IP
                $dhcpIP = Get-NetIPAddress -InterfaceIndex $AdapterIndex -AddressFamily IPv4 -ErrorAction SilentlyContinue | 
                    Where-Object { $_.IPAddress -notlike '127.*' -and $_.AddressState -eq 'Preferred' } |
                    Select-Object -First 1 IPAddress
                if ($dhcpIP) {
                    Write-Host "🔍 DHCP已分配IP:$($dhcpIP.IPAddress)" -ForegroundColor Cyan
                }
                else {
                    Write-Host "🔍 暂未获取到DHCP IP,请检查路由器/网络配置" -ForegroundColor Yellow
                }
                return $true
            }
            else {
                throw "DHCP模式配置成功,但验证状态为禁用!"
            }
        }
        catch {
            Write-Error "❌ 配置DHCP模式失败:$($_.Exception.Message)"
            # 备用方案:尝试用netsh配置DHCP(兼容所有系统)
            try {
                Write-Host "💡 尝试备用方案配置DHCP..." -ForegroundColor Cyan
                netsh interface ip set address name="$AdapterName" source=dhcp | Out-Null
                Write-Host "✅ 备用方案:网卡 $AdapterName 已配置为DHCP(netsh)" -ForegroundColor Green
                return $true
            }
            catch {
                Write-Error "❌ 备用方案也配置失败:$($_.Exception.Message)"
                return $false
            }
        }
    }

    # 主执行逻辑
    try {
        # 1. 检查管理员权限(前置)
        $currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
        if (-not $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
            throw "当前PowerShell无管理员权限!请右键PowerShell → 以管理员身份运行。"
        }

        # 2. 获取目标网卡(包含索引)
        $targetAdapter = Get-TargetNetworkAdapter -Name $AdapterName
        if (-not $targetAdapter -or $script:errorOccurred) {
            throw "未获取到有效网卡,终止操作!"
        }
        $adapterIndex = $targetAdapter.InterfaceIndex
        $adapterName = $targetAdapter.Name
        Write-Host "`n✅ 选中操作网卡:$adapterName(索引:$adapterIndex)" -ForegroundColor Green
        Write-Host "💡 提示:删除IP后会自动返回列表,输入0可退出;删除最后一个IP会自动配置DHCP" -ForegroundColor Cyan

        # 3. 循环执行IP删除
        while ($true) {
            # 重置单次操作的错误状态
            $singleError = $false

            # 3.1 获取要删除的IP(按索引)
            $ipSelection = Get-IPToRemove -AdapterIndex $adapterIndex
            if (-not $ipSelection) {
                if ($script:errorOccurred) {
                    $singleError = $true
                }
                else {
                    Write-Host "`n📌 用户选择退出,终止IP删除操作。" -ForegroundColor Cyan
                    break
                }
            }

            # 若获取IP失败,继续下一轮循环
            if ($singleError -or $script:errorOccurred) {
                $script:errorOccurred = $false
                continue
            }

            $ipToRemove = $ipSelection.IPInfo
            $totalIPCount = $ipSelection.TotalIPCount
            $ipAddress = $ipToRemove.IPAddress

            # 3.2 最后一个IP的特殊提示和确认
            $isLastIP = $totalIPCount -eq 1
            if ($isLastIP) {
                Write-Host "`n⚠️  警告:这是网卡 $adapterName 的最后一个静态IPv4地址!" -ForegroundColor Red
                Write-Host "⚠️  删除后将自动将网卡切换为DHCP模式(避免无IP断连)" -ForegroundColor Red
                $confirmLastIP = Read-Host "是否确认删除最后一个IP并启用DHCP?(Y/N,默认N)"
                if ($confirmLastIP -notmatch '^[Yy]$') {
                    Write-Host "`n📌 用户取消操作,返回IP列表..." -ForegroundColor Cyan
                    continue
                }
            }
            else {
                Write-Host "`n⚠️  确认要删除IP:$ipAddress/$($ipToRemove.PrefixLength)(网卡:$adapterName)" -ForegroundColor Yellow
                $confirm = Read-Host "是否确认删除?(Y/N,默认N)"
                if ($confirm -notmatch '^[Yy]$') {
                    Write-Host "`n📌 用户取消删除,返回IP列表..." -ForegroundColor Cyan
                    continue
                }
            }

            # 3.3 执行删除操作(按索引+IP)
            try {
                Write-Host "`n=== 开始删除IP ===" -ForegroundColor Cyan
                Remove-NetIPAddress -IPAddress $ipAddress -InterfaceIndex $adapterIndex -Confirm:$false -ErrorAction Stop
                
                if ($isLastIP) {
                    Write-Host "✅ 成功删除最后一个静态IP:$ipAddress(网卡:$adapterName)" -ForegroundColor Green
                    # 自动配置DHCP模式(传索引+名称)
                    $dhcpSuccess = Set-AdapterToDHCP -AdapterIndex $adapterIndex -AdapterName $adapterName
                    if ($dhcpSuccess) {
                        Write-Host "`n📌 最后一个IP已删除并配置DHCP,自动退出循环..." -ForegroundColor Cyan
                    }
                    else {
                        Write-Warning "`n⚠️  最后一个IP已删除,但DHCP配置失败!请手动检查网络" -ForegroundColor Yellow
                    }
                    break # 退出循环
                }
                else {
                    Write-Host "✅ 成功删除IP:$ipAddress(网卡:$adapterName)" -ForegroundColor Green
                    # 验证剩余IP(按索引)
                    $remainingIPs = Get-NetIPAddress -InterfaceIndex $adapterIndex -AddressFamily IPv4 -ErrorAction SilentlyContinue | 
                        Where-Object { $_.IPAddress -notlike '127.*' } |
                        Select-Object IPAddress, PrefixLength
                    Write-Host "🔍 当前剩余IP数量:$($remainingIPs.Count)" -ForegroundColor Cyan
                }
            }
            catch [Microsoft.Management.Infrastructure.CimException] {
                $errorMsg = $_.Exception.Message
                # 兼容最后一个IP删除后的异常
                if ($errorMsg -match "No matching MSFT_NetIPAddress objects found" -and $isLastIP) {
                    Write-Host "✅ 最后一个静态IP $ipAddress 已删除(系统自动清理配置)" -ForegroundColor Green
                    # 配置DHCP
                    $dhcpSuccess = Set-AdapterToDHCP -AdapterIndex $adapterIndex -AdapterName $adapterName
                    break
                }
                elseif ($errorMsg -match "does not exist") {
                    Write-Error "❌ 错误:IP地址 $ipAddress 不存在,无需删除!"
                }
                elseif ($errorMsg -match "access denied") {
                    Write-Error "❌ 错误:权限不足,请以管理员身份运行!"
                }
                else {
                    Write-Error "❌ 操作失败:$errorMsg"
                }
            }
            catch {
                if ($isLastIP) {
                    Write-Host "✅ 最后一个静态IP $ipAddress 已删除(后续验证异常忽略)" -ForegroundColor Green
                    Set-AdapterToDHCP -AdapterIndex $adapterIndex -AdapterName $adapterName
                    break
                }
                else {
                    Write-Error "❌ 删除IP失败:$($_.Exception.Message)"
                }
            }

            # 3.4 非最后一个IP时返回列表
            if (-not $isLastIP) {
                Write-Host "`n💡 即将返回IP选择列表(按任意键继续...)" -ForegroundColor Gray
                $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
            }
        }

        # 最终验证
        Write-Host "`n=== 最终验证结果 ===" -ForegroundColor Cyan
        try {
            # 检查DHCP状态(按索引)
            $dhcpStatus = Get-NetIPInterface -InterfaceIndex $adapterIndex -AddressFamily IPv4 -ErrorAction SilentlyContinue
            if ($dhcpStatus.DHCP -eq 'Enabled') {
                Write-Host "网卡 $adapterName 当前模式:DHCP(已启用)" -ForegroundColor Green
            }
            else {
                $finalIPs = Get-NetIPAddress -InterfaceIndex $adapterIndex -AddressFamily IPv4 -ErrorAction SilentlyContinue | 
                    Where-Object { $_.IPAddress -notlike '127.*' } |
                    Select-Object IPAddress, PrefixLength
                if ($finalIPs) {
                    Write-Host "网卡 $adapterName 当前模式:静态IP" -ForegroundColor Cyan
                    Write-Host "剩余IPv4地址:"
                    $finalIPs | Format-Table -AutoSize
                }
                else {
                    Write-Host "网卡 $adapterName 无静态IP且DHCP未启用(请手动检查)" -ForegroundColor Yellow
                }
            }
        }
        catch {
            Write-Host "网卡 $adapterName 配置验证完成(部分信息无法查询,属正常)" -ForegroundColor Cyan
        }
    }
    catch {
        Write-Error "❌ 操作失败:$($_.Exception.Message)"
        $script:errorOccurred = $true
    }
    finally {
        if ($script:errorOccurred) {
            Write-Host "`n⚠️  IP删除操作异常终止,请检查错误信息后重试!" -ForegroundColor Yellow
        }
        else {
            Write-Host "`n🎉 IP删除操作正常完成!" -ForegroundColor Green
        }
    }
}

一样, 做为一个 function 来使用。

我把这两个 function 添加到 powershell profile 里面,比较方便。

豆包说这是临时的 ip,重启电脑就没了,这个没有试,因为我一般不关电脑。 :)

本文由作者按照 CC BY 4.0 进行授权