Weekend Scripter: Use PowerShell to Easily Modify Registry Property Values

Summary: Microsoft Scripting Guy, Ed Wilson, shows to use the PowerShell registry provider to easily modify registry property values.

Microsoft Scripting Guy, Ed Wilson, is here. It is finally the weekend. It seems like it has been a rather long week. Of course, each week is only 168 hours long, but this one has seemed long. It is due in part to the travel for recent conferences, various meetings, and an unexpected dinner with Windows PowerShell tweeps. It has been raining quite a bit this week, and the air outside has a fresh spring rain smell to it. I am sitting on the lanai sipping a cup of Irish Breakfast tea and munching on a blueberry scone that the Scripting Wife made last night. I have set aside most of today to work on my Windows PowerShell 3.0 Step-by-Step book that will be published this summer with Microsoft Press. (Cool! I just noticed that you can preorder it on Amazon.)

Note   This is the sixth blog in a series of Hey, Scripting Guy! Blogs that discuss using the Registry provider. The first blog, Using the Registry Provider to Simply Registry Access posted on Monday. Tuesday I discussed using the *restore* cmdlets to perform a system state backup of a computer prior to manipulating the registry. On Wednesday I talked about creating new registry keys and assigning default values. In the fourth blog, I talked about creating new registry keys on remote computer systems. I also discussed creating registry property values. In the fifth blog, I created a function and a script that enumerate all the registry properties and their associated values. The function and script return a custom object that permits further work with the output by using standard Windows PowerShell functionality. For additional information about working with the registry via Windows PowerShell, see this collection of blogs.

Modifying the value of a registry property value

To modify the value of a registry property value requires using the Set-PropertyItem cmdlet.

Only the steps…

Modifying the value of a registry property value:

  1. Use the Push-Location cmdlet to save the current working location.
  2. Use the Set-Location cmdlet to change to the appropriate registry drive.
  3. Use the Set-ItemProperty cmdlet to assign a new value to the registry property.
  4. Use the Pop-Location cmdlet to return to the original working location.

In the image that follows, a registry key named hsg exists in the HKCU:\Software hive. The registry key has a property named NewProperty.

Image of Registry Editor

When you know that a registry property value exists, the solution is really simple. You use the Set-ItemProperty cmdlet and assign a new value. The code that follows saves the current working location, changes the new working location to the hsg registry key, uses the Set-ItemProperty cmdlet to assign new values, and then uses the Pop-Location cmdlet to return to the original working location.

The code that follows relies on positional parameters for the Set-ItemProperty cmdlet. The first parameter is Path. Because the Set-Location cmdlet sets the working location to the hsg registry key, a period identifies the path as the current directory. The second parameter is the Name of the registry property to change. In this example, it is NewProperty. The last parameter is Value, and that defines the value to assign to the registry property. In this example, it is mynewvalue. Thus, the command with complete parameter names would be:

Set-ItemProperty -Path . -Name newproperty -Value mynewvalue. The quotation marks in the code that follows are not required, but they do not harm anything either.

Here is the code:

PS C:\> Push-Location

PS C:\> Set-Location HKCU:\Software\hsg

PS HKCU:\Software\hsg> Set-ItemProperty . newproperty “mynewvalue”

PS HKCU:\Software\hsg> Pop-Location

PS C:\>

Of course, all the pushing and popping and setting of locations are not really required. It is entirely possible to change the registry property value from any location within the Windows PowerShell provider subsystem.

Only the step…

The short way to change a registry property value:

  1. Use the Set-ItemProperty cmdlet to assign a new value. Ensure that you specify the complete path to the registry key.

Here is an example of using the Set-ItemProperty cmdlet to change a registry property value without first navigating to the registry drive.

PS C:\> Set-ItemProperty -Path HKCU:\Software\hsg -Name newproperty -Value anewvalue

Dealing with a missing registry property value

If you need to set a registry property value, you can set the value of that property easily by using the Set-ItemProperty cmdlet. But what if the registry property does not exist? How do you set the property value then? You can still use the Set-ItemProperty cmdlet to set a registry property value, even if the registry property does not exist.

Set-ItemProperty -Path HKCU:\Software\hsg -Name missingproperty -Value avalue

To determine if a registry key exists is easy: Use the Test-Path cmdlet. It returns True if the key exists and False if it does not exist. This technique is shown here.

PS C:\> Test-Path HKCU:\Software\hsg


PS C:\> Test-Path HKCU:\Software\hsg\newproperty


But unfortunately, this technique does not work for a registry key property. It always returns False—even if the registry property exists. This is shown here.

PS C:\> Test-Path HKCU:\Software\hsg\newproperty


PS C:\> Test-Path HKCU:\Software\hsg\bogus


Therefore, if you do not want to overwrite a registry key property if it already exists, you need a way to determine if the registry key property exists—and using the Test-Path cmdlet does not work.

One of the cool things about writing the Hey, Scripting Guy! Blog is the interaction with the readers. One such reader, Richard, mentioned the problem of using Test-Path to determine if a registry property exists prior to calling the Set-ItemProperty. This is the technique he suggested, and it works great.

Only the steps…

Testing for a registry key property prior to writing a new value:

  1. Use the if statement and the Get-ItemProperty cmdlet to retrieve the value of the registry key property. Specify erroraction (ea is an alias) of SilentlyContinue (0 is the enumeration value).
  2. In the script block for the if statement, display a message that the registry property exists, or simply exit.
  3. In the else statement, call the Set-ItemProperty to create and to set the value of the registry key property.

This technique is shown here.

if((Get-ItemProperty HKCU:\Software\hsg -Name bogus -ea 0).bogus) {‘Propertyalready exists’}

ELSE { Set-ItemProperty -Path HKCU:\Software\hsg -Name bogus -Value’initial value’}

The use of this technique appears in the image that follows. The first time, the bogus registry key property value does not exist and it is created. The second time, the registry key property already exists and a message to that effect appears.

Image of command output

Well, this concludes Registry Week. Tomorrow, I answer a question about how to continue with the spirit of the Scripting Games.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy 

Comments (9)

  1. Anonymous says:

    Hi Ed, can you count on accesses to the Registry provider being thread-safe when accessed from different PS processes?

  2. Anonymous says:

    Cool post. I hope to get it working once I get over this last hurdle:

    So I used PowerShell to modify the registry entry that controls whether icons on the taskbar are combined or not. It did change the value, but it didn’t change the behavior in Windows. Any suggestions on how I can say "Apply" when I have made a change? Do I
    need to "save" the change made in my PS session?

  3. mredwilson says:

    @Matt P I am glad you found the article helpful. Thanks for sharing.

    @AussieDog Of that, I am not certain.

  4. Informative as always, thanks!

  5. jrv says:

    @AussieDog – what do you mean by treadsafe in this context?  A key has a value.  Multiple prpocesses can cahneg it.  There is not realy any locking or serialization and PowerShell has only one thread.  How can it interfere with itself?

    Start here by reviewing a discusson of what thread safe indicates: http://www.designedsystemsonline.com/…/Demo-Treeview.ps1.txt

    The registry calls assure safety for a multiprogrammig environment but it is on a first-come-first-serve basis.  There is no locking or exclusion.  In a multithreaded program you could privide a sync mechanism to prevent different threads from accessing the same value in an uncontrolled way although this would only be required if you were to be incrementing a value.  Pure replacement does not require this.

  6. Paul Jorgensen says:

    another helpful link on this topic relating to Multistring Registry entries

    Powershell:Append a new value to existing Multistring Registry item


  7. Matt P says:

    Thanks. I have been trying to resolve this issue for a couple days. I developed some unreliable functions. I definitely prefer this simple solution.

  8. jqngrc says:

    Registry Editor (regedit.exe) is well suited for simple tasks that involves few keys/values, on both local and remote computers. PowerShell shoud be more errr… powerful.

  9. factgasm says:

    The ".bogus" in the line:

    if((Get-ItemProperty HKCU:Softwarehsg -Name bogus -ea 0).bogus) {‘Propertyalready exists’}

    itself appears to be bogus.

Skip to main content