By the end of this article, you’ll be comfortable looking up Registry values, making changes, and adding and deleting values—all from the comfort of the PowerShell console.
Latest posts by Timothy Warner (see all)

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

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

Name                                    Root
----                                    ----
HKCU                                    HKEY_CURRENT_USER
HKLM                                    HKEY_LOCAL_MACHINE

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
PS HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run>

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

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:

Get-Item .

    Hive: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion

Name                           Property
----                           --------
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:

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

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.

  1. Avatar
    Brian Grigory 8 years ago

    Best explanation out there!

  2. Avatar
    cellurl 6 years ago

    in regedit I do control-F.

    All those I want deleted.

    Any suggestions?

    Thanks for posting!


  3. Avatar
    Lawrence Knowlton 6 years ago

    I was unable to get this to work, though I had high hopes.  The script runs without error, but no changes appear to have occurred in the registry.  Any ideas?

    • Avatar
      MarthonGT 6 years ago

      You will need elevated rights in order to make changes in the registry. Start Powershell as an admin

  4. Avatar
    Mike M 6 years ago

    Thanks for the post – very informative.

    Is there any way within PowerShell to cause the registry to flush to disk?  I found reference to the registry function RegFlushKey but it didn’t look like that was part of the power shell registry provider

  5. Avatar
    Alex Paper (Rank 2) 5 years ago

    Thanks, very useful, exactly what I was looking for!

  6. Avatar
    John 5 years ago

    How in the world do you add a command to check if new values appear in the registry during same execution of current PowerShell script run? I’m checking to see when a new Key value gets created, then it does another task, currently it doesn’t find the new values unless I stop the script and retry, which isn’t want we want done. I’m having troubles finding related articles on this…

    • Avatar

      Hi John,
      My guess is that you are using a variable to check in a if loop statement if the value is Key-Value is true or not. In short maybe is better to outline the difference of assigning by  value or by reference. Let me explain with a easier example with an interactive powershell session:

      PS:>$date = Get-Date
      If you print it $date now you’ll have the exact time right? Sort of…

      Wednesday, 12 September 2018 5:13:00 PM

      If you print it after 10 minutes? 1 h? 1 year? Same result
      Wednesday, 12 September 2018 5:13:00 PM

      This $date is assigned once and never refreshed. So in your case it looks like you’re not refreshing the variable that you’re checking. An examples of it is that if I run these sequence I get the expected result all the time.

      1. Get-ItemProperty -Path “HKCU:\Control Panel\Desktop” -Name MenuShowDelay
      2. Set-ItemProperty -Path ‘HKCU:\Control Panel\Desktop’ -Name MenuShowDelay -Value 50
      3. Get-ItemProperty -Path “HKCU:\Control Panel\Desktop” -Name MenuShowDelay

      Have the expected result.
      Instead if on step 1 you store the result on a Variable and on step 3 you wan to print the value the result will not have the value updated. Does this make sense? Is it your case?

      I hope it helps.

  7. Avatar
    Akshatha 4 years ago

    how to automate the process? Like reading the key value from the file(maybe 50 key values), check if the registry key exists, if exists then modify with the new value from the file and if not exists then add the new key value pair

Leave a reply

Your email address will not be published. Required fields are marked *


© 4sysops 2006 - 2023


Please ask IT administration questions in the forums. Any other messages are welcome.


Log in with your credentials


Forgot your details?

Create Account