Creating a list of Users and their e-mail addresses in Exchange 2000

Amit Zinman photo
In Exchange 5.5 you had a GUI interface that let you easily import and export users in the Exchange Administrator utility. Active Directory essentially lets you do the same thing with two utilities: Ldifde and CSVDE. However, both utilities are not that easy to use. Basically you have to unappealing options: either you export the entire directory and start filtering through the many fields available there (and there are a lot!) or you deal with command line switches.


In Exchange 5.5 you had a GUI interface that let you easily import and export users in the Exchange Administrator utility. Active Directory essentially lets you do the same thing with two utilities: Ldifde and CSVDE. However, both utilities are not that easy to use. Basically you have to unappealing options: either you export the entire directory and start filtering through the many fields available there (and there are a lot!) or you deal with command line switches.

To make it easier from you I’ve written a simple VBScript script that exports all users and their e-mail addresses to a CSV file. Since it was one of the first scripts I’ve ever written, it’s not that complex. You can change my script to export to Excel, or add fields to it as you find useful, such as the user’s department. If you haven’t yet invested the time yet to understand the workings of VB you can simply run the script and collect the “users.csv” file that it creates at the root of drive C and load it into Excel.

The script is a recursive one. This means it does not perform an LDAP query against Active Directory to find all the users, because at the time I did not know how to do this. Instead, it goes through all the OUs and Containers. If an OU has sub-OUs, it searches all sub-OUs. This is slower than LDAP searches of course, but makes the script easier to understand.

First thing we want to determine the domain in which we are running. This means that this code would run on your domain without any modifications:

Dim rootDSE, domainObject
Set rootDSE=GetObject("LDAP://RootDSE")
domainContainer = rootDSE.Get("defaultNamingContext")
Set domainObject = GetObject("LDAP://" & domainContainer)

This code, though complex looking, simply connect to RootDSE which is as the name implies the top of the directory, gets “defaultNaming Context” which is the domain that the script is run on, and binds to it using LDAP to return the “domainObject”

Next, we create a text file, named “c:\user.csv”.

Set fs = CreateObject ("Scripting.FileSystemObject")
Set userFile = fs.CreateTextFile ("c:\users.csv")

Then, we call a subroutine, ExportUsers, that writes user information to a file.

ExportUsers(domainObject)

After running it, we clean up, send a message box saying we’re done.

Set oDomain = Nothing
MsgBox "Finished"
WScript.Quit

So, here is the subroutine that does most of the work.


Sub ExportUsers(oObject)
Dim oUser
For Each oUser in oObject
Select Case oUser.Class
Case "user"
If oUser.mail <> "" then
userFile.Write "," & oUser.displayName & "," & oUser.sAMAccountName & "," & oUser.userprincipalname & ","
for each email in oUser.proxyAddresses
userFile.Write email & ","
next
userFile.WriteLine ""
End if
Case "organizationalUnit" , "container"
If UsersinOU (oUser) then
ExportUsers(oUser)
End if
End select
Next
End Sub

We have a for loop that looks at the domain folder and looks at all the object there. Naturally at the domain level, everything is just containers and OUs. If it encounters an OU or a container, it simply runs itself again, this time on the OU/Container if it is not empty.
If it finds users it writes some their name and username to the file, then goes through all of their mail addresses (since each use can have many).

The function below looks at an OU or Container to see if it has any users inside. Notice that it calls itself to determine if any OUs or Containers inside also contain users.

Function UsersinOU (oObject)
Dim oUser
UsersinOU = False
for Each oUser in oObject
Select Case oUser.Class
Case "organizationalUnit" , "container"
UsersinOU = UsersinOU(oUser)
Case "user"
UsersinOU = True

End select
Next
End Function

This is about it. One of my next articles will show how to this more efficiently, using LDAP queries

About Amit Zinman

Amit Zinman photo Currently working as Project Manager and Systems Consultant, heading and consulting on Exchange and NT/Windows 2000 based migrations and deployments for large companies such as Checkpoint, Comverse, Smarteam, Nice, Aladdin and leading Israeli Banks, Also involved in writing scripts and custom solutions for clients based on ADSI, CDO and Visual Basic and teaching Windows 2000 and Exchange 2000 in MSCE colleges and lecturing in Microsoft User Groups.

Click here for Amit Zinman's section.

Share this article

Receive all the latest articles by email!

Get all articles delivered directly to your mailbox as and when they are released on MSExchange.org! Choose between receiving instant updates with the Real-Time Article Update, or a monthly summary with the Monthly Article Update. Sign up to the MSExchange.org Monthly Newsletter, written by Exchange MVP Henrik Walther, containing news, the hottest tips, Exchange links of the month and much more. Subscribe today and don't miss a thing!



Receive all the latest articles by email!

Receive Real-Time & Monthly MSExchange.org article updates in your mailbox. Enter your email below!
Click for Real-Time sample & Monthly sample

Become an MSExchange.org member!

Discuss your Exchange Server issues with thousands of other Exchange experts. Click here to join!

Solution Center

Readers' Choice

Which is your preferred OWA Addon solution?