我如何得到一个注册表项的值和只有值使用 Powershell

有人能帮我提取注册表项的值并将其放入 PowerShell 中的变量吗?到目前为止,我已经使用了 Get-ItemPropertyreg query,尽管它们都会拉取值,但都会添加额外的文本。我只需要从注册表项的字符串文本和只有字符串文本的关键。我确信我可以创建一个函数来去掉额外的文本,但是如果有什么变化(比如 reg 键名) ,它可能会影响这一点。

263167 次浏览

你得说得具体点。据我所知,注册表中的键是属性的“文件夹”。你的意思是得到房产的价值吗?如果是这样,试试这样的方法:

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

首先,我们得到一个包含 Get-ItemProperty所需属性的对象,然后从该对象获得所需属性的值。将该属性的值作为字符串返回。上面的示例为您提供了“遗留”/兼容性的 PS 版本-mdoe powershell (1.0或2.0)。

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

我从来不喜欢这个提供程序是这样实现的:/

基本上,它使每个注册表值为 PSCustomObject对象,具有 PsPathPsParentPathPsChildnamePSDrivePSProvider属性,然后为其实际值设置一个属性。因此,即使你要求的项目的名称,得到它的价值,你必须使用一次的名称。

我不确定这是否已经被修改,或者它是否与你正在使用的 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

下面的代码将枚举某个 Registry 键的所有值,对它们进行排序,并返回由冒号(:)分隔的值名:

$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\

Harry Martyrossian 在 他自己的答案的评论中提到
Get-ItemPropertyValue cmdlet 是在 Powershell v5中引入的,它解决了这个问题:

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)可以在块中简单地使用两次。

或者,一个简单的 helper 函数可以减轻痛苦:

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

注意: 搭桥手术以上的所有解决方案都与 Ian Kemp 的的答案中描述的问题相同——当使用 财产名称时,需要对某些值名称使用显式引号; 例如,.'15.0'——因为值名称作为 参数传递,而属性访问通过 变量进行; 例如,.$ValueName


至于其他答案:

如果你创建一个对象,你会得到一个可读性更好的输出,也会得到一个你可以访问的属性对象:

$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 框架

目标是: $obj. InstallRoot = C: Windows Microsoft.NET Framework

事情的真相是这比它需要的要复杂得多。这里有一个更好、更简单的例子:

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

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

write-output $objReg


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

你可以接触到物体本身:

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

这些答案都不适用于值名包含空格、点或 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中都适用(尽管您可能应该在 v5中使用 Get-ItemPropertyValue)。

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

enter image description here

我会选择“ MSSQLSERVER”,在以下情况下,我不确定属性名将使用点符号:

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

不确定这个功能到达了什么版本,但是您可以使用类似的东西来返回一个数组中多个子注册表项的所有属性:

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

只是添加了这一点,因为谷歌把我带到这里有一个相关的原因,我最终想出了上述一行程序疏通注册表。