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.

'==========================================================================
' Author: Nick Moseley, http://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

 

  1. #1 by dKarl on June 5, 2009 - 3:51 am

    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. #2 by Nicolas Moseley on June 5, 2009 - 5:23 am

    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. #3 by Jerry on July 9, 2009 - 7:30 pm

    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. #4 by Nicolas Moseley on July 10, 2009 - 5:26 am

    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. #5 by Christoph Voigt on July 13, 2009 - 12:57 am

    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. #6 by sanj on July 29, 2009 - 7:30 am

    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.

  7. #7 by Nicolas Moseley on August 3, 2009 - 3:32 pm

    Hi Sanj, if you need to disable auto update for Sun Java, you may want to try using the install switch JAVAUPDATE=0 instead…much easier!

    • #8 by sanj on August 4, 2009 - 12:49 am

      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.

      • #9 by Nicolas Moseley on August 6, 2009 - 3:20 pm

        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

      • #10 by sanj on August 10, 2009 - 1:18 am

        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.

  8. #11 by Ryan on September 23, 2010 - 3:23 pm

    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?

    • #12 by Nicolas Moseley on September 23, 2010 - 3:40 pm

      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?

  9. #13 by Ryan on September 24, 2010 - 7:48 am

    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.

  10. #14 by Ryan on September 24, 2010 - 10:49 am

    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!

    • #15 by Nicolas Moseley on September 24, 2010 - 11:41 am

      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?

  11. #16 by Ryan on September 24, 2010 - 1:05 pm

    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).

    • #17 by Nicolas Moseley on September 24, 2010 - 1:13 pm

      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.

  12. #18 by Kelly on June 21, 2011 - 9:52 am

    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”

    • #19 by Nicolas Moseley on June 21, 2011 - 9:54 am

      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.

      • #20 by Kelly on June 21, 2011 - 10:00 am

        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!

      • #21 by Nicolas Moseley on June 21, 2011 - 11:17 am

        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.

  13. #22 by Hoang on February 6, 2012 - 5:17 pm

    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?

    • #23 by Nicolas Moseley on February 6, 2012 - 7:00 pm

      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″

      • #24 by Hoang on February 7, 2012 - 7:36 am

        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?

      • #25 by Hoang on February 7, 2012 - 8:33 am

        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?

      • #26 by Nicolas Moseley on February 7, 2012 - 7:48 pm

        Just a hunch, but if you’re using Windows 7 with UAC enabled, you probably have to execute the script from an elevated command prompt…

      • #27 by Hoang on February 10, 2012 - 8:24 am

        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.

      • #28 by Nicolas Moseley on February 10, 2012 - 8:25 am

        Right on. I’m glad it’s working!

  14. #29 by Michael Lining - please call me at 630-779-6566 on March 10, 2012 - 8:00 am

    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…

  15. #30 by Michae Lining on March 10, 2012 - 8:16 am

    Disregard previous long post. I figured it out. Thanks anyway!

    • #31 by Nicolas Moseley on March 10, 2012 - 12:38 pm

      Cool :-) What was your solution, if you don’t mind sharing if others should experience the same troubles?

  1. WinXP Configurations « t3chn1ck

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 39 other followers