Link to home
Start Free TrialLog in
Avatar of Pete Long
Pete LongFlag for United Kingdom of Great Britain and Northern Ireland

asked on

Bulk creation of users in Active Directory

I know CSVDE and LDIFDE can be used for bulk impotation of users.

CSVDE is a non starter because it cannot set passwords.

So Im left with LDIFDE, however this does not work with .csv files (all the users concerned are in a spreadsheet)

So - What I want to know is

is it possible to bulk import from a CSV (or another format) users into active directory.

I require the accounts to be set up with

First Name
Last Name
Logon Name
Password set to "password"
Password set to require changing at next log on
users to be created as standard users (not put in a particular OU)
users that are created should NOT be created with the accounts disabled.

additional info

if it will help my domain namespace will be  middlesbroughpct.nhs.uk
I can rejig the spreadsheet to fit any coded solution.

ideas guys'n'gals????

Pete
Avatar of Debsyl99
Debsyl99

Sorry, must remember to properly read problem FIRST, then post later!
SOLUTION
Avatar of Netman66
Netman66
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Pete Long

ASKER

Deb LOL - No Problem Ive done it myself

Netman66 & oBdA

Many thanks guys Ill be back in the office tommorow and Ill take a look at both your suggestions.

dont think Ive forgotten, then I'll have to do a bit of testing on the test network - Ill report back as soon as ive got something

regards

Pete
Pete,
You could do this with VBScript also fairly easily. I will make an example and post later...

4auHuk

Outstanding - waiting with anticipation

Pete
I just noticed I did too much copy & paste. The Resource Kit help to addusers.exe is incorrect; the correct user definition is

UserName,FullName,Password,Comment,HomeDrive,HomeShare,Profile,Script,
Ok, here it is.

1. Disclamer
I'm not a VBScript guru so following script may be not optimal.
It worked in my test environment but you should indeed test it first also.
I did not write error handling so be carefull with parameters.

2. What it does.
Well, exactly what you need. It reads text file that contains full user names one per line in format:

John Doe
Jane Doe

Note: No empty strings allowed in this file.

Then it creates users with corresponding first, last and full names in "Users" container in your AD. Logon name is combined from first letter of first name and lastname, all lowercase. "John Doe" will have logon name "jdoe".
Then it sets default password (same for all users), enables accounts and sert "User must change password at next logon" option.
That's all :)

3. Parameters
Three parameters: distinguished domain name, default password, users list file path.
They are hardcoded in script. See script comments.

4. How to run.
Save following script in file with vbs extention and run by issuing this command at command prompt: "cscript /nologo scriptname.vbs"

5.Script:

dcroot   = "dc=company,dc=org"        ' base path. Put "dc=middlesbroughpct,dc=nhs,dc=uk" here
Password = "password"                     ' Default password assigned to all created users
usrfile  = "c:\users.txt"                       ' File containing users' full names list.

' Reading usrfile
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(usrfile, 1)
Do Until objFile.AtEndOfStream
      Fullname = objFile.ReadLine
      If not FullName = "" Then
            st        = InStr(FullName, " ")
            FirstName = Mid(FullName,1,st-1)
            LastName  = Mid(FullName,st+1)
            LogonName = LCase(Mid(FirstName,1,1)) & LCase(Lastname)
' Creating user account
            Set objContainer = GetObject("LDAP://cn=Users," & dcroot)
            Set objNew = objContainer.Create("User", "cn=" & FullName)
            objNew.Put "sAMAccountName", LogonName
            objNew.Put "givenName", FirstName
            objNew.Put "sn", LastName
            objNew.Put "displayName", FirstName & " " & LastName
            objNew.SetInfo
            Set objNew = Nothing
' Setting password and enabling account
            Set objUser = GetObject("LDAP://cn=" & FullName & ",cn=Users," & dcroot)
            objUser.ChangePassword "", Password
            objUser.AccountDisabled = FALSE
            objUser.Put "pwdLastSet", 0
            objUser.SetInfo
            Set objUser = Nothing
            WScript.Echo "User """ & FirstName & " " & LastName & """ created."
      End If
Loop
objFile.Close

6. Did i forget something to mention?.. :)
4auHuk

Looks - cool havnt tested it yet though, will this set the accounts to "change password at next logon"?

Pete
and for your example

John Doe
Jane Doe

it wont create two users called jdoe will it?

and - how difficult is it to swap the username around to produce doej instead of jdoe (eg I would be longp) sorry to be awkward

Pete
>will this set the accounts to "change password at next logon"?
Yes, these lines does this:
objUser.Put "pwdLastSet", 0
objUser.SetInfo

>it wont create two users called jdoe will it?
I was sure you will notice this :) It will give you error "Objest already exist" since logon names are the same.
Well, we can set up the script to make unique logon names by, say, adding numbers (jdoexx), and inform you in log
User "John Doe" (jdoe) created.
User "Jane Doe" (jdoe01) created.
Or to write unique logon names in usrfile and get them from there.

It is a sample that takes about 30 min. to write so it does not cover all cases of course.
>and - how difficult is it to swap the username around to produce doej instead of jdoe

Was:
LogonName = LCase(Mid(FirstName,1,1)) & LCase(Lastname)

Will be:
LogonName =  LCase(Lastname) & LCase(Mid(FirstName,1,1))
>>objUser.Put "pwdLastSet", 0

Brilliant!

>>Will be: LogonName =  LCase(Lastname) & LCase(Mid(FirstName,1,1))

Brilliant!


>>Well, we can set up the script to make unique logon names by, say, adding numbers (jdoexx), and inform you in log
>>User "John Doe" (jdoe) created.
>>User "Jane Doe" (jdoe01) created.
>>Or to write unique logon names in usrfile and get them from there.

Mmmmm

how difficult would it be for.....

jon doe

script creates doej

jane doe

doej arready exists so it adds the second letter (fist name) and creates

doeja

if by some incredibly random chance that also exists it simply adds the next letter (first name) and creates

doejan

and it continues to loop till its unique (I know this will only go so far but the chances of there being a number of users with names that similar are very long)

>>I'm not a VBScript guru so following script may be not optimal.

Dont put yourself down, It all looks like arabic to me Im a network Engineer! LOL

Regards

Pete

ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Im back at home now :(

I intend to post a "points for 4auHuk" question (Ill have to ask the mods to post another 500 pointQ)

award points as a split in this question.

just so you guys dont think Im messing you about :)

As soon as Ive tested it I'll report back, you are putting a lot of effort and its much appreciated - ThanQ
Hi Pete,

I wish everyone dealt with questions like you do!

Good luck with this one, I'm watching and learning!!

Deb :)
>>I wish everyone dealt with questions like you do!

I think everyone who provides some help should be rewarded, Ive spent many hours on the site answering questions and have gone for days without getting a "Good Answer" So I know what that feels like :(

Pete
Right - Im off out to test this code - Ill report shortly :0)
OK ran the script with a big list of usernames and it worked like a charm.

Then I gave it a list of name that were more difficult like

Christine Long
Christopher Long
Tanya Long
Tania Long

And again it worked like a charm :0) Though I have hit a problem :0(

If two users have the SAME name then it falls over.....................

contents of user.txt

Tanya Long
Chritine Long
Tania Long
Christopher Long
Peter Seaton
Peter Seaton


Response from script run

C:\>cscript /nologo makeusr.vbs
Reading user names from c:\users.txt

Line number:    Action:
==================================================
1               User "Tanya Long" (longt) created.
2               User "Chritine Long" (longc) created.
3               User "Tania Long" (longta) created.
4               User "Christopher Long" (longch) created.
5               User "Peter Seaton" (seatonp) created.
6               Can not create user "Peter Seaton"

This is a problem for me, because I have two Peter Seatons on the Live system and I suspect there will be a couple more users with the same name, can this be caught in the code and rectified???

Otherwise in awe!

Pete
Of course it can.
How do you want the script to make unique name? You choose.

The quick and dirty way is manual. Since script will continue to create another users leaving a sign in log about failures and since i do not suspect a big number of users with same names, you can analyze log and create the manually.
But we want it be fully automatic, right? :)

One note i want to make: Be careful with usrfile format. The script relies heavily on the fact that each line reads as
Firstname[space]LastName
It does not check for corrct line syntax. If ,say, no space exist or extra space put in the start of line script will fail. Sometimes even giving you wrong error description like "Can not bind to.."
If extra space exist at the end of line, it will be included as part of LastName.


Best,
4auHuk
Thanks for the quick reply :0)

I do need to create users with the same name's and Knowing AD I know this is not a problem in LDAP, I thought the script would create the first user as

seatonp
and the second as
seatonpe

So I was supprised it errored? If I can overcome this problem the scriupt will be perfect (I intend to use it in the future)

Also If you dont mind, Ill post it on my wesite, so if you want to put your name in the script, Ill credit it to your good self - providing you have no objections of course :)

Pete
Oh, i got it.
The problem is that object names must be unique within same container in AD while logon names are unique across domain.
You can create as many "John Doe" user objects in different containers as you want but one per container. It's like file names within same directory.
That's what i mean when talking about unique names in previous post.

>I intend to use it in the future
I suppose i will also :)

>Also If you dont mind...
Not at all. No need to put my name in the script either.
As i said before and that was my whole point, VBscript is very useful and simple to learn language.
This script is very simple by code. And it is not an "Enterprise" level script. I mean, it still does not handle all possible errors, does not check usrfile line syntax etc. It should still recieve some testing and coding to make it safe to post as a general solution for bulk user creation. But you are free to do with it whatever you wish.

4auHuk
Well It would seem you are correct (I tried manually) Im glad my name isnt Dave Smith LOL right then, I can solve this problem from the input then, as its in Excel I can sort it alphabatically and check for any duplicates, and root them out before I run the script.

Good best go and ask permission to give you some extra points then :-)
Well, I found this topic to be a good practice as it is real problem, not another book example. So i really feel myself rewarded already.
Pete, if you ask me I would say that you do not need to spend more points than you assigned to this question.

Best,
4auHuk
Points for 4auHuk https://www.experts-exchange.com/questions/20901654/Points-for-4auHuk.html

>>that you do not need to spend more points
Im a PS Member it dont cost me anything :0)

Regards
Pete
4auHuk...Great Code...just one question.

If I wanted to add another field to the users.txt file so that its First Name, Last Name, Student ID and I would like the Student ID to be the password...can the code be modified easily to do this?  I am not familiar with vb code and syntax.  If its too much of a pain its no big deal but I was hoping to do that.  Thanks for your help
Yes, it shouldn't be hard.
Can't test code below right now, but it should work.
Each line of users.txt must contain three fields (first name, last name and student id) delimited by spaces.
Test it.

--Start------------------------------
On Error Resume Next
dcroot = "dc=company,dc=org"   ' Base path. Put "dc=subdomain,dc=domain,dc=domain" here.
Password = "password"              ' Default password assigned to all created users
usrfile = "c:\users.txt"                 ' File containing users' full names list.

Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists(usrfile) Then
    Set objFile = objFSO.OpenTextFile(usrfile, 1)
Else
    Wscript.Echo "File" & usrfile & " does not exist."
    WScript.Quit
End If

WScript.Echo "Reading user information from " & usrfile & VbCrLf
WScript.Echo "Line number:" & VbTab & "Action:"
WScript.Echo "=================================================="
Do Until objFile.AtEndOfStream
    succ = FALSE
    i = 1
    CurLine = objFile.Line
    FullName = objFile.ReadLine
    If not FullName = "" Then
        st = InStr(FullName, " ")
        FirstName = Mid(FullName,1,st-1)
        FullName  = Mid(FullName,st+1)
        st = InStr(FullName, " ")
        LastName = Mid(FullName,1,st-1)
        Password = Mid(FullName,st+1)
        FullName = FirstName & " " & LastName
        LogonName = LCase(Lastname) & LCase(Mid(FirstName,1,1))
        Set objContainer = GetObject("LDAP://cn=Users," & dcroot)
        If Err <> 0 Then
            WScript.Echo "Can not bind to " & dcroot & ". Check syntax."
            WScript.Quit
        End If
        Err.Clear
        Do Until succ or i>3
            Set objNew = objContainer.Create("User", "cn=" & FullName)
            objNew.Put "sAMAccountName", LogonName
            objNew.SetInfo
            If Err <> 0 Then
                 i = i+1
                LogonName = LCase(Lastname) & LCase(Mid(FirstName,1,i))
                Err.Clear
            Else
                succ = TRUE
                objNew.Put "givenName", FirstName
                objNew.Put "sn", LastName
                objNew.Put "displayName", FirstName & " " & LastName
                objNew.SetInfo
                Set objNew = Nothing
                Set objUser = GetObject("LDAP://cn=" & _
                              FullName & ",cn=Users," & dcroot)
                objUser.ChangePassword "", Password
                objUser.SetInfo
                If Err <> 0 Then
                    pwderr = "Can not set password (restrictions?). Left blank."
                    Err.Clear
                Else
                    pwderr = ""
                End If
                objUser.AccountDisabled = FALSE
                objUser.Put "pwdLastSet", 0
                objUser.SetInfo
                Set objUser = Nothing
                WScript.Echo CurLine & vbTab & vbTab & "User """ & _
                             FullName & """ (" & LogonName & ") created. " & pwderr
            End If
        Loop
        If not succ Then
            WScript.Echo CurLine & vbTab & vbTab & _
                         "Can not create user """ & FullName & """"
        End If
    Else
        WScript.Echo CurLine & vbTab & vbTab & _
                     "Skipping Empty line in " & usrfile
    End If
Loop
objFile.Close

--End-----------------------------
4auHuk:

Worked like a charm, thanks for all the help, your code has saved hours of work
4auHuk:
thanks for the good code; but would it be possible to set the student ID field in the txt file as the username? or would this be too painfull?

All the best
                 Phil
 
Philipbrooke

perhaps it might be fairer to 4auHuk if you posted another question?

Pete
Pete:

My apologies Pete, I am a new user and was unfamiliar with the points system.

I have set up a new question, Please view

https://www.experts-exchange.com/questions/21020690/Bulk-User-Creation-In-Active-Directory-From-a-Text-File.html
GR8 Philip  - No need to appologise we were all new here once - hope you get sorted out

best wishes

Pete
Hey guys,
Sorry for not answering soon, I'm temporarily out of EE. I'll take a look at new topic and 'll see if I can help.

4auHuk
Hmm, question has been deleted... Philip, do you still need any assistance with this script?

4auHuk
Thanks for your responce 4auHuk, but I have solved my problem.
Thanks Anyway

Phil
One comment on this code, very well written btw, it would be easier to use the split() function to parse a csv file into an array, its faster and works well for long input files, i ran into this situation myself and the script ran quite a bit faster just using this function

reference: http://www.w3schools.com/vbscript/func_split.asp
Would it be possible to modify this script so that it would work on just a Windows 2003's local accounts as my server isn't in a domain just a workgroup.

Question asked here

https://www.experts-exchange.com/questions/21223055/How-do-Create-accounts-via-a-batch-file-and-set-password-to-change-on-logon.html