PowerShell通过注册表查询指定发布商软件:多通配符匹配失效
解决PowerShell多发布商通配符匹配已安装软件无结果的问题
问题原因
你的脚本在多发布商匹配时无结果,核心错误在于第二个foreach循环中,Where-Object条件里误用了整个发布商数组$SoftwarePub,而非当前循环的单个发布商规则$pub。此外,这种循环匹配的方式效率较低,且容易出现输出格式问题。
修正后的代码
方法一:修正循环变量(基础修复)
$HKLM = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*" $HKLM_Wow = "HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" $HKCU = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*" $InstalledSoftware = Get-ChildItem $HKLM, $HKLM_Wow, $HKCU $allSoftware = [System.Collections.ArrayList]@() $SoftwarePub = [System.Collections.ArrayList]@("Microsoft*", "Dell*") foreach($obj in $InstalledSoftware) { $software = [PSCustomObject]@{ DisplayName = $obj.GetValue("DisplayName") Version = $obj.GetValue("DisplayVersion") Publisher = $obj.GetValue("Publisher") InstallDate = $obj.GetValue("InstallDate") } $null = $allSoftware.Add($software) } # 修正循环内的匹配变量,并合并结果 $matchingSoftware = @() foreach ($pub in $SoftwarePub) { $matchingSoftware += $allSoftware | Where-Object {$_.Publisher -like $pub} } # 去重并输出 $matchingSoftware | Select-Object -Unique DisplayName, Version, Publisher, InstallDate
方法二:更高效的无循环匹配(推荐)
直接在Where-Object中判断是否匹配任意一个通配符规则,避免额外循环:
$HKLM = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*" $HKLM_Wow = "HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" $HKCU = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*" $SoftwarePub = @("Microsoft*", "Dell*") Get-ChildItem $HKLM, $HKLM_Wow, $HKCU | ForEach-Object { [PSCustomObject]@{ DisplayName = $_.GetValue("DisplayName") Version = $_.GetValue("DisplayVersion") Publisher = $_.GetValue("Publisher") InstallDate = $_.GetValue("InstallDate") } } | Where-Object { # 检查Publisher是否匹配任意一个通配符规则 $publisher = $_.Publisher $SoftwarePub | ForEach-Object { $publisher -like $_ } | Where-Object { $_ } } | Select-Object -Unique DisplayName, Version, Publisher, InstallDate
关键说明
- 变量误用修正:原代码中
$_.Publisher -like $SoftwarePub错误地将整个数组作为匹配规则,改为$_.Publisher -like $pub后,才能正确使用单个通配符规则进行匹配。 - 输出优化:添加
Select-Object -Unique避免同一软件因多注册表项重复显示。 - 脚本简化:使用
[PSCustomObject]替代New-Object和Add-Member,代码更简洁易读;直接通过管道处理对象,省去ArrayList的额外操作。
内容的提问来源于stack exchange,提问作者JohnA2023
相关产品推荐
相关产品推荐

