2013-03-19 4 views
45

Может ли кто-нибудь помочь мне вытащить значение раздела реестра и поместить его в переменную в PowerShell? До сих пор я использовал Get-ItemProperty и reg query, и хотя оба будут тянуть значение, оба также добавляют дополнительный текст. Мне нужен только текст строки из раздела реестра и ТОЛЬКО текст строки из ключа. Я уверен, что я мог бы создать функцию, чтобы удалить лишний текст, но если что-то изменится (то есть имя ключа reg), это может повлиять на это.Как получить значение раздела реестра и ТОЛЬКО значение using powershell

+0

Это хороший вопрос, но обратите внимание, что 'Get-ItemProperty' не добавляет дополнительный _text_; вместо этого он возвращает _object_, один из которых _properties_ содержит нужные данные. Дополнительный текст поступает из выходного форматирования по умолчанию возвращаемого объекта (представление структуры объекта). – mklement0

ответ

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

Я никогда не любил, как это было поставщик был реализован так:/

В основном, это делает каждый параметр реестра PSCustomObject объект PsPath, PsParentPath, PsChildname, PSDrive и PSProvider свойства, а затем для его фактической стоимости. Поэтому, даже если вы попросили элемент по имени, чтобы получить его значение, вам нужно снова использовать имя.

+3

Привет @Andy: Почему бы просто не просто (Get-ItemProperty -Path $ key) .ProgramFilesDir', чтобы избежать избыточности? Это подходит для меня; но есть ли они в некоторых случаях, когда это не ...? –

+1

@msorens См. Ответы Charleswj81 на M Джереми Картера. –

2

Ну, вам нужно быть конкретным здесь. Насколько я знаю, ключ в реестре - это «папка» свойств. Значит, вы имели в виду получить стоимость имущества? Если это так, попробуйте что-то вроде этого:

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

Сначала мы получаем объект, содержащий свойство, нам нужно с Get-ItemProperty и тогда мы получим значение для свойства нам нужно от этого объекта. Это вернет значение свойства в виде строки. Пример выше дает вам версию PS для «устаревшей»/совместимости-mdoe powershell (1.0 или 2.0).

4

Я не уверен, что это было изменено, или если оно имеет какое-то отношение к какой версии PS вы используете, но с использованием примера Энди я могу удалить параметр -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 
+3

Это и всегда было так. В вашем подходе нет ничего технически неправильно, однако он менее эффективен, чем указание конкретных свойств для возврата. Ваш метод будет запрашивать все свойства и затем отфильтровывать их перед возвратом. – charleswj81

+3

Чтобы проиллюстрировать это, см. Разницу - это время, в течение которого выполняются следующие два однолинейных элемента 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

0

После код будет перечислять все значения для определенного ключа реестра, сортирует их и возвратит имя значения: пары значений, разделенных двоеточием (:):

$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; }; 

Like это:

DbgJITDebugLaunchSetting: 16

DbgManagedDebugger: "C: \ Windows \ system32 \ vsjitdebugger.exe" PID% d APPDOM% d EXTEXT "% S" EVTHDL% d

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

+0

Вопрос заключался в получении _data_ значения _specific_ value, без дополнительной информации. Помимо этого, ваш код полагается на вызовы методов .NET для тех вещей, которые можно сделать более легко сделать изначально в PowerShell. – mklement0

+1

Для PowerShell v. 5.0 и выше используйте новый командлет - Get-ItemPropertyValue: '$ value = Get-ItemPropertyValue -Path $ regKeyPath -Name $ valueName;' –

+1

Использование v5 + 'Get-ItemPropertyValue' - отличный совет , благодаря. Хотя с тех пор вы уже немного больше ответили на PowerShell, он по-прежнему отвечает на вопрос, который не задавался, и ответ, который вы дадите, по-прежнему далек от того, чтобы быть PowerShell-идиоматичным. Более идиоматическая версия: '(Get-ItemProperty 'HKLM: \ SOFTWARE \ Microsoft \ .NETFramework'). Psobject.properties | ? Имя - не похоже на «PS *» | Имя сортировочного объекта | Select-Object Name, Value'. Кроме того, если вы не хотите размещать несколько операторов в строке, нет причин для прекращения операторов с ';'. – mklement0

8
  • Andy Arismendi's helpful answer объясняет досаду с необходимостью повтора название значение для того, чтобы получить данные о стоимости эффективно.
  • M Jeremy Carter's helpful answer более удобно , но может быть производительности ловушкой для ключей с большим количеством значений, так как объект с большим количеством свойств должно быть построено.

Update: Гарри Martyrossian упоминает в комментарии his own answer что
Get-ItemPropertyValue cmdlet был введен в Powershell v5, который решает эту проблему:

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

Alt ernatives для 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 
} 
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.InstallRo ot = 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\ 
10

НИ ОДИН из этих ответов не работать в ситуациях, когда имя значение содержит пробелы, точки, или другие символы которые зарезервированы в 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 (хотя вы Shoul d, вероятно, следует использовать Get-ItemPropertyValue в версии 5).

Смежные вопросы