首页 > 解决方案 > Powershell、注册表和通配符,哦,我的

问题描述

鉴于...

HKLM\Software\   
  KeyName
    Property_1
    Property_2
    Property_[0-1] 
  Key*Name
    Property_1
    Property_2
    Property_[0-1]   
  Key@Name
    Property_1
    Property_2
    Property_[0-1]

我可以用

Get-Item -path:"Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Key*Name"

这将返回KeyName,Key*NameKey@Name, 而

Get-Item -literalPath:"Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Key*Name"

将返回只是Key*Name。到现在为止还挺好。我可以根据需要使用 -path 或 -literalPath 来搜索带有通配符的键。但是属性会带来问题。

Get-ItemProperty -path:"Registry::HKEY_LOCAL_MACHINE\SOFTWARE\KeyName" -name:"Prop_[0-9]"

按预期工作并从密钥返回Prop_1& 。和Prop_2KeyName

Get-ItemProperty -literalPath:"Registry::HKEY_LOCAL_MACHINE\SOFTWARE\KeyName" -name:"Prop_[0-9]"

按预期工作并仅从Prop_[0-9]同一个键返回。但是,当您需要使用通配符在包含通配符作为键路径中的文字的路径中查找属性时,一切都会失败。所以...

Get-ItemProperty -path:"Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Key*Name" -name:"Prop_[0-9]"

从所有三个键返回Prop_1& 。Prop_2根本不是想要的行为。

我曾希望能够PSPath使用 -`literalPath' 进行过滤,但这

Get-ItemProperty -literalPath:"Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Key*Name" -name:"Prop_[0-9]" | where {$_.PSPath -match [RegEx]::Escape("Key*Name")}

不返回正确的属性。似乎 a-literalPath也意味着字面名称。所以我试着过滤PSPathName就像这样

Get-ItemProperty -literalPath:"Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Key*Name" -name:"Prop_[0-9]" | where {(($_.PSPath -match [RegEx]::Escape("Key*Name")) -and ($_.Name -match "Prop_[0-9]"))}

但这不起作用,因为一旦您真正获得了真正的属性,它们就不再是 .NET 类型,它们已被转换为PSCustomObject. 这开始变得如此复杂,我想知道是否有更好的方法来进行。我应该注意,这里的最终目标是获取文字路径和文字属性名称列表,以便我可以移动、复制或删除属性。因此,给定路径Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Key*Name和名称,Prop_[0-9]我最终会想要,例如,删除

HKEY_LOCAL_MACHINE\SOFTWARE\Key*Name\Prop_1 

&

HKEY_LOCAL_MACHINE\SOFTWARE\Key*Name\Prop_2

但不是

HKEY_LOCAL_MACHINE\SOFTWARE\Key*Name\Prop_[0-9]

编辑:根据@Tomalak 的回答,我进行了一些简化,以简单地获取属性名称列表。看起来像这样

$keyPath = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Key*Name"
$propExpr = "Prop_[0-9]"
((Get-Item -literalPath:$keyPath | Get-ItemProperty).PSObject.Properties | Where-Object Name -Match $propExpr | ForEach-Object {$_.Name})

标签: powershellregistrywildcard

解决方案


这将通过文字路径获取注册表项并通过正则表达式匹配过滤其属性

$keyPath = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Key*Name"
$propExpr = "Prop_[0-9]"

Get-Item -literalPath $keyPath -PipelineVariable key | Get-ItemProperty | ForEach-Object {
    $_.PSObject.Properties | Where-Object Name -Match $propExpr | ForEach-Object {
        [pscustomobject]@{
            key = $key.Name
            prop = $_.Name
            value = $_.Value
        }
    }
}

如果这对您的任务更方便,您$key.Name当然可以返回实际值,而不是。$key


推荐阅读