在循环中使用Get-ItemProperty遍历RegistryKey集合的问题
解决PowerShell遍历注册表项筛选DisplayName的问题
首先,先看你原来的代码,有个明显的语法错误——最后少了一个闭合的},这会导致PowerShell无法正确执行命令,这可能是你没得到预期结果的核心原因之一。不过即使修正了语法,我们也可以优化逻辑,让它更简洁高效。
最简洁的正确写法
其实你完全不需要用ForEach-Object逐个处理,Get-ItemProperty可以直接接收Get-ChildItem返回的注册表项对象作为管道输入,所以逻辑可以简化成:
$arr = Get-ChildItem HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall $arr | Get-ItemProperty | Where-Object { $_.DisplayName -like "MyProgram*" }
这条命令会自动遍历所有注册表项,提取它们的属性,然后精准筛选出DisplayName匹配MyProgram*的项。
如需使用ForEach-Object的写法
如果因为某些场景必须用ForEach-Object逐个处理,除了补全缺失的},还可以加上对DisplayName属性存在性的判断(避免部分无该属性的项导致的潜在异常):
$arr | ForEach-Object { # 获取当前注册表项的属性 $itemProps = Get-ItemProperty -Path $_.PSPath # 先判断属性是否存在,再执行匹配逻辑 if ($itemProps.PSObject.Properties['DisplayName'] -and $itemProps.DisplayName -like "MyProgram*") { $itemProps } }
补充说明:原写法失效的可能原因
- 语法不完整:你提供的代码末尾缺失
},PowerShell无法解析完整命令,自然不会输出结果; - 无DisplayName属性的项干扰:部分注册表卸载项可能没有
DisplayName属性,当Where-Object尝试对比$null -like "MyProgram*"时会返回$false,但只要目标项存在,修正语法后就能正常匹配。
另外,你也可以把流程合并成一行,省去中间变量$arr,更符合PowerShell管道编程的风格:
Get-ChildItem HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall | Get-ItemProperty | Where-Object { $_.DisplayName -like "MyProgram*" }
内容的提问来源于stack exchange,提问作者LightningWar
相关产品推荐
相关产品推荐

