CIS Logo SVC Logo

   Computing & Information Systems


Schoology Facebook        Search CIS Site      Tutorials

WSH Account Creation Example

Here is a really useful (and lengthy) script. It can generate a collection of customized user accounts with little or no manual intervention. The script was used for college students taking certain courses, but could be adapted to other situations. The idea is to read a file of data for the new accounts (essentially consisting of the names of the people and the courese that they are in). The script manipulates Active Directory to create accounts for these people and to give them access to network shares (mapped as network drives) for the particular courses they are in. The script must be run on the server where accounts are to be made. Account information (such as usernames and initial passwords) are written to a text file.

Warning: Adapt and test this script carefully. Test it, for example, by creating just a couple of accounts to start with. You don't want hundreds of incorrect accounts created, permissions set incorrectly on numerous folders, etc. Even once the script is working well for you, it still sometimes requires manual intervention. The most likely spot is when a requested new account would have the same username as an existing account. The script just warns you of this in the output file, so that you can decide later whether to make a new account manually for this case, whether the old account is really for the same person, etc.

' Filename:   AddUsers.vbs
' Date:      March 8, 2005
' Authors:   Br. David Carlson, Jessie Vernon, and Scott Gillis
' Based on script by:  Brian LaSitis
' Description:  This script uses a file of student names and course numbers and generates accounts  
'               for these students.  The script runs on a server running Windows 2003 Server.
'               An error message is sent to the "newuser.txt" file for each account that appears
'               to already exist.  Review any such messages to decide whether the old account can
'               be removed to make way for the new one or whether the old account is for the
'               correct person and only needs to be modified for the current semester.  New
'               account password info is also placed in the "newuser.txt" file.
'               Each line of the input file should be in the following format:
'               Items in parenthesis are optional.
'               Student ID;Last Name, First Name (Middle initial);Course 1;(Course 2;)
'               Here is an example:
'               779098;Student, Zach J.;CS 175-01;
'               Each student is given a course network drive and a homework drop-off folder for
'               each course the person is enrolled in.  The student ID number is ignored.
'               Here is the syntax used to run this script at the command line of the server:
'               AddUsers.vbs FILENAME
'               The one command-line parameter is the name of the input file.  This file should
'               be located in the same folder where the script is located.
' Modified September 3, 2006 by Br. David Carlson to generalize the script somewhat so that
' it will be easier for others to adapt it and use it.

Option Explicit

'LDAP Constants
Const cFQDN = ""  ' fill in the fully-qualified domain name for your server, e.g. ""
Const cNBDomain = ""  ' fill in the netbios domain, e.g. "itdept"
Const cDomain = ""  ' fill in the remaining 3 pieces, e.g. "DC=xyz,DC=zstate,DC=edu"
Const cServer = ""  ' fill in the server name, e.g. "alpha"

'Drive Letters & Paths
Const cWebSrvRoot = ""  ' fill in web server root location, e.g. "N:\wwwroot\"
Const cUsersRoot = ""  ' fill in root location for user directories, e.g. "P:\"
Const cProfilesRoot = ""  ' fill in location for user profiles, e.g. "Q:\Profiles\"
Const cHomeworkRoot = ""  ' fill in location for homework folders, e.g. "R:\"
Const cNetLogonRoot = ""  ' fill in location for folders holding logon scripts, e.g. "S:\scripts\"

'Variable Declaration and Initialization
Dim oItem, oOU, oUser, oGroup
Dim ts, oShell
Dim FullName, UserID, Given, Password, Surname, UserPrinc, OU, path, SkipFlag
Dim CourseNumArray, DriveArray
Dim fso, tsInFile, tsOutFile, tsDataLine, LineArray, k, NameArray, FirstArray
Dim UserName, FirstName, LastName, Course, CourseArray, CourseNum, CourseSection
Dim CourseList(6), NumCourses, i, str, args

' List drive letters usable by student accounts for mapped network drives (other
' than those using predetermined drive letters such as M).
DriveArray = Array("H:","I:","J:","K:","L:","N:","O:","S:","T:","U:","V:")

Const cScriptPath = ""  ' fill in the location for this AddUsers script, e.g. "S:\adminscripts\

'Checks to make sure a parameter was given
set args = WScript.Arguments
If args.Count=0 then
    Wscript.Echo "You must enter the file name."
    Wscript.Echo "EX: AddUsers.vbs FILENAME"
    Wscript.Quit 1
End if

Set fso = WScript.CreateObject("Scripting.FileSystemObject")
Set tsInFile = fso.OpenTextFile(args.item(0))

'Establish connection with root Active Directory Object.
Dim oRoot
Set oRoot = GetObject("LDAP://" & cFQDN & ":636/" & cDomain)
'Uncomment the following line and similar lines to get debugging messages.
'WScript.Echo "Connection to server established..."

Set oOU = oRoot.GetObject("organizationalUnit", "OU=IT Students")  ' adjust the organizational unit

Do While Not tsInFile.AtEndOfStream
   SkipFlag = 0
   ' Read a line of data, extracting the name and course information.
   tsDataLine = tsInFile.ReadLine
   LineArray = split(tsDataLine, ";")
   NumCourses = UBound(LineArray) - 2

   For k = 1 To UBound(LineArray) - 1
      If k = 1 Then
         NameArray = split(LineArray(1), ",")
         FirstArray = split(NameArray(1), " ")
         FirstName = FirstArray(1)
         LastName = NameArray(0)
         UserName = Left(LastName, 7) & Left(FirstName, 1)
         UserName = LCase(UserName)   ' done for consistency
         Course = LineArray(k)
         CourseArray = Split(Course, "-")
         CourseNum = CourseArray(0)
         CourseNumArray = Split(CourseNum, " ")
         CourseNum = LCase(CourseNumArray(0)) & CourseNumArray(1)
         CourseSection = CourseArray(1)
         CourseSection = Right(CourseSection, 1)
         Course = CourseNum & "-" & CourseSection
         ' Skip any courses that do not use homework and course folders.
         If CourseNum="ba465" or CourseNum="cs450" or CourseNum="cs550" or CourseNum="cs305" Then
         End If
      End If

   UserID =UserName 
   Given = FirstName
   Surname = LastName

   'Check to see if UserID is already being used.
   For Each oItem In oOU
      If oItem.Class = "user" Then
         If UserID = oItem.get("samAccountName") Then
            Set fso = WScript.CreateObject("Scripting.FileSystemObject")
            Set ts = fso.OpenTextFile("newuser.txt", 8, True)
            ' Adjust this message as desired:
            ts.writeLine("IT Department Windows 2003 Server Account Already Exists")
            ts.writeline("User already exists with ID: " & UserID)
            SkipFlag = 1
         End If
      End If

   If SkipFlag = 0 Then
      ' Create an account for this user.
      FullName = Given & " " & Surname
      UserPrinc = UserID & "@" & cFQDN
      'WScript.Echo "Creating User..."
      Set oUser = oOU.Create("user", "CN=" & CStr(FullName))

      'WScript.Echo "   Setting UserID"
      oUser.put "samAccountName", UserID

      'WScript.Echo "   Setting Name Information"
      oUser.put "userPrincipalName", UserPrinc
      oUser.put "givenName", Given
      oUser.put "sn", Surname
      oUser.put "displayName", FullName
      oUser.put "adminDisplayName", FullName

      'WScript.Echo "   Saving Settings"
      oUser.SetInfo  'Required before password setting occurs.

      'WScript.Echo "   Setting User Password"
      Password = GeneratePassword()

      'WScript.Echo "   Enabling Account"
      oUser.put "userAccountControl", CInt(512)

      'WScript.Echo "   Saving Settings"

      'Begin writing User Login Data to newuser.txt
      Set fso = WScript.CreateObject("Scripting.FileSystemObject")
      Set ts = fso.OpenTextFile("newuser.txt", 8, True)
      ts.writeLine("IT Department Windows 2003 Server Account")
      ts.write("Classes: ")

      'WScript.Echo "Setting Group Membership..."
      For k=0 to NumCourses-1
         oItem = "CN=" & CourseList(k) & ",OU=IT Students"  ' adjust the organizational unit
         Set oGroup = oRoot.GetObject("group", oItem)
         'WScript.Echo "   Adding to group " & oItem
         ts.write(CourseList(k) & " ")

      'Stage 1 Cleanup
      Set oGroup = Nothing
      Set OItem = Nothing

      'Continue Writing new user login data to newuser.txt.  Adjust the message as needed.
      ts.writeLine("Name: " & FullName)
      ts.writeLine("Username: " & UserID)
      ts.writeLine("Password: " & Password)
      ts.writeLine("This account is to access the IT dept PCs and Windows 2003 server.")
      ts.writeLine("See the printed directions in the lab or your instructor")
      ts.WriteLine("for full details on how to use our systems.  Make sure that")
      ts.WriteLine("you read and understand the college policies located on")
      ts.WriteLine("the main departmental web page at")
      ts.WriteLine("Direct any questions about the policies and any requests for")
      ts.WriteLine("systems support to NAME, PHONE, ETC.")
      ts.WriteLine("You will be prompted to change your password upon your first")
      ts.WriteLine("login, and about every NUMBER weeks thereafter.")

      'Create Folders for classes and homework
      Set oShell = WScript.CreateObject("WScript.Shell")

      'WScript.Echo "Creating logon script..."
      Set ts = fso.OpenTextFile(cNetLogonRoot & UserID & ".vbs", 2, True)
      ts.WriteLine("Dim Network")
      ts.WriteLine("Set Network = Wscript.CreateObject(""WScript.Network"")")
      ' Set up the standard drives: M - private drive for user, P - public drive, W - web drive.
      ts.WriteLine("Network.MapNetworkDrive ""M:"", ""\\" & cServer & "\users\"" & Network.UserName")
      ts.WriteLine("Network.MapNetworkDrive ""P:"", ""\\" & cServer & "\public""")
      ts.WriteLine("Network.MapNetworkDrive ""W:"", ""\\" & cServer & "\www\"" & Network.UserName")

      'Create User's Web Folder 
      path = cWebSrvRoot & UserID
      oShell.Run "xcacls " & path & " /t /e /g " & cNBDomain & "\" & UserID & ":F /y", 0, True

      'Create User's Home Folder
      path = cUsersRoot & UserID
      oShell.Run "xcacls " & path & " /t /e /g " & cNBDomain & "\" & UserID & ":F /y", 0, True

      'Copy Default XP My Documents Contents To User's Home Folder
      path = cUsersRoot & UserID
      oShell.Run "xcopy M:\DefaultUserDrive " & path & " /E /H /K", 0, True

      'Create User's Profile Folder
      path = cProfilesRoot & UserID
      oShell.Run "xcacls " & path & " /t /e /g " & cNBDomain & "\" & UserID & ":F /y", 0, True

      ' Set up user's homework folders:
      i = 0
      For k=0 to NumCourses-1
         oItem = CourseList(k) 
         'WScript.Echo "   Creating User Homework Folder for " & oItem
         str = "hw" & Mid(oItem,3)
         path = cHomeworkRoot  & "\" & str & "\" & UserID
         oShell.Run "xcacls " & path & " /t /e /g " & cNBDomain & "\" & UserID & ":F /y", 0, True
         ts.WriteLine("Network.MapNetworkDrive """ & DriveArray(i) & """, ""\\" & cServer & "\" & _
            str & "\" & UserID & """")
         ts.WriteLine("Network.MapNetworkDrive """ & DriveArray(i+1) & """, ""\\" & cServer & "\" & _
            oItem & """")
         i = i + 2
      'One course has an extra mapped network drive to give access to particular software:
      For k=0 to NumCourses-1
         oItem = CourseList(k)
         If oItem = "cs333-1" or oItem = "cs333-1adm" Then
            'WScript.Echo " Mapping drive for SOFTWARE NAME"  ' fill in the name of the software
            ' Adjust the directory location from abc on next line to location needed:
            ts.WriteLine("Network.MapNetworkDrive ""R:"", ""\\" & cServer & "\abc""")
         End If


      'WScript.Echo "Setting Permisions on logon script."
      oShell.Run "xcacls " & cNetLogonRoot & UserID & ".vbs  /t /e /g " & cNBDomain & "\" & UserID & ":F /y", _
         0, True

      'WScript.Echo "Finishing user creation."
      'WScript.Echo "   Setting Logon Info"
      oUser.put "profilePath","\\" & cServer & "\profiles\" & UserID
      oUser.put "scriptPath", UserID & ".vbs"
      oUser.put "pwdLastSet", 0

      'WScript.Echo "Successfully added " & FullName & " (" & UserID & ") " & "to the AD."
   End If
'Final Cleanup
Set tsInFile = Nothing
Set oShell = Nothing
Set oUser = Nothing
Set oOU = Nothing
Set fso = Nothing
Set ts = Nothing

' Password-generation function.  Adjust this to suit your situation,
' perhaps adding upper case letters and special characters and insisting
' on good password complexity. 

'Given:  Nothing.
'Task:   Generate a random, 8 character password.
'Return: The password.
Function GeneratePassword()      
   Const NUM_CHARS = 27;
   Dim Chars, pwd, r, k

   Chars = Array(2,3,4,5,6,7,8,9,"a","b","c","d","e","f","g","h","i","k","m","n","p","r","s","t","w","y","z")

   For k=1 to 8
      r = (100 * Rnd) Mod NUM_CHARS
      pwd = pwd & Chars(r)

   GeneratePassword = pwd
End Function

Back to main Windows Script Host page

Author: Br. David Carlson
Last updated: September 14, 2006