I'm trying to modify registry entries within HKCU at logoff. The corresponding script works okay when invoked manually. I was afraid there might be issues with a loopback policy kicking in, but according to rsop.msc this is not the case, i.e. the script should be executed. However, the desired effect in the registry is not there upon next login.
Is there a general problem simply because the script runs "too late"? If so what can be done? What else could this be?
EDIT:
I should have specified what my logoff.vbs
script looks like (minimalized):
const HKCU = &H80000001
Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
' ...
oReg.SetStringValue HKCU,"SOFTWARE\Foo","Bar", "Baz"
I use Logoff Scripts fairly frequently. The user's registry is still loaded when the script runs and modifications can be made to their registry. Logoff scripts run synchronously, by design. I have logoff scripts that read from the user's registry but I've never had occasion to write. Even so, I expect it would work fine.
I took your code snippet above, put it in a file and assigned it as a Logoff Script in Local Group Policy on a Windows XP SP3 VM, and obtain the desired result. I set
HKCU\Software\Foo\Bar
equal toxxx
, logged-off, logged-on again, and found that the value had been changed toBaz
, as-expected.I think you're having some other kind of problem, aside from script execution. I added a
MsgBox
call to the code so I could "see" the code running on logoff. Adding the MsdBox did not change the registry-related behavior but did give me a visual indication the code was running (and held-up logoff until I dismissed the dialog).(I can go ahead and test on Windows 7, too, if you'd like but I anticipate no change in functionality.)
I imagine you are using
reg.exe
for modify registry entries. The problem is thatreg.exe
runs in a separate process, and logoff script only wait for itself to finish. So it's likely that registry hive gets unloaded before the edit gets done.I think you can solve the issue using two rows of WScript, like the following example:
The third parameter of
objShell.Run
, calledbWaitOnReturn
, tells the script to wait for the external process to complete before continuing the execution.There were actually two problems.
Firstly, in the presence of loopback policy one must be careful with rsop.msc because just using the default (i.e. ticking "jump to the last page of the wizard without collecting more data" right after selecting user and computer containers) may not reflect the true policy results. One must at least tick loopback on the second page (and replace or merge) to obtain realistic results. Being careful here helps diagnozing correctly if the script would be run at logoff.
Secondly,
SetStringValue
creates values if they don't exist before, but it does not create non-existing keys. Therefore,oReg.CreateKey HKCU,"SOFTWARE\Foo"
must be issued in the script (for the record,
CreateKey
does create non-existing keys recursively, but of course "HKCU\SOFTWARE" is already there).