21.3 Creating Many User Accounts

User-specific scripts work well if you have to create only a few user accounts. If you need to create many user accounts at one time, or if you create new accounts often, using a script with an input file is more efficient. The input file includes the user data so that you can use the script to create any user account. For example, the output shown below represents the users-to-create.txt input file that provides the user data for the universal script in Example 21-3. Although this input file includes only four data sets, you can include as many data sets as you want. You include a data set for each user account that you want to create.

vlaunders:12/09/01:The description:Victoria Launders:onebanana
aglowenorris:08/07/00:Another user:Alistair Lowe-Norris:twobanana
kbemowski:03/03/03:A third user:Karen Bemowski:threebanana
jkellett:08/09/99:A fourth user:Jenneth Kellett:four

As the output shows, each data set goes on a separate line. A data set can contain as many values as you want. The data sets in the users-to-create.txt file have five values: username, expiration date, description, full name, and password. You use colons to separate the values.[1]

[1] While comma-separate-value (CSV) files are the norm for this sort of thing, the comma is more often used in properties that will be added for users, so I use the colon here instead.

Example 21-3. Creating many user accounts using a script with an input file
Option Explicit

Const ForReading = 1

Dim objDomain, objUser, fso, tsInputFile, strLine, arrInput
Dim fldUserHomedir, wshShell

Set objDomain = GetObject("LDAP://cn=Users,dc=mycorp,dc=com")
Set fso = CreateObject("Scripting.FileSystemObject")

'Open the text file as a text stream for reading.
'Don't create a file if users-to-create.txt doesn't exist
Set tsInputFile = fso.OpenTextFile("c:\users-to-create.txt", ForReading, False)

'Execute the lines inside the loop, even though you're not at the end
'of the file
While Not tsInputFile.AtEndOfStream

  'Read a line, and use the Split function to split the data set into
  'its separate parts
  strLine = tsInputFile.ReadLine
  arrInput = Split(strLine, ":")

  Set objUser = objDomain.Create("user","cn=" & arrInput(0))
  objUser.Put "sAMAccountName", & arrInput(0)
  objUser.Put "userPrincipalName", arrInput(0) & "@mycorp.com"

  'Write the newly created object out from the property cache
  'Read all the properties for the object, including
  'the ones set by the system on creation

  'Set the properties
  objUser.AccountDisabled = False
  objUser.AccountExpirationDate = arrInput(1)
  objUser.Description = arrInput(2)
  objUser.IsAccountLocked = False
  objUser.LoginScript = "\\MYDOMAIN\DFS\Loginscripts\" & arrInput(0) & ".vbs"
  objUser.Profile = "\\MYDOMAIN\DFS\Users\" & arrInput(0) & "\profile"
  objUser.PasswordRequired = True
  objUser.DisplayName = arrInput(3)

  'Set the drive that you'll map to
  objUser.HomeDirectory = "\\MYDOMAIN\DFS\Users\" & arrInput(0)
  objUser.Put "homeDrive", "Z:"

  'Create the home directory
  If Not fso.FolderExists("\\MYDOMAIN\DFS\Users\" & arrInput(0)) Then
    Set fldUserHomedir = fso.CreateFolder("\\MYDOMAIN\DFS\Users\" & arrInput(0))
  End If

  'Set full rights for the user to the home directory
  Set wshShell = WScript.CreateObject("Wscript.Shell")
  wshShell.Run "cacls \\MYDOMAIN\DFS\Users\" & arrInput(0) _
    & " /e /g " & arrInput(0) & ":F", 1, True

  'Set the password
  objUser.SetPassword arrInput(4)

  'Stop referencing this user
  Set objUser = Nothing

'Close the file

The script reads in the user data to create the user accounts. As the script shows, you use FileSystemObject (FSO) and TextStream (TS) objects to manipulate the user data. For information about FSO and TS objects, see http://msdn.microsoft.com/library/default.asp?url=/nhp/Default.asp?contentid=28001169. After you create a reference to an FSO object and assign that reference to the fso variable, apply the FileSystemObject::OpenTextFile method to open the users-to-create.txt file, setting the user data to the tsInputFile TS variable. Then use a while loop with the TextStream::AtEndOfStream method to loop through each line in tsInputFile until the end of the file. Once you reach the end of the file, use the TextStream::Close method to end the script.

The while loop is the heart of the script. Begin the while loop by applying the TextStream::ReadLine method to read in one line of tsInputFile at a time. The strLine string variable holds the retrieved data from that line, which you pass to VBScript's Split function. Using the colon as the separator, this function splits the data set into its five parts, assigning the data to the arrInput array variable. This array has index values that correspond to the five parts: 0 represents the username, 1 represents the expiration date, 2 represents the description, 3 represents the full name, and 4 represents the password.

The code in the middle of the while loop is similar to the code used earlier. After we create a reference to an ADSI User object and assign that reference to the objUser variable, we set that user's property values (including the home drive). We then use IADs::SetInfo, create the home directory, set the directory permissions, and set the password. However, instead of specifying each user's username, expiration date, description, full name, and password in the code, we specify the appropriate array index value. For example, for those property values in which you need to specify the username, you specify arrInput(0) instead of vlaunders, aglowenorris, kbemowski, or jkellett.

The while loop ends with setting objUser to Nothing. We need to clear objUser because we use this variable again when the TextStream::ReadLine method reads in the next line from tsInputFile to create the next user account.

Instead of reading in user data from a text file, you can read in data from other sources, such as a web-based form, a Microsoft Word document, a Excel spreadsheet, a database, or even a specially formatted Microsoft Outlook email message. You also can use command-line arguments to pass in user data, as we will show in a later example.

    Part II: Designing an Active Directory Infrastructure
    Part III: Scripting Active Directory with ADSI, ADO, and WMI