使用Get-ItemProperty通配符获取注册表属性,需返回匹配属性数组的问题
PowerShell注册表Get-ItemProperty筛选问题解决方案
问题场景回顾
注册表路径registry::HKEY_LOCAL_MACHINE\SOFTWARE\TestKey下有TestString1、TestString2、NotValid三个字符串属性:
- 执行
Get-ItemProperty -Path "registry::HKEY_LOCAL_MACHINE\SOFTWARE\TestKey" -Name "TestString*",返回结果包含匹配的属性,同时附带PSPath、PSParentPath等PowerShell内置属性,用Where-Object筛选时拿不到目标属性。 - 特殊情况:如果该路径下存在名为
TestString*的属性,原命令会返回所有属性+内置内容;换成-LiteralPath参数后,仅返回这个TestString*属性,这一行为未在官方文档中说明。
核心问题原因
Get-ItemProperty返回的是复合对象,既包含自定义注册表属性,也包含PowerShell自带的NoteProperty(如PSPath),直接用Where-Object筛选无法区分两类属性,导致筛选失效。-Path支持通配符解析,当存在与通配符表达式完全一致的字面量属性(如TestString*)时,PowerShell匹配逻辑会异常,返回所有属性;而-LiteralPath严格按字面量解析,不处理通配符,只会匹配名称完全一致的属性。
解决方法:仅获取匹配TestString*的属性数组
方法1:用Get-ItemPropertyValue直接获取(推荐)
PowerShell 5.1及以上版本提供的Get-ItemPropertyValue命令,会直接返回匹配的属性值,不会附带任何内置属性:
Get-ItemPropertyValue -Path "registry::HKEY_LOCAL_MACHINE\SOFTWARE\TestKey" -Name "TestString*"
如果需要同时获取属性名和值,可以结合Get-Item遍历:
$regKey = Get-Item "registry::HKEY_LOCAL_MACHINE\SOFTWARE\TestKey" $regKey.Property | Where-Object { $_ -like "TestString*" } | ForEach-Object { [PSCustomObject]@{ 属性名 = $_ 属性值 = $regKey.GetValue($_) } }
方法2:过滤Get-ItemProperty的返回结果
如果必须使用Get-ItemProperty,可以通过Get-Member区分内置属性和自定义属性:
$allProps = Get-ItemProperty -Path "registry::HKEY_LOCAL_MACHINE\SOFTWARE\TestKey" -Name "TestString*" $targetProps = $allProps | Get-Member -MemberType NoteProperty | Where-Object { $_.Name -like "TestString*" } | ForEach-Object { [PSCustomObject]@{ 属性名 = $_.Name 属性值 = $allProps.$($_.Name) } } $targetProps
这里通过Get-Member提取所有NoteProperty,再筛选出匹配TestString*的项,排除掉PS开头的内置属性。
关于-Path与-LiteralPath的特殊行为说明
- 当存在名为
TestString*的属性时,-Path配合-Name "TestString*"会触发异常逻辑:PowerShell会将通配符表达式与字面量属性名匹配,进而返回该注册表项的所有属性及内置内容,这属于文档未覆盖的边缘场景。 -LiteralPath的设计就是不解析任何通配符或转义字符,因此配合-Name "TestString*"时,会严格匹配名称为TestString*的属性,仅返回该属性的内容。
内容的提问来源于stack exchange,提问作者Gordon
相关产品推荐
相关产品推荐

