问题现象

一台长期使用、经历过多次系统迁移、网卡变化或连接环境变化的 Windows 电脑,可能会出现这样的网络名称:

EXAMPLE_WIFI
EXAMPLE_WIFI 2
EXAMPLE_WIFI 3

或者:

网络
网络 3
网络 4
网络 5
……

甚至几十条。

这些记录并不一定意味着系统中保存了几十个 Wi-Fi 密码。

真正的 Wi-Fi 配置和 Windows 的 NetworkList 网络历史记录,是两个不同的系统。

这一区别非常重要。


一、Windows 实际上保存了两类网络信息

WLAN Profile

Wi-Fi SSID、密码、加密方式、自动连接设置等主要由 WLAN Profile 保存。

查看:

netsh wlan show profiles

输出类似:

All User Profile : EXAMPLE_WIFI

这些配置包含真正的 Wi-Fi 连接参数。

删除:

netsh wlan delete profile name="EXAMPLE_WIFI"

会导致保存的 Wi-Fi 配置一起消失。

如果目标只是整理“网络 2、网络 3”之类的历史名称,通常不应该执行这个命令


NetworkList

Windows 还维护另一套网络识别数据库:

HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList

其中最重要的两个区域是:

Profiles
Signatures

Profiles 负责保存 Windows 曾经识别到的网络身份。

Signatures 则负责保存识别这些网络时使用的一些特征,例如:

  • 网关 MAC;
  • 网络描述;
  • DNS 信息;
  • FirstNetwork;
  • 网络签名。

于是,即使 Wi-Fi Profile 只有一个:

EXAMPLE_WIFI

NetworkList 中仍可能出现:

EXAMPLE_WIFI
EXAMPLE_WIFI 2
EXAMPLE_WIFI 3

二、为什么 Windows 会自动增加数字后缀

Windows 会根据网络签名判断“这是不是以前那个网络”。

如果某些识别条件发生变化,例如:

  • 路由器更换;
  • 网关 MAC 改变;
  • 网卡更换;
  • 驱动重新安装;
  • Windows 系统迁移;
  • 网络共享方式改变;
  • USB 网卡或虚拟网卡变化;
  • DHCP / 网络拓扑变化;

系统就可能认为这是一个“新的网络”。

如果名称已经存在,就自动生成:

EXAMPLE_WIFI 2
EXAMPLE_WIFI 3

因此,NetworkList 本质上是一套网络历史数据库。

使用时间越长,里面越容易积累大量旧记录。


三、读取全部 NetworkList Profiles

管理员 PowerShell:

$profileRoot = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles'

Get-ChildItem $profileRoot |
    ForEach-Object {

        $p = Get-ItemProperty $_.PSPath

        [PSCustomObject]@{
            ProfileName = $p.ProfileName
            Description = $p.Description
            Category    = $p.Category
            GUID        = $_.PSChildName
        }

    } |
    Sort-Object ProfileName |
    Format-Table -AutoSize

其中:

Category = 0

通常代表 Public。

Category = 1

通常代表 Private。


四、首先确认当前正在使用的网络

在删除任何记录之前,都应该读取当前活动连接:

Get-NetConnectionProfile |
    Format-Table Name, InterfaceAlias, InterfaceIndex, NetworkCategory -AutoSize

例如:

Name          InterfaceAlias    NetworkCategory
------------  ----------------  ---------------
EXAMPLE_WIFI  Wi-Fi             Private

当前活动 Profile 应当受到保护。


五、自动找出带数字后缀的重复组

可以将名称末尾的数字去掉,然后分组:

$profiles = @(
    Get-ChildItem $profileRoot |
        ForEach-Object {

            $p = Get-ItemProperty $_.PSPath

            [PSCustomObject]@{
                BaseName    = $p.ProfileName -replace '\s+\d+$',''
                ProfileName = $p.ProfileName
                Description = $p.Description
                Category    = $p.Category
                GUID        = $_.PSChildName
            }
        }
)

$profiles |
    Group-Object BaseName |
    Where-Object {
        $_.Count -gt 1
    } |
    ForEach-Object {

        Write-Host "`n--- $($_.Name) ---"

        $_.Group |
            Sort-Object ProfileName |
            Format-Table ProfileName, Description, Category, GUID -AutoSize
    }

可能得到:

EXAMPLE_WIFI
EXAMPLE_WIFI 2
EXAMPLE_WIFI 3

这种情况就是明显的数字后缀组。


六、不要把所有“以数字结尾”的名称都当成重复项

这是非常重要的一点。

例如:

OFFICE-5G
PHONE-2026
DEVICE 1318

数字本身可能就是网络名称的一部分。

因此,不应该简单使用:

ProfileName -match '\d+$'

然后全部删除。

更安全的方法是:

  1. 去除数字后缀;
  2. 确认同一个 BaseName 至少有两条记录;
  3. 确认其中存在无数字版本;
  4. 只删除该组中的数字版本。

例如:

$duplicateGroups = @(
    $profiles |
        Group-Object BaseName |
        Where-Object {
            $_.Count -gt 1 -and
            ($_.Group.ProfileName -contains $_.Name)
        }
)

这样,单独存在的数字名称不会被误删。


七、清理前备份整个 NetworkList

建议先完整导出:

$backup = "$env:USERPROFILE\Desktop\NetworkList-Backup"

New-Item -ItemType Directory -Path $backup -Force |
    Out-Null

reg.exe export `
    "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList" `
    "$backup\NetworkList.reg" /y

这样即使误操作,也保留了恢复依据。


八、删除数字后缀 Profile

生成删除目标:

$targets = @(
    $duplicateGroups |
        ForEach-Object {

            $_.Group |
                Where-Object {
                    $_.ProfileName -match '\s+\d+$'
                }
        }
)

删除前应检查当前活动网络是否进入目标列表:

$activeNames = @(
    Get-NetConnectionProfile |
        Select-Object -ExpandProperty Name
)

$activeTargets = @(
    $targets |
        Where-Object {
            $_.ProfileName -in $activeNames
        }
)

if ($activeTargets.Count -gt 0) {
    throw 'Active NetworkList profile is in deletion list.'
}

如果安全检查通过,再处理。


九、为什么还必须清理 Signatures

只删除:

NetworkList\Profiles

并不代表这条网络历史完全消失。

它对应的网络签名可能仍然保留在:

NetworkList\Signatures\Managed
NetworkList\Signatures\Unmanaged

读取方式:

$sigRoots = @(
    'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Signatures\Managed',
    'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Signatures\Unmanaged'
)

每个 Signature 都带有:

ProfileGuid

因此,可以根据 GUID 找出对应关系。

删除 Profile 时,最好同时删除指向该 GUID 的 Signature。


十、清理孤立 Signature

有些系统在历史操作后还会遗留这样的情况:

Signature → 某个 ProfileGuid

但:

Profiles\{该 GUID}

已经不存在。

这就是孤立 Signature。

检测:

$profileGuids = @(
    Get-ChildItem $profileRoot |
        Select-Object -ExpandProperty PSChildName
)

$orphans = @()

foreach ($root in $sigRoots) {

    if (!(Test-Path $root)) {
        continue
    }

    foreach ($key in Get-ChildItem $root) {

        $s = Get-ItemProperty $key.PSPath -ErrorAction SilentlyContinue

        if (
            $s.ProfileGuid -and
            $s.ProfileGuid -notin $profileGuids
        ) {

            $orphans += [PSCustomObject]@{
                ProfileGuid = $s.ProfileGuid
                Description = $s.Description
                Path        = $key.PSPath
            }
        }
    }
}

确认后即可删除:

foreach ($orphan in $orphans) {
    Remove-Item $orphan.Path -Recurse -Force
}

十一、最终验证

检查数字重复组

$after = @(
    Get-ChildItem $profileRoot |
        ForEach-Object {

            $p = Get-ItemProperty $_.PSPath

            [PSCustomObject]@{
                BaseName    = $p.ProfileName -replace '\s+\d+$',''
                ProfileName = $p.ProfileName
                GUID        = $_.PSChildName
            }
        }
)

$after |
    Group-Object BaseName |
    Where-Object {
        $_.Count -gt 1 -and
        ($_.Group.ProfileName -contains $_.Name)
    }

理想情况下不应再得到目标重复组。


检查孤立 Signature

再次比较:

Signatures.ProfileGuid

和:

Profiles.GUID

理想结果应为:

No orphaned NetworkList signatures remain.

检查当前活动网络

Get-NetConnectionProfile |
    Format-Table Name, InterfaceAlias, InterfaceIndex, NetworkCategory -AutoSize

当前网络名称应保持正常。


十二、这项操作不会删除什么

如果整个过程中没有调用:

netsh wlan delete profile

那么 NetworkList 清理通常不会删除:

  • Wi-Fi SSID;
  • Wi-Fi 密码;
  • WPA/WPA2/WPA3 配置;
  • 自动连接设置;
  • WLAN Profile。

也就是说:

NetworkList 历史记录

与:

保存的 Wi-Fi Profile

是两回事。

这也是清理此类问题时最需要区分的概念。


总结

Windows 中出现:

网络
网络 2
网络 3

或者:

EXAMPLE_WIFI
EXAMPLE_WIFI 2
EXAMPLE_WIFI 3

通常不是 Wi-Fi 配置本身出了问题,而是 NetworkList 长期积累了多个网络身份记录。

比较完整的清理流程是:

读取活动网络
        ↓
读取全部 NetworkList Profiles
        ↓
找出数字后缀重复组
        ↓
备份 NetworkList
        ↓
保护当前活动 Profile
        ↓
删除数字后缀 Profiles
        ↓
删除对应 Signatures
        ↓
检查并清理 orphaned Signatures
        ↓
重新验证

核心原则可以概括成一句话:

整理 NetworkList,不等于删除 WLAN Profile。

只要严格限定操作范围,就可以清除多年积累的“网络 2、网络 3”历史记录,同时保留真正需要的 Wi-Fi 配置和密码。

Leave a Reply

Your email address will not be published. Required fields are marked *