如何使用Powershell与注册表一起工作?

时间:2016-01-15 09:37:20

标签: powershell registry

显然,我的Google-fu在查找有关如何在Powershell脚本中使用Windows注册表的完整但可理解的教程方面很弱(而不是在PS shell中交互式)。注册表使用"键名值"结构,但以某种方式访问​​"相同的文件系统目录"简直让我困惑。

假设我有一个注册表:

HKLM
  KeyA
    NameA1=ValueA1
  KeyB
    NameB1=ValueB1
  KeyC
    NameC1=ValueC1
    NameC2=ValueC2
    NameC3=ValueC3
    KeyCA
      NameCA1=ValueCA1
    KeyCB
      NameCB1=ValueCB1

执行以下操作的最正确方法是什么:

  1. 检查KeyA是否存在?
  2. 检查NameB1是否存在?
  3. 获取密钥中第一个/唯一项目的名称和价值部分(例如NameC1ValueC1),因为我不知道该名称的名称item(只有密钥的路径)?
    • 目前,我粗略地使用Get-ItemProperty来获取@{name=value}并应用一些字符串拆分。
  4. (更一般地说:)迭代KeyC中的所有名称(所以NameC1, NameC2, NameC3),假设可能有零个或多个项目?
  5. KeyCKeyCA, KeyCB)中对所有子项进行迭代,假设可能有零个或多个项目?
  6. 重命名密钥(例如,NameB1NameB2);或创建具有相同类型和值的新密钥,并删除旧密钥?
  7. 根据我知道密钥和名称,更改值(例如ValueC3ValueC5)?
  8. 我知道我可以将Get-ChildItem用于某些事情,而Get-ItemProperty则可以用于其他事情,但我不理解它并且在运气不佳的情况下摸索着。我如何最好地将这些应用于我列出的需求?

    *(相关但非偏离主题:对于Powershell而言,' pythonic'等同于什么?)

1 个答案:

答案 0 :(得分:2)

我试图回答下面的每个问题,但我建议您阅读help file about PS Providers(将注册表映射为文件系统的抽象层):

help about_Providers
  

检查KeyA是否存在?

由于注册表的映射方式与文件系统类似,因此您可以使用Test-Path

PS> Test-Path HKLM:\KeyA
True
  

检查NameB1是否存在?

注册表提供程序将名称 - 值对视为项属性,检查Get-ItemProperty是否返回任何内容:

PS>[bool](Get-ItemProperty HKLM:\KeyA -Name NameB1)
True
  

获取密钥中第一个/唯一项目的名称和值 - 部分(例如,NameC1和ValueC1),因为我不知道该项目的名称(只有密钥的路径) )?

同样,注册表可以像文件系统一样对待,您可以使用Get-Item来检索任何密钥。与实际文件系统的不同之处在于返回的对象类型为Microsoft.Win32.RegistryKey而不是System.IO.FileInfo。注册表项对象具有GetValueNames()方法,可用于检索值名称:

PS> $RegKey = Get-Item HKLM:\KeyC
PS> $RegKey.GetValueNames()
NameC1
NameC2
NameC3

要获得第一个:

PS> $RegKey = Get-Item HKLM:\KeyC
PS> $ValueName = $RegKey.GetValueNames() |Select-Object -First 1
PS> Get-ItemProperty $RegKey.PSPath -Name $ValueName |Select-Object $ValueName

如果您希望该值,请将-ExpandPropertySelect-Object一起使用:

PS> Get-ItemProperty $RegKey.PSPath -Name $ValueName |Select-Object -ExpandProperty $ValueName
  

迭代KeyC中的所有名称(所以NameC1,NameC2,NameC3),假设可能有零个或多个项目?

再次使用GetValueNames()方法:

foreach($ValueName in ($Key = Get-Item HKLM:\KeyC).GetValueNames())
{
    "{0} has value {1}" -f $ValueName,$Key.GetValue($ValueName)
}
  

迭代KeyC中的所有子键(所以KeyCA,KeyCB),假设可能有零个或多个项目?

像在常规文件系统中一样使用Get-ChildItem

PS> Get-ChildItem HKLM:\KeyC |Select -ExpandProperty Name
HKEY_LOCAL_MACHINE\KeyC\KeyCA
HKEY_LOCAL_MACHINE\KeyC\KeyCB
  

重命名密钥(例如,NameB1到NameB2);或创建具有相同类型和值的新密钥,并删除旧密钥?

对于(即KeyC),请使用Rename-Item

Rename-Item HKLM:\KeyC -NewName KeyD

对于值名称(即NameB1),请使用Rename-ItemProperty

Rename-ItemProperty HKLM:\KeyB -Name NameB1 -NewName NameB2

奖金问题:

  

*(相关但非偏离主题:对于Powershell而言,' pythonic'等同于什么?)

我不认为PowerShell已经存在了相当长的时间,但我个人会使用PowerShell-idiomatic或者#34; PowerShellian" :d