How to create a Global Address List programmatically using Visual Basic

Since I do a fair share of programming in Visual Basic, C# and C++ I thought I would post something here for you guys that like to do things programmatically. With the code sample provided here in this article you will be able to use Visual Basic to create a Global Address List.

An Exchange Servers Global Address List is an Active Directory object that exists in the Configuration container of the Active Directory. In order for you to create a Global Address List, you must first create an addressBookContainer class object in the directory under the following object:

CN=All Global Address Lists,CN=Address Lists Container,CN=Organization,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=DomainName,DC=com

Global Address Lists, unlike address lists, cannot be nested and should be created in the All Global Address Lists container.

To enable MAPI (Messaging Application Programming Interface) clients to use a Global Address List, you must add the Distinguished Name of the newly created GAL to the globalAddressList attribute on the Microsoft Exchange container.

Once this is done you must then set the following two attributes on the Global Address List object before your first call to SetInfo when you create the object:

NOTE: Although the preceding attribute is marked optional, you must set it at object-creation time before the first SetInfo call. You must also set the following optional attributes:

  • purportedSearch (optional) : A single-valued directory string attribute that stores the search query filter for this GAL.
  • msExchPurportedSearchUI (optional) : A multi-valued attribute that stores the parameters necessary to rebuild the Exchange System Manager's (ESM) Find Exchange Recipients dialog box. This attribute does not need to be set; however, without a value, the Modify button on the General tab of your GAL's Properties dialog box is not available (dimmed).NOTE: This attribute is not documented; therefore, when you set it programmatically, this action is not supported. The best way to set this attribute is to actually create an address list with a similar query filter from ESM. Then, copy the value of the msExchPurportedSearchUI attribute for this newly-created address list, and then paste it into the msExchPurportedSearchUI attribute for the GAL that you are creating programmatically.

This Visual Basic sample code that I am displaying below creates a Global Address List in the Active Directory. Note that this code does not demonstrate how to modify security on the new GAL. This sample code requires that the "Active DS Type Library" topic be included in the Visual Basic references for this project. The minimum requirements to run this code include the following:

  • A Windows 2000, 2003, XP or Vista client with the Active Directory Client Extensions installed.
  • Administrative privileges over the domain that the Exchange Server computer on which you plan to create the GAL resides.

To create this Visual Basic Project, follow these steps:

  1. Start Visual Basic.
  2. Select the Standard EXE new project.
  3. Click Project, click References, and then add Active DS Type Library.
  4. Insert the following code in the Code view of the form:

Private Sub Command1_Click()Dim RootOUNameDim sSystemFlagsDim displayNameDim purportedSearchsSystemFlags = "1610612736"displayName = "testGAL5"purportedSearch = "(mailNickname=*)"' Get Address list containerSet AddressListCont = GetObject("LDAP://Myserver/CN=All Global Address Lists,CN=Address Lists Container,CN=MyOrg,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=MyDomain,DC=com") ' Create the New Address ListSet NewAddressList = AddressListCont.Create("addressBookContainer", "CN=testGAL5") NewAddressList.DisplayName = displayName'this will have to be customized based on the query filterNewAddressList.purportedSearch = purportedSearch'This can only be set at creation time'This attribute is set by passing a value that is defined by the ADS_SYSTEMFLAG_ENUM enumeration documented at -'https://msdn.microsoft.com/library/default.asp?url=/library/en-us/netdir/adsi/ads_systemflag_enum.asp'In this sample I am passing in the 1610612736 (0x60000000) which is'0x60000000 = 0x40000000 or 0x20000000 (ADS_SYSTEMFLAG_CONFIG_ALLOW_RENAME + ADS_SYSTEMFLAG_CONFIG_ALLOW_MOVE)NewAddressList.systemflags = sSystemFlags' Save New GALNewAddressList.SetInfoDebug.Print "GAL Saved OK."'Now that the GAL is created, we would need to add the distinguished' name of this new GAL to the "globalAddressList" attribute on the' CN=Microsoft Exchange object, so that Outlook clients would know' the list of all the GALs' If your not creating a GAL but creating a regular address list, you' should not perform the following steps!Set msExchService = GetObject("LDAP://MyServer/CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=MyDomain,DC=com")msExchService.PutEx ADS_PROPERTY_APPEND, "globaladdresslist", Array("CN=testGAL5,CN=All Global Address Lists,CN=Address Lists Container,CN=MyOrg,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=MyDomain,DC=com")msExchService.SetInfoMsgBox "Done"End Sub

 If you would like more information about Active Directory security you can referecene this article: 269159
 https://support.microsoft.com/kb/269159/EN-US -  HOWTO: Use Visual Basic and ADsSecurity.dll to Properly Order ACEs in an ACL 
 Dave