Migrating the Address Book from Exchange 5.5 to Exchange 2000
The old Exchange address book was not very powerful or complex but it did the job in most situations. A handy feature that existed in Exchange 5.5 was automatic creation of address lists. All you had to do was go to File à New Other à Address Book View, choose a mailbox attribute and almost immediately you would get address view for all your departments or whatever attributes you decided to sort users by.
Exchange 2000 now has a new feature mentioned in my previous article (Creating a list of Users and their e-mail addresses in Exchange 2000 (2)) called Address Lists that is more powerful and lets you create very specific rules based criterions such as "all users in Mexico that are not in Management".
To create a new address list you go Recipients choose any address list and from the menus select Action à New à Address List: and the fill out the name and criterions.
Now, although it based on a very powerful LDAP query engine, you can't create Address Lists, say, for all your departments without some effort. This is usually not a problem since departments in most companies do not change on a daily basis but becomes a real headache when dealing with Exchange 5.5 migrations and corporate restructuring. To further clarify this, let say you are a big company with many branches. In Exchange 5.5 it took you about 20 seconds to create Address Book Views for all the branches by sorting users by their Custom Attribute 1. If a new branch was built somewhere you didn't even have to deal with it as a new Address Book View would magically appear for that branch. Now in the process of migrating to Exchange 2000 you figure that you will have to manually create 300 or more Address Lists for to match the Exchange 5.5 ones. In this article I will present a way to ease this process by using scripting.
To create the screenshots for this article I set a test lab and created a few users. For the users I filled out Custom Attribute 1 to reflect their branch designation and created a simple address book view. All in all, in less then five minutes my Address book was fully functional with those five branches.
Now I will show how to "transfer" these to Exchange 2000 (actually to Active Directory). First, we export the Address Book Views. This can be done manually or by script. To make things simple, in this article we will export these manually.
To export all branches Address Book Views I selected all of them on the right pane, and from the menu selected File à Save Windows Contents and saved the information to a file by the name of Branches.CSV.:
Then I touched up the file a bit so that only Branch names will be available and renamed it Branches.txt
Okay, so now I had a file containing all branch names so I figured it was time to do some scripting magic. In a real environment now was a good time to think about some changes since Exchange 2000 Address Lists can now use all the directory fields unlike the Address Book Views in Exchange 5.5. For example, instead of using the awkward a script or an LDIF import/export could be used to use the Office attribute instead of Custom Attribute 1. In the lab for the Exchange 2000 part I used the Office attribute as if indeed this has been performed but I might as well just used Custom Attribute 1.
The following script is based on an example I found on MSDN for programmatically creating address lists.
First, the script opens the text file just created and runs through all the lines to create the address lists.
Set fs = CreateObject ("Scripting.FileSystemObject")
Set userFile = fs.OpenTextFile ("c:\branches.txt")
Do Until userFile.AtEndOfStream = True
Lets see what my subroutine actually does and how I created it.
Sub CreateAL (strBranch)
sSystemFlags = "1610612736"
Up till now, pretty straightforward declarations and a system flag that I guess MS programmers can better explain. Now I constructed the LDAP search by constructing a fake branch Address List in Exchange 2000 System Manager.
After creating the Address List I copied its LDAP search query string.
This I pasted into my script to the purportedSearch string except that instead of the "fakefake" fake branch name the string extracted from the branches.txt file is pasted.
purportedSearch = "(&(&(&(& (mailnickname=*) (| (&(objectCategory=person)(objectClass=user)(!(homeMDB=*))(!(msExchHomeServerName=*))) (&(objectCategory=person)(objectClass=user)(|(homeMDB=*)(msExchHomeServerName=*)))(&(objectCategory=person)(objectClass=contact)) (objectCategory=group)(objectCategory=publicFolder) )))(objectCategory=user)(extensionAttribute4=" & strBranch & ")))"
Now I ran ADSIEdit to find out the full directory name of the address list container in Active Directory. ADSIEdit is available if you install the Windows 2000 support tools available on the Windows 2000 CD. To run it enter adsiedit.msc in the Run dialog box.
Then I drilled down to the parent "Branches" Address List container and copied its path to the script.
' Get Address list container
Set AddressListCont = _
GetObject("LDAP://myserver.mydomain.com/CN=Branches,CN=Org,CN=All Address Lists,CN=Address Lists Container,CN=Org,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=leumi")
Now the following section creates the actual Address List
' Create the New Address List
WScript.Echo "Creating " & strAL & " " & strBranch
Set NewAddressList = AddressListCont.Create("addressBookContainer", "CN=" & strBranch)
NewAddressList.DisplayName = StrBranch
'this will have to be customized based on the query filter
NewAddressList.purportedSearch = purportedSearch
NewAddressList.systemflags = sSystemFlags
' Save New AL
WScript.Echo "Created Address List" & strBranch
And so the script ends. This script can be modified to search Active Directory for added branches instead of looking at a text file and automatically create them for you the way it did in Exchange 5.5. To automatically run it you just set it to run every couple of minutes using the Task Scheduler.