getUsers


The createUsers.bat script requires input from a text file that looks something like this :

input file : users.txt


	User		Role -> Group	Team

	-----------------------------------------
	Christine	Coordinators	PT
	Koen		Clerks		PT
	Kaat		Teamleiders	FT
	Brigitte	Clerks		FT
	Elsk		Clerks		ST
	Ina		Teamleiders	CT
	Kristel		Clerks		CT
	Anne		Teamleiders	ND
	<...>


		

Obviuosly, this file can be made manually, with any text editor, but for larger systems, and in the context of disaster recovery, it makes more sense to use a script to create such a file

net user

With net user > users.txt we can collect user accounts on the domein controller. However, the output is not in a very convenient format.

ADSI script

With an ADSI script, we have more control over the output. ADSI scripts can be used against any ADSI compatible system (e.g. Windows 2000 Domain Controller).

'Bulk Import and Export to the Active Directory
'Beta 2 Technical Walkthrough
'asg.web.cmu.edu/orpheus/msdocs/wt/dsbulk.doc

'modified by Koen Noens, June 2005

'parameter
Dim TAB, strDomain, objDomain

TAB =  chr(9)
strDomain = "KICKS"


'main
If UCase(Right((wscript.FullName),11)) <> "CSCRIPT.EXE" Then
	Wscript.Echo "this script is best run with:    CSCRIPT " & wscript.ScriptName & " [>> users.txt]"

Else
	EnumerateUsers
End If
Wscript.Quit


'---------------------------------
'SUBROUTINES and FUNCTIONS
'---------------------------------

Sub EnumerateUsers ()

	Dim objUser, strOutput

	Set objDomain = GetObject("WinNT://" & strDomain)
	objDomain.Filter = Array("User")

	For Each objUser in objDomain
		strOutput = objUser.DistinguishedName & TAB & objUser.Name
		wscript.Echo strOutput
	Next

End Sub

		

That is pretty staightforward, but unfortunately it does noet work. The objUser object apparently does not have a 'DistinguishedName' property, or it can not be accessed this way. Fortenately, the Scripting Guy knows an other way :


'get user distinguished name
'The scripting guy:
'http://www.microsoft.com/technet/scriptcenter/resources/qanda/oct04/hey1021.mspx
'modified by Koen Noens, June 2005

'parameters
Dim TAB, strDomain, objDomain

TAB =  chr(9)
strDomain = "dc=kicks,dc=local"


'main
If UCase(Right((wscript.FullName),11)) <> "CSCRIPT.EXE" Then
	Wscript.Echo "this script is best run with:    CSCRIPT " & wscript.ScriptName & " [>> users.txt]"

Else
	EnumerateUsers
End If
Wscript.Quit


'---------------------------------
'SUBROUTINES and FUNCTIONS
'---------------------------------

Sub EnumerateUsers ()
On Error Resume Next

	Const ADS_SCOPE_SUBTREE = 2
	
	'ADODB connection stuff to query LDAP
	Set objConnection = CreateObject("ADODB.Connection")
	Set objCommand =   CreateObject("ADODB.Command")
	objConnection.Provider = "ADsDSOObject"
	objConnection.Open "Active Directory Provider"
	Set objCommand.ActiveConnection = objConnection

	objCommand.Properties("Page Size") = 1000
	objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE 

	'query LDAP to get all user distingished names e.a.
	objCommand.CommandText = _
    		"SELECT distinguishedName, sAMAccountName FROM 'LDAP://" & strDomain & "'"  & _
        	"WHERE objectCategory='user'"

	Set objRecordSet = objCommand.Execute

	'iterate recordset and create output

	objRecordSet.MoveFirst
	Do Until objRecordSet.EOF
		strOutput = objRecordSet.Fields("distinguishedName").Value  & TAB & objRecordSet.Fields("sAMAccountName").Value
		wscript.Echo strOutput
		objRecordSet.MoveNext
	Loop
End Sub


		

This produces a list of users distinguished names and SAM ID's in users.txt when you execute the scripy at the command prompt ( CSCRIPT getUSers.vbs " >> users.txt ) and can be used as an alternative for dsquery (see further), eg when you want to collect user accounts from a Windows 2000 domain controller and reproduce them on a Windowss 2003 domain controller using the dsuser add command.

Clearly, the Organizational Unit(s) each user belong in are obvious from the distinguished name. If, for some reason, you'd like to isolate the OU from the distinghuished name, you can do so with the following statements :


	strDN = objRecordSet.Fields("distinguishedName").Value
    	arrPath = Split(strDN, ",")
    	intLength = Len(arrPath(1))
    	intNameLength = intLength - 3
    	
	strOU = Right(arrPath(1), intNameLength)

		

dsquery

On recent Windows systems (XP, 2003 Server), a new set of commands exists that can be used to collect user account information and recreate it.


	dsquery user | dsget user -dn -SAMid  > users.txt

		

Result:


  	(...)
  	CN=Leen,OU=ST,OU=kantoor,DC=KICKS,DC=LOCAL        Leen              
 	CN=Elsk,OU=ST,OU=kantoor,DC=KICKS,DC=LOCAL        Elsk              
  	CN=Ina,OU=CT,OU=kantoor,DC=KICKS,DC=LOCAL         Ina
  	(...)

		

This file can easily be used to create the same accounts again, including the Organization Units and Domain name.


	REM (line breaks added for readibility)

	FOR /L "tokens=1-2" %%x in (users.txt) do (

		Dsadd	user "%%x" 	-samid %%y
					-pwd aaaAAA111 
					-mustchpwd yes 
					-canchpwd yes 
					-profile \\SRV01\users$\%%y
					-hmdir \\SRV01\home$\%%y
					-hmdrv P :
					-loscr logon.bat
	)
		

Using the distinguished name to create the account automatically puts the user in the correct Organizational unit, as OU's and domain are part of the name.


Koen Noens
june 7, 2005