Refer to system administration scripts for background. The commands used in this script are available from Windows 2003 Server on. On Windows 2000 domain controllers, you will have to resort to ADSI scripts to do the same
Enumerating users and their group membership may be rather complicated, as one user can be member of several groups. The statement used in this script to collect users, groups, etc from Actiove Directory, works fine if a user is member of 1 and only one group. This is something we tried to achieve in the Active Directory Design, but in case the business logic requires that we make users member of more than one group, we may have to approach this differently.
Concept : for each user we will create a separate text file that contains all the groups that this user is a member of. To create unique names for these text files, we will use the user's SAMid - which will also allow as to identify the required file by user SAMid when we start reproducing the group membership.
REM enumerating group membership FOR /F "tokens=1-2" %%x in (.\adconf\users.txt) do ( dsget user "%%x" -memberof > .\adconf\user%%y.txt )
For user Betty with SAMID 'Betty' this will result in a file called 'userBetty.txt', containing a list of all groups Betty is member of. To reproduce this user's group membership in a new active directory, we iterate the list of users once again (userDN = token %%x), and find the corresponding file (by SAMID : token %%y) that contains the groups (token %%n) this user is member of. We add the userDN (%%x) to the groups found (%%n)
FOR /F "tokens=1-2" %%x in (.\adconf\users.txt) do ( FOR /F %%n in (.\adconf\user%%y.txt) do ( dsmod group "%%n" -addmbr "%%x" ) )
Be sure to use quotes around the parameters ("%%x", etc.) to avoid trouble with spaces in the Distinghuished Names. You may also need to qualify the FOR /F commands further (delims, tokens, ...) to be sure the DN's are passed to the dsmod command correctly (as pointed out by Brian de Jongh).
The previous sollution creates a large number of text files. For a large number of users, this may become troublesome. A sollution with a more powerful scripting language, allowing us to parse text files, manipulate strings, use complex variables and apply more elaborate control structures, may be more elegant. Here's a Visual Basic script to enumerate user group memberschip :
‘ Script (concept code) Const ADS_PROPERTY_APPEND = 3 For u = 0 to x ‘iterate users Set objGroup = GetObject _ ( "LDAP://” & arrUsersGroups(u,1) ) objGroup.PutEx ADS_PROPERTY_APPEND, _ "member", _ Array ( arrUsersGroups(u,0) ) objGroup.SetInfo Next ‘user’
The arrUsersGroups(x,y) would be an array containing user - group combinations. Other complex variables (structures, associative arrays, ...) should be possible to ...