You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过PowerShell获取与「更改或删除程序」一致的软件清单?

如何用PowerShell获取与「更改或删除程序」完全一致的软件清单

Windows的「更改或删除程序」可以展示已安装软件的名称、发布者、安装日期、大小及版本信息。目前通过读取注册表的PowerShell脚本获取清单时,部分软件的安装日期字段缺失,但该字段在控制面板中是存在的。已尝试过不推荐的Get-WmiObject -Class Win32_Product和Get-Package,需要找到能完全匹配控制面板清单的方法。

原脚本:

$uninstallPath = "\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\"
$uninstallWow6432Path = "\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\"
@(
    if (Test-Path "HKLM:$uninstallWow6432Path" ) { Get-ChildItem "HKLM:$uninstallWow6432Path"}
    if (Test-Path "HKLM:$uninstallPath" ) { Get-ChildItem "HKLM:$uninstallPath" }
    if (Test-Path "HKCU:$uninstallWow6432Path") { Get-ChildItem "HKCU:$uninstallWow6432Path"}
    if (Test-Path "HKCU:$uninstallPath" ) { Get-ChildItem "HKCU:$uninstallPath" }
) |
ForEach-Object { Get-ItemProperty $_.PSPath } |
Where-Object {
    $_.DisplayName -and !$_.SystemComponent -and !$_.ReleaseType -and !$_.ParentKeyName -and ($_.UninstallString -or $_.NoRemove)
} |
Sort-Object DisplayName | 
ForEach-Object -Process {
    echo "$($_.DisplayName);$($_.DisplayVersion);$($_.InstallDate)"
}

核心问题分析

部分软件的注册表Uninstall项中没有InstallDate值,但「更改或删除程序」会读取该注册表项的创建时间来填充安装日期,这是原脚本缺失的关键逻辑。

优化后的脚本

以下脚本保留原注册表筛选逻辑,同时补全缺失的安装日期,还会匹配控制面板的所有核心字段:

$uninstallPaths = @(
    "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\",
    "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\",
    "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\",
    "HKCU:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\"
)

# 遍历所有注册表路径,收集有效项
$installedSoftware = foreach ($path in $uninstallPaths) {
    if (Test-Path $path) {
        Get-ChildItem $path | ForEach-Object {
            $regItem = Get-ItemProperty $_.PSPath
            # 筛选条件和控制面板一致:排除系统组件、更新、父项等
            if ($regItem.DisplayName -and !$regItem.SystemComponent -and !$regItem.ReleaseType -and !$regItem.ParentKeyName -and ($regItem.UninstallString -or $regItem.NoRemove)) {
                # 处理安装日期:优先用注册表的InstallDate,否则用注册表项的创建时间
                $installDate = if ($regItem.InstallDate) {
                    [DateTime]::ParseExact($regItem.InstallDate, "yyyyMMdd", $null).ToString("yyyy-MM-dd")
                } else {
                    $_.CreationTime.ToString("yyyy-MM-dd")
                }

                # 处理大小:注册表的EstimatedSize是KB,转换为MB(保留1位小数)
                $size = if ($regItem.EstimatedSize) {
                    [math]::Round($regItem.EstimatedSize / 1024, 1)
                } else {
                    "N/A"
                }

                # 输出匹配控制面板的字段
                [PSCustomObject]@{
                    名称       = $regItem.DisplayName
                    发布者     = $regItem.Publisher ?? "N/A"
                    安装日期   = $installDate
                    大小(MB)   = $size
                    版本       = $regItem.DisplayVersion ?? "N/A"
                }
            }
        }
    }
}

# 按名称排序并输出
$installedSoftware | Sort-Object 名称 | Format-Table -AutoSize
# 如果需要导出为CSV,取消下面注释
# $installedSoftware | Sort-Object 名称 | Export-Csv -Path "已安装软件清单.csv" -Encoding UTF8 -NoTypeInformation

关键优化点说明

  • 安装日期补全:当注册表无InstallDate时,读取注册表项的创建时间,和「更改或删除程序」的显示逻辑完全一致。
  • 字段匹配:包含控制面板的所有核心字段,大小字段将注册表的KB值转换为MB,符合日常认知。
  • 筛选逻辑对齐:保留原脚本的筛选条件,确保只显示控制面板中可见的软件(排除系统组件、更新包、嵌套安装的父项等)。

为什么不推荐其他方法

  • Get-WmiObject -Class Win32_Product:仅识别MSI安装的软件,且会触发MSI的自动修复流程,可能导致系统问题。
  • Get-Package:数据源和「更改或删除程序」不完全一致,会包含一些控制面板不显示的组件(如Windows功能、更新包),且部分字段缺失。

内容的提问来源于stack exchange,提问作者Fran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 08:12:42