Powershell, реестр и подстановочные знаки, о боже

#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. ЭТО очень верно. 🙂