如何获取注册表项的值,并且仅使用Powershell获得值


74

谁能帮助我提取注册表项的值并将其放入PowerShell中的变量中?到目前为止,我已经使用了Get-ItemPropertyreg query尽管两者都会提取值,但是两者都还会添加额外的文本。我只需要注册表项中的字符串文本,而只需要注册表项中的字符串文本。我确定我可以创建一个函数来删除多余的文本,但是如果某些更改(即reg键名)可能会影响到此功能。


这是一个很好的问题,但是请注意,Get-ItemProperty它不会添加多余的文字;而是返回一个对象,其属性之一包含所需的数据。额外的文本来自返回对象的默认输出格式(对象结构的表示形式)
。– mklement0

Answers:


114
$key = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion'
(Get-ItemProperty -Path $key -Name ProgramFilesDir).ProgramFilesDir

我从来不喜欢这样的提供者是如何实现的:/

基本上,它使每一个注册表值PSCustomObject与对象PsPathPsParentPathPsChildnamePSDrivePSProvider属性,然后为它的实际值的属性。因此,即使您按名称要求输入商品,也要再次使用该名称才能获得其价值。


9
嗨,@安迪:为什么不只是(Get-ItemProperty -Path $key).ProgramFilesDir为了避免冗余?这对我行得通; 但是在某些情况下不会...吗?
Michael Sorens

3
@msorens请参阅charleswj81对M Jeremy Carter的回复。
Andy Arismendi 2013年

26

在值名称包含空格,点或PowerShell中保留的其他字符的情况下,这些答案均无效。在这种情况下,您必须按照http://blog.danskingdom.com/accessing-powershell-variables-with-periods-in-their-name/将名称用双引号引起来-例如:

PS> Get-ItemProperty Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\SxS\VS7

14.0         : C:\Program Files (x86)\Microsoft Visual Studio 14.0\
12.0         : C:\Program Files (x86)\Microsoft Visual Studio 12.0\
11.0         : C:\Program Files (x86)\Microsoft Visual Studio 11.0\
15.0         : C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\
PSPath       : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\SxS\V
               S7
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\SxS
PSChildName  : VS7
PSProvider   : Microsoft.PowerShell.Core\Registry

如果要访问14.0、12.0、11.0、15.0中的任何一个值,则接受的答案中的解决方案将不起作用-您将不会获得任何输出:

PS> (Get-ItemProperty Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\SxS\VS7 -Name 15.0).15.0
PS>

起作用的是引用值名称,出于安全考虑,您可能应该这样做:

PS> (Get-ItemProperty "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\SxS\VS7" -Name "15.0")."15.0"
C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\
PS> 

因此,应将接受的答案修改为:

PS> $key = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\SxS\VS7"
PS> $value = "15.0"
PS> (Get-ItemProperty -Path $key -Name $value).$value
C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\
PS> 

这可以在PowerShell 2.0到5.0中运行(尽管您可能应该Get-ItemPropertyValue在v5中使用)。


为了节省字幕时间,您可以将属性名称放入变量中并像下面一样引用它:
Justin

21

哈里·马蒂罗斯(Harry Martyrossian)在对自己的答案的评论中提到,Powershell v5中引入了
Get-ItemPropertyValue cmdlet ,它解决了该问题:

PS> Get-ItemPropertyValue 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion' 'ProgramFilesDir'
C:\Program Files

PowerShell v4-的替代方案:

这是一种在保持效率的同时避免重复使用值名称的尝试,但是,这仍然有些麻烦:

& { (Get-ItemProperty `
      -LiteralPath HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion `
      -Name $args `
    ).$args } 'ProgramFilesDir'

通过使用脚本块,值名称可以作为参数传递一次$args然后可以在该块内部简单地两次使用参数变量()。

另外,一个简单的辅助函数可以减轻痛苦:

function Get-RegValue([String] $KeyPath, [String] $ValueName) {
  (Get-ItemProperty -LiteralPath $KeyPath -Name $ValueName).$ValueName
}

注意:以上所有解决方案都绕过Ian Kemp答案中描述的问题-当用作属性名称时,需要对某些值名称使用显式引号;例如,.'15.0'-因为值名称作为参数传递,并且属性访问是通过变量进行的;例如,.$ValueName


至于其他答案:


6

我不确定这是否已更改,或者是否与您使用的PS版本有关,但是使用Andy的示例,我可以删除-Name参数,但仍会获得reg项目的值。 :

PS C:\> $key = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion'
PS C:\> (Get-ItemProperty -Path $key).ProgramFilesDir
C:\Program Files


PS C:\> $psversiontable.psversion

Major  Minor  Build  Revision
-----  -----  -----  --------
2      0      -1     -1

6
情况一直如此。您的方法在技术上没有什么问题,但是它比指定要返回的特定属性效率低。您的方法将查询所有属性,然后在返回之前将其过滤掉。
charleswj81

5
为说明起见,区别在于以下两个PowerShell单行代码运行所需的时间:measure-command{1..10|%{[void]( Get-ItemProperty HKLM:\software\microsoft\windows\currentversion\installer\Folders -Name 'C:\Windows\PCHEALTH\' )}}measure-command{1..10|%{[void]( Get-ItemProperty HKLM:\software\microsoft\windows\currentversion\installer\Folders )}}
charleswj81 2013年

3

给定\SQL具有两个属性的键:

在此处输入图片说明

我在以下情况下抓住了“ MSSQLSERVER”,在这种情况下,我不确定使用点符号表示属性名称是什么:

$regkey_property_name = 'MSSQLSERVER'
$regkey = get-item -Path 'HKLM:\Software\Microsoft\Microsoft SQL Server\Instance Names\SQL'
$regkey.GetValue($regkey_property_name)

2

好吧,您需要在这里具体说明。据我所知,注册表中的键是属性的“文件夹”。那么,您的意思是得到财产的价值吗?如果是这样,请尝试以下操作:

(Get-ItemProperty HKLM:\Software\Microsoft\PowerShell\1\PowerShellEngine -Name PowerShellVersion).PowerShellVersion

首先,我们获得一个包含所需属性的对象Get-ItemProperty,然后从该对象获取所需属性的值。这将以字符串形式返回属性的值。上面的示例为您提供了用于“旧版” / compatibility-mdoe powershell(1.0或2.0)的PS版本。


1

以下代码将枚举某个注册表项的所有值,对它们进行排序并返回值名称:用冒号(:)分隔的值对:

$path = 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework';

Get-Item -Path $path | Select-Object -ExpandProperty Property | Sort | % {
    $command = [String]::Format('(Get-ItemProperty -Path "{0}" -Name "{1}")."{1}"', $path, $_);
    $value = Invoke-Expression -Command $command;
    $_ + ' : ' + $value; };

像这样:

DbgJITDebugLaunchSetting:16

DbgManagedDebugger:“ C:\ Windows \ system32 \ vsjitdebugger.exe” PID%d APPDOM%d EXTEXT“%s” EVTHDL%d

InstallRoot:C:\ Windows \ Microsoft.NET \ Framework \


问题是关于获取特定值的数据,而没有额外的信息。除此之外,您的代码还依赖.NET方法调用,这些操作可以在PowerShell中以本机方式轻松完成。
mklement0 '16

1
对于PowerShell $value = Get-ItemPropertyValue -Path $regKeyPath -Name $valueName;
v。5.0

1
Get-ItemPropertyValue谢谢,使用v5 +是一个很好的技巧。从那以后,您的答案变得有点像PowerShell,但它仍然可以回答未曾提出的问题,而且您给出的答案仍然远非PowerShell惯用的。更为惯用的版本是:(Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\.NETFramework').psobject.properties | ? Name -notlike 'PS*' | Sort-Object Name | Select-Object Name, Value。另外,除非要在一行上放置多个语句,否则没有理由用终止语句;
mklement0 '16

1

不确定此功能到达哪个版本,但是您可以使用类似这样的方法来返回数组中多个子注册表项的所有属性:

$InstalledSoftware = Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" | ForEach-Object {Get-ItemProperty "Registry::$_"}

只是由于Google的相关原因才将其添加到这里,我最终想出了上述一类信息来疏通注册表。


0

如果创建对象,则将获得更具可读性的输出,并获得具有可访问属性的对象:

$path = 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework'
$obj  = New-Object -TypeName psobject

Get-Item -Path $path | Select-Object -ExpandProperty Property | Sort | % {
$command = [String]::Format('(Get-ItemProperty -Path "{0}" -Name "{1}")."{1}"', $path, $_)
$value = Invoke-Expression -Command $command
$obj | Add-Member -MemberType NoteProperty -Name $_ -Value $value}

Write-Output $obj | fl

输出示例:InstallRoot:C:\ Windows \ Microsoft.NET \ Framework \

和对象:$ obj.InstallRoot = C:\ Windows \ Microsoft.NET \ Framework \

事实的真相是,这比需要的要复杂得多。这是一个更好的示例,并且更加简单:

$path = 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework'
$objReg = Get-ItemProperty -Path $path | Select -Property *

$ objReg现在是一个自定义对象,其中每个注册表项都是一个属性名称。您可以通过以下方式查看格式列表:

write-output $objReg

InstallRoot        : C:\Windows\Microsoft.NET\Framework\
DbgManagedDebugger : "C:\windows\system32\vsjitdebugger.exe"

您可以访问对象本身:

$objReg.InstallRoot
C:\Windows\Microsoft.NET\Framework\
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.