Monday, August 12, 2013

Using Active Setup to Update Anything in HKEY_CURRENT_USER

Following my last post, I had next to make sure that every user's entry in the registry was updated, and that change had to be scripted. This turned out to be a non-trivial task and took some research. First of all, the entry is located in HKEY_CURRENT_USER registy hive. Therefore, being logged in as Admin I cannot directly set an entry for Bob because Bob is not the current user at the moment. Then what can I do? The HKEY_CURRENT_USER is a kind of shortcut to HKEY_USERS. Under HKEY_USERS I can see the following structure

HKEY_USERS\.DEFAULT
HKEY_USERS\S-1-5-18
HKEY_USERS\S-1-5-19
HKEY_USERS\S-1-5-20
HKEY_USERS\S-1-5-21-0123456789-012345678-0123456789-1004
HKEY_USERS\S-1-5-21-0123456789-012345678-0123456789-1004_Classes

The first 4 entries correspond to built-in system accounts, and the rest are real user accounts on a PC. So, one way to make the change I need is to loop through all users and make the changes as requested. Someone even wrote a VB script which does exactly that. My case is a bit different, though. I only have a small handful of users, but the change I'm making in the registry key depends on the user. So, maybe I can map a username to the registry key.

If I run the following from the command line wmic useraccount get name,sid, I will see a table similar to the following

Name            SID
Administrator   S-1-5-21-1180699209-877415012-3182924384-500
Guest           S-1-5-21-1180699209-877415012-3182924384-501
Tim             S-1-5-21-1180699209-877415012-3182924384-1004

Great. Now I can script my change and run it. However - it does not work. It appears that user hives are usually only loaded for currently logged in users. That complicates things.

Fortunately, I came across the alternative solution - use Active Setup. It's original use is, likely, to check if a specific version of the software is installed to help installers to install, uninstall and repair software. It can, however, be used to write pretty much anything in the HKCU of the user who logs on. Here's how it works:

When the user logs on, the following registry key is checked: HKCU\Software\Microsoft\Active Setup\Installed Components\

If the HKCU key is not found in the registry then the contents of the string value StubPath is executed. This is essentially all that's important, so here is my example.

reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Active Setup\Installed Components\MountDrive" /v "Version" /d "1" /t REG_SZ /f

reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Active Setup\Installed Components\MountDrive" /v "StubPath" /d "reg add HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run /v "MountDrive" /d "C:\map.cmd" /t REG_SZ /f" /f

Or, translating the reg add commands into PowerShell script

$mapcmd = "C:\map.cmd"
$regKey = "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\MountDrive"
New-Item -path $regKey | Out-Null
$regKey = "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\MountDrive"
$regName = "Version"
$value = "1"
New-ItemProperty -path $regKey -name $regName -value $value | Out-Null
$regName = "StubPath"
$value ="reg add HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run /v MountDrive /d $mapcmd /f"
New-ItemProperty -path $regKey -name $regName -value $value | Out-Null

Here's what happens when the user logs on:

  • HKCU\Software\Microsoft\Active Setup\Installed Components\MountDrive is checked. There is nothing there.
  • string value in StubPath is executed. The value is "reg add" command and it creates a MountDrive string under Run key, with a value "C:\map.cmd". Therefore, this cmd script will run on user logon.
  • Also, a Version entry is created in HKCU\Software\Microsoft\Active Setup\Installed Components\MountDrive with a value of 1.
  • Next time the user logs on, step 1 find the Version entry, thefore no actions will be performed.

Seems a little complicated, but after running once and observing the changes as they are made in the registry, it becomes clear.

References:

Update a registry key for ALL users on a system
HKEY_USERS
Security Identifier
How To Find a User's Security Identifier (SID) in Windows
Adding Registry Settings
by . Also posted on my website

No comments: