Scripting HKCU Changes

In a corporate environment, distributing software can frequently be tricky.  One thing that can cause the most headaches is when there are registry changes that need to be made within the HKCU hive of any or even every user.  For example,  Apple designed QuickTime to allow every user to decide whether or not to enable automatic updates.  So this value is set in HKCU\Software\Apple Computer, Inc.\QuickTime\LocalUserPreferences\.  But in a controlled environment, you really don’t want the users doing their own thing.  So the package needs to be designed in such a way that edits the aforementioned registry key.

With SMS/SCCM, one could always build a script to make the change and configure the Program to run every time a user logs on.  I used to do it this way, but grew tired of constantly needing to monitor that the advertisement is successful and there are not alot of failures…so I became my own thinktank to figure out a new process.  What I realized is that I could use the existing WinXP registry tool (reg.exe) to make all the changes I need.

The process kind of looks like this: once there is no user logged into Windows, I run a script that

  1. Parses HKLM for every user profile
  2. Loads the discovered user’s registry hive
  3. Makes the HKCU change
  4. Unloads the user’s registry hive
  5. Moves onto the next profile

This even modifies the Default User’s profile so that anyone who logs onto the computer for the first time will already have this setting!  Rinse.  Repeat.  Done.

NOTE: If you’re looking for a sample script to delete a registry key or value, see https://t3chn1ck.wordpress.com/2012/11/12/vbscript-to-delete-hkcu-values-or-keys/

'==========================================================================
' Author: Nick Moseley, https://t3chn1ck.wordpress.com
' Comments: This script will parse all User profiles on the computer, load their  HKCU hive, 
'    then set the appropriate registry keys. 
' History: 
'    1.0 (04/07/2009) - Initial script 
'    1.1 (06/03/2009) - Added example for setting dword values based on MyITForum question
'    1.2 (06/05/2009) - Added additional comments to identify the section where to define the values to be set
'    1.3 (09/23/2010) - Corrected comment typos
'==========================================================================
Option Explicit
Const ForAppending = 8
Const HKLM = &H80000002
 
' ************************************************ 
' Configure the following values to define the HKCU keys to be set 
' ************************************************ 
Const sStringUserKey = "\Software\SampleKey"
Const sStringUserKeyValueName = "SampleValueName"
Const sStringUserKeyValue = "SampleValue" 
Const sDwordUserKey = "\Software\SampleKey"
Const sDwordUserKeyValueName = "SampleValueName"
Const sDwordUserKeyValue = "SampleValue"
' ************************************************
Dim oReg, oFSO, oFile, oUserSubkey, aUserProfiles, oShell
Dim sProfileLCase, sRegExe, sRegLoad, sRegUnload, sHiveName, sSubPath, sProfile, sValueName, sKeyPathUserProfiles, sValue, ReturnVal
Set oReg = GetObject("winmgmts:\\.\root\default:StdRegProv")
Set oShell = CreateObject ("WScript.Shell") 
Set oFSO = CreateObject ("Scripting.FileSystemObject")

' Begin configuration of existing user profiles
sValueName = "ProfileImagePath"
sKeyPathUserProfiles = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"
sRegExe = "C:\Windows\system32\reg.exe"
oReg.EnumKey HKLM, sKeyPathUserProfiles, aUserProfiles
For Each oUserSubkey In aUserProfiles
    sSubPath = sKeyPathUserProfiles & "\" & oUserSubkey
    oReg.GetExpandedStringValue HKLM,sSubPath,sValueName,sValue
 
    sProfile = Split(sValue, "\")
    sProfileLCase = LCase(sProfile(2))
 
    If sProfileLCase = "system32" Then
     ' Do nothing
    ElseIf sProfileLCase = "localservice" Then
     ' Do nothing
    ElseIf sProfileLCase = "networkservice" Then
     ' Do nothing
    ElseIf sProfileLCase = "serviceprofiles" Then
     ' Do nothing
    Else
     sHiveName = "TempHive_" & sProfileLCase
   
     ' Load user's profile hive into a temp location
     sRegLoad = " LOAD HKLM\" & sHiveName & " """ & sValue & "\ntuser.dat"""
     oShell.Run sRegExe & sRegLoad, 0, True
   
     ' Call subroutine to change registry key
     SetConfigUserHive (sHiveName)
   
     ' Unload user's profile hive
     sRegUnload = " UNLOAD HKLM\" & sHiveName
     oShell.Run sRegExe & sRegUnload, 0, True
    End If 
Next

' Default User Profile
sHiveName = "TempHive_DefaultUser"
sRegLoad = " LOAD HKLM\" & sHiveName & " ""C:\Documents and Settings\Default User\ntuser.dat"""
oShell.Run sRegExe & sRegLoad, 0, True
SetConfigUserHive (sHiveName)
sRegUnload = " UNLOAD HKLM\" & sHiveName
oShell.Run sRegExe & sRegUnload, 0, True
WScript.Quit ()
Sub SetConfigUserHive (sTempHive)
Dim sTempHiveStringKeyPath, sTempHiveDwordKeyPath

' Path of registry keys
sTempHiveStringKeyPath = sTempHive & sStringUserKey
sTempHiveDwordKeyPath = sTempHive & sDwordUserKey

' Create String registry key if the value doesn't already exist
If oReg.GetStringValue(HKLM, sTempHiveStringKeyPath & "\", sStringUserKeyValueName) <> 0 Then
    ReturnVal = oReg.CreateKey(HKLM, sTempHiveStringKeyPath)
End If
' Create Dword registry key if the value doesn't already exist
If oReg.GetDwordValue(HKLM, sTempHiveDwordKeyPath & "\", sDwordUserKeyValueName) <> 0 Then
    ReturnVal = oReg.CreateKey(HKLM, sTempHiveDwordKeyPath)
End If
  
' Create String value
ReturnVal = oReg.SetStringValue(HKLM, sTempHiveStringKeyPath & "\", sStringUserKeyValueName, sStringUserKeyValue)

' Create Dword value
ReturnVal = oReg.SetDwordValue(HKLM, sTempHiveDwordKeyPath & "\", sDwordUserKeyValueName, sDwordUserKeyValue)
End Sub

54 thoughts on “Scripting HKCU Changes

Add yours

  1. Hi Nick, nice script you wrote ;-)
    Will try it but can you tell me where in your script I can put my registry edits?
    Or can I first lauch a registry change and launch your script that will copy the .dat file from default user to every user?
    Thanks

  2. Thanks for the feedback. I updated the script today to include:

    1. Added dword scripting examples
    2. Script comments to help identify where to set the script values which will set the HKCU registry settings

    So to answer your spefiic question, find the section where I added additional comments and set those registry values to what you need them to be. If you don’t use the dword values, then be sure to delete or comment them out and delete or comment out the dword changes in the subroutine (at the very bottom)

  3. You can also do this by using the ActiveSetup registry key. This key resides in both the HKLM and HKCU hives. When a user logs on, it compares the keys in HKLM, to see if they exist in HKCU and are the same version number. If not, it will run any command in a StubPath key for that component. So you can put a .reg file on the workstation with the install package, and have the StubPath command import the reg file.

  4. Great to know, thanks for sharing! I may give that a try the next time I develop a package that requires registry changes. Although, IMHO there are two downsides to doing it this way
    1. Doing cleanup if the entries become obsolete
    2. Making other “complex” registry changes. For example, I one had to distribute a change where I needed to only change a single position within a DWORD array but leave all other values unchanged.

    Then again, maybe there is still a method which could be used to do what you have suggested, but instead of importing a regkey, that it would run a script or command or something. Still, I’m not sure I would want to do a search-in-destroy cleanup. :-(

  5. If you’re using MSI packages to deploy your software there’s a more elegant way to accomplish HKCU changes.

    Put all HKCU keys into an own Feature and repair the feature on logon:
    msiexec.exe /fu {productcode} INSTALL=YourFeatureHoldingHKCU /qb-

    This method has its downsides too – for example, you would want to check if the feature has already been installed before triggering a repair and delaying the login for the user further.

    It works quite well for us.

  6. Hello Mate,
    I need to sort out the following reg key:
    [HKEY_CURRENT_USER\Software\JavaSoft\Java Update\Policy]
    “EnableAutoUpdateCheck”=hex:01,00,00,00,d0,8c,9d,df,01,15,d1,11,8c,7a,00,c0,4f,\
    c2,97,eb,01,00,00,00,91,55,d9,ac,96,77,9c,4d,ba,97,d0,bf,70,5a,0c,e3,00,00,\
    00,00,1c,00,00,00,50,00,61,00,73,00,73,00,77,00,6f,00,72,00,64,00,20,00,44,\
    00,61,00,74,00,61,00,00,00,03,66,00,00,a8,00,00,00,10,00,00,00,a8,22,a5,70,\
    2a,61,66,09,bb,c8,48,df,ca,bc,a2,6e,00,00,00,00,04,80,00,00,a0,00,00,00,10,\
    00,00,00,dd,aa,b2,d1,70,84,f7,db,f8,db,42,30,67,f9,97,36,08,00,00,00,9d,0f,\
    c0,a5,fb,8b,fc,1d,14,00,00,00,0a,8d,1c,43,bd,74,cc,61,04,0c,21,29,dc,10,fe,\
    cd,66,8a,ba,e1

    This willdisable the auto update on java, but because the key is tailored for each user, i cannot roll it out,, any help please.

    sanj.

    1. Hi Nick,
      I have tried this, but on the later version of Java, Setting this key to 0, does not however take away the Tick
      in the check for Auto Updates tab in the java consle. Im running Java 6.13.
      Now even though it is set in the registry not to update, but the check box still being ticked is abit risky for me to roll
      out java nationwide. Alot of the users wont be affected because they do not have admin rights. but nearly half our users are local
      administrators on their machines, which will cause issues, because we are running a Warehouse management system that
      requires a set version of Java.

      1. I did a little digging and there is a potential bug in the UI for the Java console for the Auto Update. Regardless, it seems that majority of the updates can be controlled through the following HKLM registry key…which means you won’t need to use this HKCU script.

        HKLM\SOFTWARE\JavaSoft\Java Update\Policy

      2. Thanks For your Help Nick,
        I will set all the relevant Java update switches to 0 in the registry before rolling this out to the company. Hopefully it is a bug and the Java does not update, a risk i suppose.

        Cheers mate.

  7. There is a typo: line 25 should be commented out but isn’t
    Commented sections for the subroutine are backwards (e.g., Dword should be String and vice versa)

    I corrected the above typos and then removed all the instances for Dword values since I didn’t need them but am still having issues getting this to work.

    Any suggestions?

    1. Oops; case of the good ‘ol failed copy-and-paste! Thanks Ryan for letting me know of the script errors, I do appreciate it.

      When you say it is failing, is there a vbscript code error or does it not produce the expected results?

  8. No worries–glad I can help out.

    Sorry I wasn’t more descriptive. I do not get any vbscript error codes. I can run through the script however it doesn’t provide the desired results.

    I am trying to enter in a string value so I removed the dword entries (lines 21,22,23,94,95,96,102 using v1.3). I then substituted my string values on lines 18,19,20, making sure to keep the example syntax in place (quotes and slashes).

    After running the script I check the registry under the current user key (HKCU\Software\…) but it has not been updated with the value I’m using.

    Is there something else I’m missing or another way to check/troubleshoot the script?

    Thanks so much for your help and time putting this together.

  9. OK I think I answered my own questions. I was trying to run the script logged on as the local administrator and it wasn’t working (obviously because it couldn’t load the user hive while signed in duh). I did confirm it worked for the Default User profile and other local user profiles.

    Is there a way to include in this script (or another) to import the registry settings to the currently logged on user? Even better yet, import the registry settings for all users (including a logged on user) using admin rights?

    Thanks!

    1. Glad you tracked down the troubles and thanks for sharing the cause. It could certainly be possible to enhance the script to check if there is currently a logged in user (that is executing the script) to make the change(s). However, this script is primarily intended to run using a tool such as SCCM and run with admin rights while no users are logged into Windows, so that all user profiles are updated. Do you have SCCM or something like it?

  10. Yes we are using SMS 2003 and I am planning on using this script with some of the packages I’ve setup that require modifications to the HKCU keys.

    I was hoping to reduce the overall time it would take to make these changes. Obviously if we set the advertisement to only run while no users are logged into Windows it could take days if not weeks to push out (as most of our users stay logged in for long periods of time).

    1. Yeah that can certainly hold up one’s processes! Unfortunately to update a current logged in user’s registry, the Program needs to run as them (not as admin) and if they are not local admins themselves then all other users won’t be updated. Using chained Programs, I typically install the application, force a restart of the computer, and then run the script.

  11. Hi Nicolas, I’m fairly new to scripting and just wondered if I wanted to configure more than one HKCU key where should I specify this in the script?
    Am I right in thinking the below code is specifying one key only?
    Const sStringUserKey = “\Software\SampleKey”
    Const sStringUserKeyValueName = “SampleValueName”
    Const sStringUserKeyValue = “SampleValue”

    1. Kelly, thank you for the comment. You are correct, the code only contains one example. To do multiple changes, simply duplicate the entries that you need within the script.

      1. So if I had two HKCU keys to edit I should add three lines below “Const sStringUserKeyValue = “SampleValue” (line 21) eg. :
        Const sStringUserKey2 = “\Software\SampleKey”
        Const sStringUserKeyValueName2 = “SampleValueName”
        Const sStringUserKeyValue2 = “SampleValue”
        I’m not sure how to change/add this in rest of the code. I told you I was a newbie!! Sorry if I sound stupid!

      2. Unfortunately, just changing the value to have the number 2 at the end of it will not suffice. For every line of code that you find which has the sample code, you’ll need to duplicate the line and change the value’s name to then have a 2 on it.

  12. I am a newbie so please bare with me on this. I’d like to write HKCU registry to all user as follow:
    [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer]
    “NoClose”=dword:00000001

    On your script:
    Const sStringUserKey = “\Software\SampleKey” – This I know it would be “Software\Microsoft\Windows\CurrentVersion\Policies\Explorer”

    Const sStringUserKeyValueName = “SampleValueName” – Should I put it as “NoClose”

    Const sStringUserKeyValue = “SampleValue” – What do I put here?
    Const sDwordUserKey = “\Software\SampleKey” -What do I put here?
    Const sDwordUserKeyValueName = “SampleValueName” -Should I use “00000001” ?
    Const sDwordUserKeyValue = “SampleValue” -What should I put it here?

    1. Using your example, these are the only values you will use. The others you’ll need to delete or comment out with a single quote.

      sDwordUserKey = “\Software\Microsoft\Windows\CurrentVersion\PolicsDwordUserKeyValuies\Explorer”
      sDwordUserKeyValueName = “NoClose”
      sDwordUserKeyValue = “1”

      1. Unfortunately, after input those value and run the script as recommended, it gave the error: Variable is under undefined: ‘sStringUserKey’

        Could you shed me a light on what was wrong?

      2. Please ignore the previous reply. I’ve edited and delte those unrelated sStringUserKey and the script does run. However, the script does not write the setting for HKCU. What did I do wrong?

      3. Thank you very much for your patient and assistance. I am truly appreciate you help. I’ve actually used SSCM to run reg add to add that registry key to HKCU first, then run your script and it does replicate for all users even new users log in to the PC.

  13. Nicoloas,
    I’m a IT administrator for a Christian school trying to script a change in the HCKU hive for their computer lab. We use Faronics Deepfreeze in the lab, so the students profiles are generated each time they log into a machine, and the profiles are wiped out on reboot. (Windows 7 Professional). For a program called E-sword that they use to look up Bible verses, the program looks for its default user files in the wrong place and displays errors on startup. So I changed the default paths in the registry to a place where all students would have rights. I’ve created the reg file that has these lines:

    Windows Registry Editor Version 5.00

    [HKEY_CURRENT_USER\Software\VB and VBA Program Settings\e-Sword\Editor]
    “Journal Notes”=”C:\\Users\\Public\\Documents\\E-sword Default Settings\\journal.jnlx”
    “Study Notes”=”C:\\Users\\Public\\Documents\\E-sword Default Settings\\study.notx”
    “Topic Notes”=”C:\\Users\\Public\\Documents\\E-sword Default Settings\\topic.topx”

    [HKEY_CURRENT_USER\Software\VB and VBA Program Settings\e-Sword\Settings]
    “Markup File”=”C:\\Users\\Public\\Documents\\E-sword Default Settings\\markup.ovlx”
    “VerseList File”=”C:\\Users\\Public\\Documents\\E-sword Default Settings\\Bookmarks.lstx”

    Im not sure why running this reg file at boot would require admin rights, even if run /s. But it does. Of course, if you run it as admin with my admin credentials, even if they’re logged in, it only makes the change in my HKCU hive.

    I just need these HKCU settings pushed to each student that logs in (as their new profile is generated from the default user’s).

    I tried your script, and changed the values as seen below (but I probably didn’t do this right)

    ‘ ************************************************
    ‘ Configure the following values to define the HKCU keys to be set
    ‘ ************************************************
    Const sDwordUserKey = “Software\VB and VBA Program Settings\e-Sword\Editor”
    Const sDwordUserKeyValueName = “Journal Notes”
    Const sDwordUserKeyValue = “C:\\Users\\Public\\Documents\\E-sword Default Settings\\journal.jnlx”
    Const sDwordUserKey = “Software\VB and VBA Program Settings\e-Sword\Editor”
    Const sDwordUserKeyValueName = “Study Notes”
    Const sDwordUserKeyValue = “C:\\Users\\Public\\Documents\\E-sword Default Settings\\study.notx”
    Const sDwordUserKey = “Software\VB and VBA Program Settings\e-Sword\Editor”
    Const sDwordUserKeyValueName = “Topic Notes”
    Const sDwordUserKeyValue = “C:\\Users\\Public\\Documents\\E-sword Default Settings\\topic.topx”
    Const sDwordUserKey = “Software\VB and VBA Program Settings\e-Sword\Settings”
    Const sDwordUserKeyValueName = “Markup File”
    Const sDwordUserKeyValue = “C:\\Users\\Public\\Documents\\E-sword Default Settings\\markup.ovlx”
    Const sDwordUserKey = “Software\VB and VBA Program Settings\e-Sword\Settings”
    Const sDwordUserKeyValueName = “VerseList File”
    Const sDwordUserKeyValue = “C:\\Users\\Public\\Documents\\E-sword Default Settings\\Bookmarks.lstx”
    ‘ ************************************************

    What do you recommend? I’m working on it this morning, so I’m not sure when you’ll get this…

  14. Hello!

    Please forgive my lack of knowledge on this subject….

    I came across your script while trying to find a way to populate a registry key/value to HKCU for a specific piece of software for Win XP/7 devices.

    Will your script work on Win 7? It appears as it is geared towards XP.

    Thank you.
    LK

    1. The registry hasn’t changed between Windows XP and Windows 7. The only difference you may encounter is going from 32-bit to 64-bit software. So long as you plug in the registry key’s exact location, it will be fine.

      1. Thanks for the reply.

        It appears when running the script on XP (x86) it runs without error, but the keys are not created. Is there anything I can add to the script to pause it or generate output if it was successful or not?

        Thanks.

      2. Hey Leon, it’s likely not working because there is an error in the script. I’ll drop you an email offline to get a copy of your script and I’ll see if I can isolate the script error. As for the logging, I’ve typically added logging, but double checked this script and didn’t. So I’ll have to revision that some time, thanks for the feedback on that :-)

  15. I am having the same problem. It appears when running the script on XP (x86) it runs without error, but the keys are not created. Do you mind looking at mine?

  16. Hi Leon. I came upon your site to perform something very similar. In my case I am trying to disable automatic updates for AMD Catalyst drivers. The key is located here:

    HKEY_CURRENT_USER\Software\ATI\ACE\Settings\Graphics\UpdateNotification

    Basically all I need to do is modify the string titled AutomaticUpdate in the key to be False.

    I have edited your your VB script, removing the sStringUserKey, sStringUserKeyValueName, & sStringUserKeyValue and updated the rest to be the following:

    Const sDwordUserKey = “\Software\ATI\ACE\Settings\Graphics\UpdateNotification”
    Const sDwordUserKeyValueName = “AutomaticUpdate”
    Const sDwordUserKeyValue = “False”

    For some reason, running the VB script gives me an error:

    Line: 68
    Char: 1
    Error: Type Mismatch
    Code: 8041005
    Source: SWbemObjectEx

    Any idea as to what I could be doing wrong? This would be for Windows 7 32bit

    Thanks

  17. Is there a a way to change this to delete a registry key path on all users profiles?
    like i want to delete \Software\Avaya\CMS
    thanks

    1. Certainly! The command that’s being run in the script just uses Windows’ reg.exe utility for doing the changes. The command to use instead is reg.exe DELETE. For more info on how to use the command, you can just reg.exe DELETE /?

      1. so im kinda new to scripting. what would i need to change exactly. i would need to change the reg.exe to “reg.exe delete” and then change the oReg.CreateKey to oreg.deletekey and comment out the “ReturnVal = oReg.SetStringValue….” ?

      2. or would i need something like this:

        oReg.EnumKey HKLM, sTempHiveStringKeyPath, arrSubKeys
        For Each subkey in arrSubKeys
        WshShell.RegDelete “HKLM\” & sTempHiveStringKeyPath & subKey & “\”
        Next

  18. trying to either remove

    Const sStringUserKey = “\SOFTWARE\Apple Computer, Inc.\QuickTime\LocalUserPreferences”
    Const sStringUserKeyValueName = “FolderPath”

    or at least change it to this

    Const sStringUserKeyValue = “c:\”

    on all users profiles

    I cannot get the script to do either do you think you can help?

      1. I figured out that my boss did not cut and paste the entire script Once I figured that out it worked perfectly to either add or delete

        Sent from my iPhone

  19. Hi Nick. I am trying to monitor registry change in HKCU. The key is located here:

    HKEY_CURRENT_USER\Software\AppDataLow\Software\JavaSoft\DeploymentProperties\ deployment.expiration.check.enabled

    Basically all I need to do is modify the string titled deployment.expiration.check.enabled in the key to be False.

    I have edited your your VB script, removing the sStringUserKey, sStringUserKeyValueName, & sStringUserKeyValue and updated the rest to be the following:

    Const sDwordUserKey = “Software\AppDataLow\Software\JavaSoft\DeploymentProperties”
    Const sDwordUserKeyValueName = “deployment.expiration.check.enabled”
    Const sDwordUserKeyValue = “False”

    For some reason, running the VB script gives me an error:

    Line: 95
    Char: 1
    Error: Type Mismatch
    Code: 80041005
    Source: SWbemObjectEx

    Any idea as to what I could be doing wrong?

    Thanks

      1. I see, thanks a lot. But after change to ‘0’, hmmm, something goes wrong, there is nothing happen when I execute the script.

Leave a comment

Blog at WordPress.com.

Up ↑