As Windows system administrators, we come to know the Windows Registry quite intimately. If you’re like me, pressing the Windows key+R, typing regedit, and pressing ENTER is a second-nature way to open the good ol’ Registry Editor. The good news is that Windows PowerShell has had a built-in Registry provider since day one. The bad news is that accessing Registry data programmatically with PowerShell isn’t particularly intuitive.
The Windows Registry Editor
Viewing Registry key data ^
As I said, Windows PowerShell exposes the two main Registry subtrees (HKEY_CURRENT_USER and HKEY_LOCAL_MACHINE) via the built-in provider.
PS C:\> Get-PSDrive -PSProvider Registry | Select-Object -Property Name, Root
Let’s say we want to view the contents of the Run key on our Windows 8.1 system. Of course, we’re already comfortable checking that path to find troublesome and/or unwanted autostart programs, right?
First, we’ll shift our provider from the default file system to the Registry, navigating to the proper path like this:
Set-Location -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
Things get weird when we try to get a “directory” listing on the Run key, though:
PS HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run> Get-ChildItem
Strange, especially when we consider that I do, in fact, have an entry in that key. For example:
Verifying that we do indeed have data in our Run Registry key
Those of you who have prior experience with PowerShell data providers may be familiar with Get-Item to retrieve object-level data. As far as the Registry provider is concerned, Registry keys are items, and the values are item properties. Try this:
Run VMware User Process : "C:\Program
Files\VMware\VMware Tools\vmtoolsd.exe" -n
The dot (.) is important because Get-Item uses –Path as a first-position required parameter, and the dot historically represents the current working directory in the Cmd.exe, PowerShell, and Bash shells.
To drill into the Run key’s values, we need Get-ItemProperty:
VMware User Process : "C:\Program Files\VMware\VMware Tools\vmtoolsd.exe" -nvmusr
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion
PSChildName : Run
PSDrive : HKLM
PSProvider : Microsoft.PowerShell.Core\Registry
By creating a variable that stores a Registry key, we can easily use “dot notation” to access all the values. Check this out:
$desktop = Get-ItemProperty –Path "HKCU:\Control Panel\Desktop"
Now use tab completion with $desktop; you can quickly read any value you need. For example:
Modifying a Registry value ^
Before Windows 8 came on the scene, I habitually adjusted the MenuShowDelay value in HKCU\Control Panel\Desktop so the Start menu opened faster. I’m sure we can tweak this value again in Windows 10, but I’ll use this as an example now to teach you how to modify Registry values by using Windows PowerShell.
Let’s say we want to change the MenuShowDelay value from its current value to 50. First, we verify its current value, like this:
Get-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name MenuShowDelay
MenuShowDelay : 400
Programmers always talk about getting and setting values in their code. We’ve just done the “get;” now, let’s use Set-ItemProperty to perform the set operation:
Set-ItemProperty -Path 'HKCU:\Control Panel\Desktop' -Name MenuShowDelay -Value 50
Get-ItemProperty -Path 'HKCU:\Control Panel\Desktop' -Name MenuShowDelay
MenuShowDelay : 50
Adding and removing Registry keys and values ^
Now I want to teach you how to add new data to the Registry programmatically with PowerShell. In this example, we’ll create a new key called MyKey and a new DWORD value named MyValue. HKCU\Control Panel\Desktop is a fairly innocuous path, so let’s store that in a variable to get started:
$path = "HKCU:\Control Panel\Desktop"
Now, we’ll create the new key by invoking New-Item:
New-Item –Path $path –Name MyKey
Next, it’s time to create the MyValue value:
New-ItemProperty -Path $path\MyKey -Name "MyValue" -Value 0 -PropertyType "DWORD"
Our new Registry data
We’ll finish up by removing our new key and value. To do that, we’ll call Remove-ItemProperty into action:
Remove-ItemProperty –Path $path\MyKey –Name "MyValue"
Finally, we’ll delete the MyKey Registry key by using Remove-Item:
Remove-Item –Path $path\MyKey -Recurse
In the previous example, the –Recurse parameter deletes any subkeys that may exist beneath the target key.
That’s all there is to it (at least to start with). I hope you found this article informative.