使用软件安装
可以通过 WMI 的查询找到随 Windows Installer 一起安装的应用程序,但并非所有应用程序都使用 Windows Installer。 查找随其他工具一起安装的应用程序的特定技术取决于安装程序软件。
例如,通常不能使用此处讨论的技术来管理通过将文件复制到计算机上的文件夹安装的应用程序。 可以使用在使用文件和文件夹中讨论的技术将这些应用程序作为文件和文件夹进行管理。
对于使用安装程序包安装的软件,可以使用 Win32Reg_AddRemovePrograms 或 Win32_Product 类找到 Windows Installer。 但是,这两者都有问题。 仅当使用 System Center Configuration Manager (SCCM) 时,Win32Reg_AddRemovePrograms 才可用。 Win32_Product 类可能很慢,并且有副作用。
注意
Win32_Product 类没有进行查询优化。 使用通配符筛选器的查询导致 WMI 使用 MSI 提供程序枚举所有已安装的产品,然后按顺序解析完整列表以处理该筛选器。 这还会启动已安装包的一致性检查,从而验证和修复安装。 验证是一个缓慢的过程,可能会导致事件日志中出现错误。 有关详细信息,请参阅知识库文章 974524。
本文提供了查找已安装软件的替代方法。
查询 Uninstall 注册表项以查找已安装的软件
由于大多数标准应用程序都向 Windows 注册了卸载程序,我们通过在 Windows 注册表中查找它们便可以在本地对其进行处理。 无法保证找到系统上的每个应用程序。 但可以在下列注册表项的“添加或删除程序”中显示的列表中查找所有程序:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall
。
我们可以通过计算注册表项的数量来找到已安装的应用程序数量:
$UninstallPath = 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall'
(Get-ChildItem -Path $UninstallPath).Count
459
我们可以使用各种技术进一步搜索此应用程序列表。 若要显示 Uninstall
下注册表项中的注册表值的值,请使用注册表项的 GetValue()
方法。 该方法的值是注册表条目的名称。 例如,若要查找 Uninstall
项中应用程序的显示名称,请使用以下命令:
Get-ChildItem -Path $UninstallPath |
ForEach-Object -Process { $_.GetValue('DisplayName') } |
Sort-Object
备注
不能保证 DisplayName 值是唯一的。
以下示例生成类似于 Win32Reg_AddRemovePrograms 类的输出:
Get-ChildItem $UninstallPath |
ForEach-Object {
$ProdID = ($_.Name -split '\\')[-1]
Get-ItemProperty -Path "$UninstallPath\$ProdID" -ea SilentlyContinue |
Select-Object -Property DisplayName, InstallDate, @{n='ProdID'; e={$ProdID}}, Publisher, DisplayVersion
} | Select-Object -First 3
为简洁起见,此示例使用 Select-Object
将返回的项数限制为三个。
DisplayName : 7-Zip 22.01 (x64)
InstallDate :
ProdID : 7-Zip
Publisher : Igor Pavlov
DisplayVersion : 22.01
DisplayName : AutoHotkey 1.1.33.10
InstallDate :
ProdID : AutoHotkey
Publisher : Lexikos
DisplayVersion : 1.1.33.10
DisplayName : Beyond Compare 4.4.6
InstallDate : 20230310
ProdID : BeyondCompare4_is1
Publisher : Scooter Software
DisplayVersion : 4.4.6.27483