#powershell #registry #wildcard
Вопрос:
Дано…
HKLMSoftware 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_MACHINESOFTWAREKey*Name"
который вернется KeyName
, Key*Name
и Key@Name
, в то время как
Get-Item -literalPath:"Registry::HKEY_LOCAL_MACHINESOFTWAREKey*Name"
вернется только Key*Name
что . Пока все идет хорошо. Я могу использовать-path или -LiteralPath по мере необходимости для поиска ключа с подстановочными знаками или без них. Но свойства создают проблему.
Get-ItemProperty -path:"Registry::HKEY_LOCAL_MACHINESOFTWAREKeyName" -name:"Prop_[0-9]"
работает как ожидалось и возвращает Prop_1
amp; Prop_2
с KeyName
ключа. И
Get-ItemProperty -literalPath:"Registry::HKEY_LOCAL_MACHINESOFTWAREKeyName" -name:"Prop_[0-9]"
работает так, как ожидалось, и возвращается только Prop_[0-9]
с того же ключа. Но все это терпит неудачу, если вам нужно использовать подстановочный знак для поиска свойств в пути, который включает подстановочный символ в качестве литерала в пути к ключу. Так…
Get-ItemProperty -path:"Registry::HKEY_LOCAL_MACHINESOFTWAREKey*Name" -name:"Prop_[0-9]"
возвращает Prop_1
amp; Prop_2
со всех трех ключей. Совсем не желаемое поведение.
Я надеялся, что смогу фильтровать при PSPath
использовании -`LiteralPath’, но это
Get-ItemProperty -literalPath:"Registry::HKEY_LOCAL_MACHINESOFTWAREKey*Name" -name:"Prop_[0-9]" | where {$_.PSPath -match [RegEx]::Escape("Key*Name")}
не возвращает правильные свойства. Похоже, что a -literalPath
также означает буквальное имя. Поэтому я попробовал фильтровать PSPath
и Name
вот так
Get-ItemProperty -literalPath:"Registry::HKEY_LOCAL_MACHINESOFTWAREKey*Name" -name:"Prop_[0-9]" | where {(($_.PSPath -match [RegEx]::Escape("Key*Name")) -and ($_.Name -match "Prop_[0-9]"))}
Но это не работает, потому что, как только вы действительно получаете реальные свойства, они больше не относятся к типу .NET, они были превращены в PSCustomObject
. И это начинает становиться настолько сложным, что я задаюсь вопросом, есть ли лучший способ продолжить. Я должен отметить, что конечная цель здесь-получить как буквальный путь, так и список буквенных имен свойств, чтобы я мог перемещать, копировать или удалять свойства. Итак, учитывая путь Registry::HKEY_LOCAL_MACHINESOFTWAREKey*Name
и имя Prop_[0-9]
, я в конечном итоге захочу, например, удалить
HKEY_LOCAL_MACHINESOFTWAREKey*NameProp_1
amp;
HKEY_LOCAL_MACHINESOFTWAREKey*NameProp_2
но не
HKEY_LOCAL_MACHINESOFTWAREKey*NameProp_[0-9]
РЕДАКТИРОВАТЬ: Основываясь на ответе @Tomalak, я немного упростил, чтобы просто получить список имен свойств. Это выглядит так
$keyPath = "Registry::HKEY_LOCAL_MACHINESOFTWAREKey*Name" $propExpr = "Prop_[0-9]" ((Get-Item -literalPath:$keyPath | Get-ItemProperty).PSObject.Properties | Where-Object Name -Match $propExpr | ForEach-Object {$_.Name})
Ответ №1:
Это позволит получить раздел реестра по буквальному пути и отфильтровать его свойства по совпадению регулярных выражений
$keyPath = "Registry::HKEY_LOCAL_MACHINESOFTWAREKey*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
, если это более удобно для вашей задачи.
Комментарии:
1. Мне только что удалось заставить кое-что работать, а именно
Get-Item -literalPath 'HKLM:SOFTWAREKey*Name' | Select-Object -ExpandProperty property | Where {$_ -match "Prop_[0-9]"}
. Теперь у меня есть подход более общего назначения. Время для интеграции. Для тех, кто еще хочет , чтобы это сработало,-literalPath
$keyPath
не должно быть$key
, и$keyPath
нужно начинать сRegistry::
илиHKLM:
.2. @Гордон, Ты прав, это были оплошности, когда я переводил свой тестовый код. Исправлено.
3. Не беспокойтесь. На самом деле мне было действительно полезно по-настоящему понять ваш подход, чтобы заставить его работать. Лучший способ учиться. 🙂 Действительно рад, что у меня есть лучший подход в целом для работы с
PSCustomObject
типом возврата.4. @Гордон С PowerShell всегда есть несколько способов.
5. ЭТО очень верно. 🙂