web-dev-qa-db-fra.com

Comment obtenir la valeur d'une clé de registre et UNIQUEMENT la valeur à l'aide de powershell

Quelqu'un peut-il m'aider à extraire la valeur d'une clé de registre et à la placer dans une variable de PowerShell? Jusqu'à présent, j'ai utilisé Get-ItemProperty et reg query et bien que les deux extrairont la valeur, les deux ajouteront également du texte supplémentaire. J'ai juste besoin du texte de chaîne de la clé de registre et UNIQUEMENT du texte de chaîne de la clé. Je suis sûr que je pourrais créer une fonction pour enlever le texte supplémentaire, mais si quelque chose change (c'est-à-dire le nom de la clé de registre), cela pourrait l'affecter.

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

Je n'ai jamais aimé comment ce fournisseur a été implémenté comme ceci: /

Fondamentalement, chaque valeur de registre devient un objet PSCustomObject avec les propriétés PsPath, PsParentPath, PsChildname, PSDrive et PSProvider, puis une propriété pour sa valeur réelle. Ainsi, même si vous avez demandé l'élément par son nom, vous devez utiliser le nom une nouvelle fois pour obtenir sa valeur.

83
Andy Arismendi

Aucune de ces réponses ne fonctionne dans les situations où le nom de la valeur contient des espaces, des points ou d’autres caractères réservés dans PowerShell. Dans ce cas, vous devez mettre le nom entre guillemets, comme indiqué dans http://blog.danskingdom.com/accessing-powershell-variables-with-periods-in-their-name/ -, par exemple:

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

Si vous souhaitez accéder à l'une des valeurs 14.0, 12.0, 11.0, 15.0, la solution de la réponse acceptée ne fonctionnera pas - vous n'obtiendrez aucun résultat:

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

Qu'est-ce que le travail cite le nom de la valeur, ce que vous devriez probablement faire de toute façon pour la sécurité:

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> 

Ainsi, la réponse acceptée devrait être modifiée en tant que telle:

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> 

Cela fonctionne dans PowerShell 2.0 à 5.0 (même si vous devriez probablement utiliser Get-ItemPropertyValue in v5).

18
Ian Kemp
  • La réponse utile de Andy Arismendi explique le désagrément de devoir répéter le nom de la valeur pour obtenir les données de la valeur efficacement.
  • La réponse utile de M Jeremy Carter est plus pratique, mais peut être un piège de performance pour les clés avec un grand nombre de valeurs, car un objet avec un grand nombre de propriétés doit être construit.

Remarque: Toutes les solutions ci-dessous contournement le problème décrit dans La réponse de Ian Kemp - est la nécessité d'utiliser des guillemets explicites pour certains noms de valeur lorsque propriété noms; Par exemple, .'15.0' - car les noms de valeur sont passés sous la forme paramètres et l'accès aux propriétés se fait par l'intermédiaire d'un variable; Par exemple, .$ValueName

Harry Martyrossian mentionne dans un commentaire sur sa propre réponse que le
Get-ItemPropertyValue La cmdlet a été introduite dans Powershell v5, ce qui résout le problème:

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

Alternatives pour PowerShell v4-:

Voici une tentative pour conserver l'efficacité tout en éliminant le besoin de répéter le nom de la valeur, qui reste toutefois un peu fastidieux:

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

En utilisant un bloc de script, le nom de la valeur peut être passé dans une fois en tant que paramètre, et la variable de paramètre ($args) peut ensuite être simplement utilisée deux fois à l'intérieur du bloc.

Alternativement, une fonction d'assistance simple peut soulager la douleur:

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

Je ne sais pas si cela a été modifié ou s'il a quelque chose à voir avec la version de PS que vous utilisez, mais avec l'exemple d'Andy, je peux supprimer le paramètre -Name et obtenir toujours la valeur de l'élément 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
M Jeremy Carter

Eh bien, vous devez être spécifique ici. Autant que je sache, la clé d'un registre est un "dossier" de propriétés. Alors voulez-vous dire obtenir la valeur d'une propriété? Si oui, essayez quelque chose comme ceci:

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

Nous obtenons d’abord un objet contenant la propriété dont nous avons besoin avec Get-ItemProperty, puis nous obtenons la valeur de pour la propriété dont nous avons besoin de cet objet. Cela renverra la valeur de la propriété sous forme de chaîne. L'exemple ci-dessus vous donne la version PS pour "legacy"/compatibilité-mdoe powershell (1.0 ou 2.0).

2
Frode F.

Étant donné une clé \SQL avec deux propriétés:

 enter image description here

Je prenais celui "MSSQLSERVER" avec les cas suivants où je n'étais pas sûr du nom de la propriété qui allait utiliser la notation par points:

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

Le code suivant énumère toutes les valeurs d’une clé de registre donnée, les trie et renvoie les paires nom-valeur: valeur séparées par deux points (:):

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

Comme ça:

DbgJITDebugLaunchSetting: 16

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

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

1
Harry Martyrossian

Si vous créez un objet, vous obtenez une sortie plus lisible et vous obtenez également un objet avec des propriétés auxquelles vous pouvez accéder:

$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

Exemple de sortie: InstallRoot: C:\Windows\Microsoft.NET\Framework \

Et l’objet: $ Obj.InstallRoot = C:\Windows\Microsoft.NET\Framework \

La vérité, c’est bien plus compliqué que nécessaire. Voici un exemple bien meilleur et beaucoup plus simple:

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

$ objReg est maintenant un objet personnalisé où chaque entrée de registre est un nom de propriété. Vous pouvez voir la liste formatée via:

write-output $objReg

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

Et vous avez accès à l'objet lui-même:

$objReg.InstallRoot
C:\Windows\Microsoft.NET\Framework\
0
Steve Fellwock