Jump to content
Sign in to follow this  
Charlesekeisler

Write to all current and future user's profile

Recommended Posts

Charlesekeisler

I Though i'd share this as there are almost no resources on the net on how to do this.

I wrote this code to overcome the limitation of some programs looking for HKCU (NTUSER.DAT) for their config, and ignoring HKLM.

A few interesting facts about user reg hives:

  • HKU\.DEFAULT is not the default user's profile, it is the SYSTEM profile!
  • All Locally stored user profiles can be found in HKU under the account's SID
  • The Default User's profile is the ONLY user profile registry hive NOT mounted to HKU by default (i'm guessing to avoid accidental corruption)
thanks to The Deployment Guys (at Microsoft) for mentioning how to mount the default user's profile

Without them I only had a script that would write to current, and not future users.

_RegWriteAllUsers("Software\WinImage", "NameRegistered", "REG_SZ", "Charles Keisler")

Func _RegWriteAllUsers($keyname, $valuename = "", $type = "", $value = "")
;Mount default profile for witing as it is not mountes to HKU by default
If FileGetVersion(@WindowsDir & "\system32\ntoskrnl.exe") >= 6 Then
RunWait('reg load "HKEY_USERS\DEFAULT" "' & @UserProfileDir & '\..\Default\NTUSER.DAT"', "", @SW_HIDE)
Else
RunWait('reg load "HKEY_USERS\DEFAULT" "' & @UserProfileDir & '\..\Default User\NTUSER.DAT"', "", @SW_HIDE)
EndIf
;Write to all offline profiles
For $i = 1 To 999999999
Local $var = RegEnumKey("HKEY_USERS", $i)
If @error <> 0 Then ExitLoop
If StringInStr($var, "_Classes") Then ContinueLoop
If StringLen($var) = 8 Then ContinueLoop ;fileter out system SIDs
RegWrite("HKEY_USERS\" & $var & "\" & $keyname, $valuename, $type, $value)
Next
;UnMount default profile
RunWait('reg unload "HKEY_USERS\DEFAULT"', "", @SW_HIDE)
;write to current profile
RegWrite("HKEY_CURRENT_USUER\" & $keyname, $valuename, $type, $value)
EndFunc

Share this post


Link to post
Share on other sites
kckennedy

I'll try this out - thanks!  Looks like you have a typo on the 2nd to last line though (_USUER instead of _USER):

;write to current profile
RegWrite("HKEY_CURRENT_USUER" & $keyname, $valuename, $type, $value)

                                                    ^

Share this post


Link to post
Share on other sites
kckennedy

This script works well for the current user and default user on both XP and Windows 7, but will not get all other pre-existing user profiles.  To do that, you would have to make sure all profiles listed in "HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionProfileList" are at least temporarily loaded into the registry (so they can be modified under the HKEY_USERS hive).

From what I can tell, in Windows XP you will only see in HKEY_USERS all profiles loaded that have logged in since the last bootup (plus system profiles).  In Windows 7, you will only see the current user loaded under HKEY_USERS (plus system profiles)...

Share this post


Link to post
Share on other sites
spudw2k

...you would have to make sure all profiles listed in "HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionProfileList" are at least temporarily loaded into the registry (so they can be modified under the HKEY_USERS hive).

 

I used to have an AU3 script to do that but don't have access to it on the machine I am using.

I do however have a VBScript I wrote originally that I crafted the AU3 from.  I figured I'd post it in case someone finds it useful.

'---------Global Variables---------

    varTime = Time
    Const HKEY_LOCAL_MACHINE = &H80000002
    Const HKEY_USERS = &H80000003
    strComputer = "."
    DQ = Chr(34)

'----------------------------------


'---------Script Execution---------

    UserSIDs = Split(GetSIDs,",")

'    for each objSID in UserSIDs
'   WriteRegFile(objSID)    
'    next

    wscript.echo "Complete.  Duration: " & Duration(varTime)
    wscript.quit

'----------------------------------


'-------Sub & Function Code--------

'Gather All Account SIDs on local machine
    Function GetSIDs
    Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
    strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"
    oReg.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys
 
    For Each subkey In arrSubKeys
        results = results & subkey & ","
    Next

    Result = FilterSIDs(results)
    GetSIDs  = Result
    End Function


'Filter only Established Profiles
    Function FilterSIDs(SID)
    arrResults = Split(SID,",")

    For i = 0 to UBound(arrResults)
        if Len(arrResults(i)) > 10 then 
        Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv") 
        strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\" & arrResults(i)
        strValueName = "ProfileImagePath"
        oReg.GetExpandedStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
        'if Instr(1,strValue,"Admin") < 1 and Instr(1,strValue,"what") < 1 then
            set objFS = CreateObject("Scripting.FileSystemObject")
            Rslt = objFS.FolderExists(strValue)
            if Rslt = True then 
            varSIDs = varSIDS & arrResults(i) & ","
            MountResult = MountNTUser(strValue,arrResults(i))
            wscript.echo "------------------------------------------------------------"
            wscript.echo arrResults(i) & vbcrlf & strValue & vbcrlf & MountResult
            wscript.echo "------------------------------------------------------------" & vbcrlf
            end if
        'end if
        end if
    Next

    if right(varSIDs,1) = "," then varSIDs = left(varSIDs,Len(varSIDs) - 1)
    FilterSIDs = varSIDs
    End Function


'Mount NTUser.dat file(s)
    Function MountNTUser(path,SID)
    Set WshShell = CreateObject("WScript.Shell")
    Set Exec = WshShell.Exec("%windir%\system32\reg load HKU\" & SID & " " & chr(34) & path & "\ntuser.dat" & chr(34))  
    strOutput = Exec.StdOut.ReadAll
    if instr(1,strOutput,"success") > 1 then
        MountNTUser = "Successful!"
    else
        MountNTUser = "Warning! Failed to Load Hive!"
    end if
   End Function


'Execution Duration Check
    Function Duration(varTime)
    varTime = Left(varTime,Len(varTime) - 3)
    arrStartTime = Split(varTime,":")
    varTime = Time
    varTime = Left(varTime,Len(varTime) - 3)
    arrEndTime = Split(varTime,":")
    if arrEndTime(1) > arrStartTime(1) then
        Duration = ((arrEndTime(1) - arrStartTime(1)) * 60 + arrEndTime(2)) - arrStartTime(2) & " second(s)."
    else
        Duration = arrEndTime(2) - arrStartTime(2) & " second(s)."
    end if
    End Function
'----------------------------------
Edited by spudw2k

Share this post


Link to post
Share on other sites
gonzcj

Hello Seeker,

I'm trying to use your code to apply a change to the registry of all users. I'm not a programmer but have been asked to look into the possibilities of getting this done at work. You think you can help me out with how it should look? I would really appreciate it!

Here is what needs to be added:

 [HKEY_CURRENT_USERSoftwareMicrosoftSpeechVoices]
"DefaultTokenId"="HKEY_LOCAL_MACHINESOFTWAREMicrosoftSpeechVoicesTokensVW Julie"

Best,

Claudia

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×