Looping over User Profile Directories

Share on:

I wrote the following script a few years ago to help me loop over all user profiles to make changes to a configuration file that was stored there.  The target systems were all Windows XP and Windows 7 at the time, but I couldn't be certain where the profiles would be (C:\Documents and Settings, C:\Users, D:\Users, etc), and I wanted to make sure to hit only valid profiles and not old copies such as username.old, that were left behind from troubleshooting.

The following script does just that.  I will not run on Windows 2000, since profiles were stored back in the Windows Directory then, and I want to ignore that folder, but it should run fine on Windows 8, although untested.  You could reuse this script to help delete certain folders from every existing profile, update an INI, or even create a folder on every desktop without using the the single public desktop.

The script is written with AutoIt, but it should be easy enough to translate into your language of choice. Sorry for the lack of comment, it was something I threw together quickly to resolve a problem in the environment.

 1#NoTrayIcon
 2#RequireAdmin
 3#Region ;\*\*\*\* Directives created by AutoIt3Wrapper\_GUI \*\*\*\*
 4#AutoIt3Wrapper\_Res\_requestedExecutionLevel=asInvoker
 5#EndRegion ;\*\*\*\* Directives created by AutoIt3Wrapper\_GUI \*\*\*\*
 6
 7#include <date.au3>
 8
 9$bReturnFail = 0
10
11$logDir = "C:\TEMP"
12$logFile = $logDir & "\ProfileUpdate.log"
13
14DirCreate($logDir)
15
16$i = 1
17While 1
18	$pList = RegEnumKey("HKEY\_LOCAL\_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList", $i)
19	If @error then ExitLoop
20	$profilePath = RegRead("HKEY\_LOCAL\_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\" & $pList, "ProfileImagePath")
21	$profilePath = \_ExpandStrings($profilePath)
22
23	If StringInStr($profilePath, "%") > 0 Then
24		FileWriteLine($logFile, \_Now() & " : Skipping SID " & $pList & " because ProfileImagePath contains variable (" & $profilePath & ")")
25		FileWriteLine($logFile, "")
26	ElseIf StringLeft($profilePath, StringLen(@WindowsDir)) = @WindowsDir Then
27		FileWriteLine($logFile, \_Now() & " : Skipping SID " & $pList & " because ProfileImagePath is in Operating System directory (" & $profilePath & ")")
28		FileWriteLine($logFile, "")
29	Else
30		FileWriteLine($logFile, \_Now() & " : Processing SID " & $pList & " (" & $profilePath & ")")
31
32		; You can now do whatever you want with $profilePath
33
34		FileWriteLine($logFile, "")
35
36	EndIf
37
38	$i = $i + 1
39WEnd
40
41if $bReturnFail = 0 Then
42	Exit(0)
43Else
44	Exit(99)
45EndIf
46
47Func \_ExpandStrings($data)
48
49	Local $pctStart, $pctEnd, $sBegin, $sEnd
50
51	; Find the First %
52	$pctStart = StringInStr($data, "%")
53	If $pctStart = 0 Then Return $data
54
55	; Find the Second %
56	$pctEnd = StringInStr($data, "%", false, 1, $pctStart+1)
57	If $pctEnd = 0 then Return $data
58
59	; Get Everything Before & After the Variable
60	$sBegin = StringLeft($data, $pctStart-1)
61	$sEnd = StringMid($data, $pctEnd+1, StringLen($data))
62
63	; Pull the Variable Out of the String (Without % Signs)
64	$envVar = StringMid($data, $pctStart+1, $pctEnd-$pctStart-1)
65
66	; Bring it all back together
67	$data = $sBegin & EnvGet($envVar) & $sEnd
68
69	; Is there more to do?
70	If StringInStr($data, "%") > 0 then
71		Return \_ExpandStrings($data)
72	EndIf
73
74	Return $data
75
76EndFunc


No comments