Zum Hauptinhalt springen

Zugriff auf die Registry

Der Registry-Provider ermöglicht den komfortablen Zugriff auf die Systemregistrierung. Hierfür legt Powershell zwei Laufwerke an, HKLM: und HKCU:. HKLM verweist direkt auf den Registry-Hive Hkey_local_machine, während HKCU Zugriff auf die Benutzereinstellungen unter Hkey_Current_User ermöglicht.

Get-Item -Path HKLM:\SOFTWARE

Beim Zugriff auf die Registry gibt es eine Besonderheit zu beachten: Während die Darstellung im Regedit den Eindruck erweckt, dass ein Schlüssel (die Ordner-Symbole auf der linken Seite) einem Ordner entspricht, und die Eigenschaften (Properties) im rechten Fenster Dateien, sind die Eigenschaften in der Registry tatsächlich Eigenschaften des Schlüssels und sind als solche direkt mit dem Ordner verbunden.

image

Abbildung 5 - Der Registry-Key von 7-Zip

Ruft man, wie aus dem Dateisystem gewohnt, den Inhalt eines Schlüssels mit Get-Childitem auf, bekommt man ein unerwartetes Ergebnis:

get-childitem -Path HKCU:\Software\7-Zip\

> Name         Property
> ----         --------
> Compression  ShowPassword : 1
>              Level : 5
>              Archiver : zip
>              EncryptHeaders : 0
>              ArcHistory : {67, 0, 58, 0...}
> Extraction   PathHistory : {100, 0, 58, 0...}
>              ShowPassword : 1
> FM           CopyHistory : {68, 0, 58, 0...}
>              FolderShortcuts : {}
>              FolderHistory : {68, 0, 58, 0...}
>              PanelPath0 : D:\Downloads\
>              FlatViewArc0 : 0
>              PanelPath1 :
>              FlatViewArc1 : 0
>              ListMode : 771
>              Position : {100, 2, 0, 0...}
>              Panels : {1, 0, 0, 0...}
> Notepad

In der linken Spalte der Ausgabe sehen Sie die Namen der Unterschlüssel, wie man Sie in Abbildung 5 in der Baumansicht sehen kann. In der rechten Spalte sehen Sie die Eigenschaften, die den jeweiligen Unterschlüsseln zugeordnet sind. Aber die Eigenschaften des Schlüssels 7-zip, namentlich Notepad,Path und Path64, die Sie im Detailfenster von Abbildung 5 sehen können, werden nicht aufgelistet. Wenn Sie sich dagegen mit Get-Childitem im Dateisystem einen Ordner ansehen, bekommen sie immer auch die Dateien zu sehen, die sich im Ordner befinden.

Ursache dieser unterschiedlichen Darstellung ist, dass ein Ordner im Dateisystem und ein Schlüssel in der Registry zwei völlig unterschiedliche Typen von Objekten sind. Während ein Ordner nur ein Container für Dateien ist, gehören die Eigenschaften eines Schlüssels untrennbar zum Schlüssel. Wenn man sich einen Ordner als Ringbuchordner vorstellt, in den man beliebig Zettel einheften oder wieder entfernen kann, entspricht ein Registry-Schlüssel eher einem zusammengehefteten Notizbuch, in dem die Seiten fest mit dem Rest des Notizbuchs verbunden sind. Die Eigenschaften beschreiben in der Registry also den Schlüssel selbst und wären im Dateisystem mit den Eigenschaften eines Ordners vergleichbar, nicht mit den Dateien im Ordner.

Wenden Sie Get-Childitem auf HKCU:\Software\7-Zip an, sehen Sie die Eigenschaften von 7-Zip nicht, weil sie ja die Unterobjekte (Childitems) von 7-Zip abgerufen haben. Von den Unterschlüsseln sehen Sie dafür jetzt auch alle Eigenschaften.

Wenn man sich das vor Augen hält, sind einige Besonderheiten beim Zugriff auf die Systemregistrierung völlig logisch. Wenn Sie die Eigenschaften des Schlüssels 7-Zip sehen wollen, verwenden Sie also nicht Get-Childitem sondern Get-Item

get-item -Path HKCU:\Software\7-Zip\

> Hive: HKEY_CURRENT_USER\Software

> Name   Property
> ----   --------
> 7-Zip  Path64  : C:\Program Files\7-Zip\
>        Path    : C:\Program Files\7-Zip\
>        notepad : {77, 90, 144, 0...}

Um einen einzelnen Wert eines Schlüssels auszulesen, verwenden Sie Get-ItemProperty:

Get-ItemProperty -Path HKCU:\Software\7-Zip\ -Name Path64

> Path64       : C:\Program Files\7-Zip\
> PSPath       : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\7-Zip\
> PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software
> PSChildName  : 7-Zip PSDrive : HKCU
> PSProvider   : Microsoft.PowerShell.Core\Registry

Auch diese Rückgabe wirkt auf den ersten Blick merkwürdig, denn man möchte ja eigentlich nur den String haben, der für Path64 gespeichert ist, aber tatsächlich ist die Ausgabe konsistent, denn wir bekommen wie immer in Powershell ein Objekt zurück. Um nur die Eigenschaft Path64 des zurückgelieferten Objekts zu bekommen, müssen wir aus dem Objekt noch die Eigenschaft Path64 extrahieren:

(Get-ItemProperty -Path HKCU:\Software\7-Zip\ -Name Path64).Path64
C:\Program Files\7-Zip\

 Ab Powershell 5 wird das einfacher, denn Microsoft hatte ein Einsehen und hat ein Cmdlet eingeführt, dass nur den Wert eines Registry-Eintrags zurückliefert:

Get-ItemPropertyValue -Path HKCU:\Software\7-Zip\ -Name Path64
C:\Program Files\7-Zip\

Wenn man diese Unterschiede zwischen Dateisystem und Registry verstanden hat, ist der Rest eigentlich ganz einfach. Hier ein paar Beispiele, mit denen man alle gängigen Registry-Operationen abdecken kann:

Alle Registryschlüssel ausgeben, die Powershell im Namen tragen:

Get-childitem -path HKCU:,HKLM: -Include '*Powershell*' -Recurse

Der Parameter -Include legt fest, welche Elemente ausgegeben werden sollen, wobei Wildcards erlaubt sind. -Recurse weist den Get-Childitem an, auch in Unterschlüsseln zu suchen.

Den Schlüssel Software in der Variable $Software speichern:

$software = Get-Item HKCU:\Software

Alle Eigenschaften eines Schlüssels:

Get-Itemproperty -path 'HKLM:\Software\Microsoft\Windows NT\CurrentVersion'

Achten Sie darauf, dass hier das Cmdlet Get-ItemProperty verwendet wird. Man ruft Eigenschaften des Schlüssels ab, nicht eigenständige Objekte wie bei Dateien!

Das gleiche wie eben, aber über direkten Provider-Zugriff ohne Zuhilfename des Laufwerks HKLM:

Get-Itemproperty -Path 'Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion'

In diesem Beispiel wird nicht das Laufwerk angegeben, sondern der Provider direkt mit Registry:: referenziert. Achten Sie darauf, dass hier der komplette Pfadname angegeben ist (HKEY_LOCAL_MACHINE). Diese Schreibweise ist in Skripten normalerweise vorzuziehen, da eindeutig. In manchen Fällen kann Powershell sonst den Providerwechsel (z.B. vom Dateisystem in die Registry) nicht eindeutig erkennen, was zu Pfadfehlern führt.

Abrufen der Eigenschaft ProductID:

$RegKey = 'HKLM:\Software\Microsoft\Windows NT\CurrentVersion' Get-Itemproperty -Path $RegKey -Name ProductID

> ProductId : 00328-00000-00000-AA589
> PSPath :  Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion
> PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT
> PSChildName : CurrentVersion PSDrive : HKLM
> PSProvider : Microsoft.PowerShell.Core\Registry

 An der Ausgabe kann man sehen, dass Powershell nicht den Wert der Eigenschaft ProductID zurückliefert, sondern ein Objekt mit einer Reihe von Eigenschaften, die von Powershell an das Objekt "angeheftet" werden. Dass die Eigenschaften von Powershell hinzugefügt wurden, erkennt man am Prefix PS, wie PSDrive.

Die installierte Software auslesen:

$InstalledSoftware= 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*' Get-Itemproperty -Path $InstalledSoftware |
Select-Object DisplayName, Publisher

 Einen Wert überschreiben:

Set-Itemproperty -Path HKCU:\Software\Testschlüssel -Name NeuerWert -Value 100

Einen neuen Binärwert aus Hex-Zahlen erzeugen:

$Value = '68,02,00,00,21,01,00,00'.split(",") | Foreach-object {"0x"+$_}  # String wird aufgesplittet und die Einzelwerte als Hex (0x) markiert
New-ItemProperty -Path 'HKCU:\Software\IvoSoft\ClassicExplorer' -name "CSettingsDlg" -Value $Value -PropertyType BINARY

Einen neuen Wert mit einer Windows-Umgebungsvariable erzeugen. Wenn Sie den Inhalt der Umgebungsvariable (also hier den Pfad zum Windows-Ordner) in den Schlüssel schreiben wollen, müssen sie stattdessen mit $env:windir arbeiten und den Text in doppelte Anführungszeichen (einen expandable String) speichern. 

Set-Itemproperty -Path HKCU:\Software\Testschluessel –Name NeuerWert –Value '%Windir%\Notepad.exe' –Type Expandstring
# ergibt im Schlüssel %Windir%\Notepad.exe
Set-Itemproperty -Path HKCU:\Software\Testschluessel –Name NeuerWert –Value "$env:windir\Notepad.exe" –Type Expandstring
# ergibt im Schlüssel (bei mir) C:\Windows\Notepad.exe

Umbenennen eines Schlüssels

Rename-Item –Path HKCU:\Software\Testschluessel –NewName NeuerName

 Löschen eines Wertes

Remove-ItemProperty -Path HKCU:\Software\Testschluessel -Name NeuerWert

 Löschen eines Schlüssels

Remove-Item -Path HKCU:\Software\Testschluessel

 

 
Set-Itemproperty -Path HKCU:\Software\Testschluessel –Name NeuerWert –Value '%Windir%\Notepad.exe' –Type Expandstring
Set-Itemproperty -Path HKCU:\Software\Testschluessel –Name NeuerWert –Value "$env:windir\Notepad.exe" –Type Expandstring