Click here to Skip to main content
5,787,682 members and growing! (18,708 online)
Email Password   helpLost your password?
General Reading » Hardware & System » Active Directory     Intermediate License: The Code Project Open License (CPOL)

Mail Enable with Exchange 2007 using LDAP

By LiQuick

How to mail enable AD accounts using LDAP and Exchange 2007.
C# (C# 1.0, C# 2.0, C# 3.0, C#), VB (VB 7.x, VB 8.0, VB 9.0, VB), .NET (.NET, .NET 1.1)

Posted: 9 Oct 2008
Updated: 9 Oct 2008
Views: 4,323
Bookmarked: 13 times
Announcements
Loading...



Search    
Advanced Search
Sitemap
3 votes for this Article.
Popularity: 2.15 Rating: 4.50 out of 5
0 votes, 0.0%
1
0 votes, 0.0%
2
0 votes, 0.0%
3
1 vote, 33.3%
4
2 votes, 66.7%
5

Introduction

This article shows you have you can use LDAP and the System.DirectoryServices Namespace to mail enable an Active Directory user account when you are using Exchange 2003 and 2007.

Background

Exchange 2007 and a lot of new products of Microsoft rely heavily on Powershell to script and automate tasks. Due to the fact that we have built several connectors using LDAP to automate our user management, we have invested some time to research why our current Exchange 2003 connections wouldn't work with the new Exchange 2007 environment. When performing the same routines as we did in Exchange 2003 we ended up with Legacy Mailboxes that we had to migrate to full 2007 compliance using Powershell. Turns out that to fulfill the 2007 specs we had to populate 5 other Active Directory properties in order for Exchange 2007 to accept the mail enabling of the AD User account.

Using the code

To use the code you supply the "MailEnable" method with two parameters. One parameter is the LDAP path to the user object in Active Directory and the other parameter is the LDAP path to the Exchange Mailbox Store.

Exchange Part

To find the Paths to the mailbox stores we have made 3 methods that can retrieve the Exchange Servers, Exchange Mailbox Storage Groups and the Exchange Mailbox Stores. Because we code in VB.net and C# the code snippets will be in one or the other language. These snippets are part of a huge library so I can't supply you with all the code that is necessary to fully run.

        Protected Function Get_RootDSEProperty( _
                ByVal PropertyName As String _
                ) As String
            Dim _DirectoryEnTry As New System.DirectoryServices.DirectoryEntry
            _DirectoryEnTry.Path = Protocol + Server + "RootDSE"
            Return CType(_DirectoryEnTry.Properties(PropertyName)(0), String)
        End Function

In above Function "Protocol" is a property filled with the string value "LDAP://". Server is a property specifying a Domain Controller (eg "UM-DC.LiQuick.net/"). This Function will return the "roots" of the User/Groups/Computers/Contacts part of Active Directory (defaultNamingContext), which you can view with Active Directory User and Computers MMC, and the root in which the Configuration settings of your domain is stored (configurationNamingContext). The Configuration root is being used to retrieve the Exchange servers, storage groups and stores.

        Public Function ExchangeServer_PathsGet() As System.DirectoryServices.SearchResultCollection
            Dim _configurationNamingContext As String = Protocol + Server + Me.Get_RootDSEProperty("configurationNamingContext")
            Dim LDAPConditions() As String = New String(0) {}
            LDAPConditions(0) = "objectCategory=msExchExchangeServer"
            Return Find_DirectoryEntries(LDAPConditions, SearchScope.Subtree, _configurationNamingContext)
        End Function

The above Function returns the LDAP Paths of all the Exchange servers you have made a member of your domain. The Find_DirectoryEntries uses the System.DirectoryServices.DirectorySearcher namespace to find the objects that correspond to the LDAP Query (&(objectCategory=msExchExchangeServer)).

        Public Function ExchangeServer_RetrieveStorageGroups( _
                ByVal directoryEntryExchangeServer As DirectoryEntry _
                ) As System.DirectoryServices.SearchResultCollection
            Dim LDAPConditions() As String = New String(0) {}
            LDAPConditions(0) = "objectCategory=msExchStorageGroup"
            Return Find_DirectoryEntries(LDAPConditions, SearchScope.Subtree, directoryEntryExchangeServer)
        End Function

Specifying the above Function with a DirectoryEntry, having a LDAP path to a Exchange Server, will provide you with the storage groups that reside on that particular Exchange Server.

        Public Function ExchangeServer_RetrieveStores( _
                ByVal directoryEntryExchangeStorageGroup As DirectoryEntry _
                ) As System.DirectoryServices.SearchResultCollection
            Dim LDAPConditions() As String = New String(0) {}
            LDAPConditions(0) = "objectCategory=msExchPrivateMDB"
            Return Find_DirectoryEntries(LDAPConditions, SearchScope.Subtree, directoryEntryExchangeStorageGroup)
        End Function        

After choosing a Storage Group which you have retrieved with the Function ExchangeServer_RetrieveStorageGroups you can finally retrieve the much desired Mailbox Store Paths.

The above functions use the Find_DirectoryEntries function below. It takes a string array of conditions (for example "objectCategory=msExchPrivateMDB") and forms it into a LDAP query (eg "(&(objectCategory=msExchPrivateMDB))"). The rest is explained in the MSDN libraries.

        Public Function Find_DirectoryEntries( _
                ByVal Conditions() As String, _
                ByVal Scope As System.DirectoryServices.SearchScope, _
                ByVal FromDirectoryEntry As System.DirectoryServices.DirectoryEntry _
                ) As System.DirectoryServices.SearchResultCollection
            Dim Filter As String
            Filter = CreateFilterAND(Conditions)
            Return Find_DirectoryEntries(Filter, Scope, FromDirectoryEntry)
        End Function
        Public Function Find_DirectoryEntries( _
                ByVal Filter As String, _
                ByVal Scope As System.DirectoryServices.SearchScope, _
                ByVal FromDirectoryEnTry As System.DirectoryServices.DirectoryEntry, _
                Optional ByVal PageSize As Integer = 0 _
                ) As System.DirectoryServices.SearchResultCollection
            Dim _DirectorySearcher As New System.DirectoryServices.DirectorySearcher
            Dim _SearchResultCollection As System.DirectoryServices.SearchResultCollection
            _DirectorySearcher.SearchRoot = FromDirectoryEnTry 
            _DirectorySearcher.Filter = Filter
            _DirectorySearcher.SearchScope = Scope
            If PageSize > 0 Then
                _DirectorySearcher.PageSize = PageSize
            End If
            Try
                _SearchResultCollection = _DirectorySearcher.FindAll()
            Catch ex As Exception
                _SearchResultCollection = Nothing
            End Try
            Return _SearchResultCollection
        End Function 
        Public Function CreateFilterAND( _
                ByVal Conditions() As String, _
                Optional ByVal StringPreFilter As String = "" _
                ) As String
            Dim Filter As String = "(&"
            Filter += CreateFilter(Conditions, StringPreFilter)
            Filter += ")"
            Return Filter
        End Function
        Public Function CreateFilter( _
                ByVal Conditions() As String, _
                Optional ByVal StringPreFilter As String = "" _
                ) As String
            Dim Filter As String = ""
            Dim Condition As String
            For Each Condition In Conditions
                Filter += "(" + Condition + ") "
            Next
            Filter += StringPreFilter
            Return Filter
        End Function

User Part

I will not go into how you can retrieve the LDAP Path to a user object in Active Directory, there are numerous articles about how you can do that. The following code will actually mail enable the AD User account for an Exchange 2003 and 2007 environment. The only other thing you have to do which is not covered in this code is populating the ProxyAddresses (e-mail address of the user object. This code is taken from our WebService that provides several Active Directory manipulation methods.

    public void User_MailEnable(string path, string pathMailStore)
    {
        try
        {
            System.DirectoryServices.DirectoryEntry directoryEntryUser = 
                new System.DirectoryServices.DirectoryEntry(path);
    
            string userName = (string) directoryEntryUser.Properties["samaccountname"][0];
    
            if (directoryEntryUser.Properties.Contains("msExchMailboxGuid") == false)
            {
                if (directoryEntryUser.Properties.Contains("displayName") == false)
                {
                    directoryEntryUser.Properties["displayName"].Add(userName);
                }
                System.DirectoryServices.DirectoryEntry directoryEntryMailStore = 
                    new System.DirectoryServices.DirectoryEntry(pathMailStore);
                string homeMDB = (string) directoryEntryMailStore.Properties["distinguishedName"][0];
                string msExchHomeServerNamePath = _AD.Protocol + _AD.Server + (string) directoryEntryMailStore.Properties["msExchOwningServer"][0];
                System.DirectoryServices.DirectoryEntry directoryEntryMailServer = 
                    new System.DirectoryServices.DirectoryEntry(msExchHomeServerNamePath);
                string msExchHomeServerName = (string) directoryEntryMailServer.Properties["legacyExchangeDN"][0];
                string legacyExchangeDN = msExchHomeServerName.Substring(0,msExchHomeServerName.IndexOf("cn=")) + "cn=Recipients/cn=" + userName;
                directoryEntryUser.Properties["homemdb"].Value= homeMDB;
                directoryEntryUser.Properties["msExchHomeServerName"].Value = msExchHomeServerName;
                directoryEntryUser.Properties["mailNickName"].Value = userName;
                directoryEntryUser.Properties["legacyExchangeDN"].Value = legacyExchangeDN;
                if (directoryEntryMailServer.Properties.Contains("msExchVersion"))
                {
                   directoryEntryUser.Properties["msExchVersion"].Value = directoryEntryMailServer.Properties["msExchVersion"][0];
                   directoryEntryUser.Properties["msExchRecipientDisplayType"].Value = 1073741824; //User Mailbox
                   directoryEntryUser.Properties["msExchRecipientTypeDetails"].Value = 1; //User Mailbox
                }
                Guid guid = Guid.NewGuid();
                   directoryEntryUser.Properties["msExchMailboxGuid"].Add(guid.ToByteArray());
             }
            directoryEntryUser.CommitChanges();
        }
        catch (Exception e)
        {
        }
    }

Points of Interest

As I pointed out: the above code is not ALL you need to mail enable an AD user account but I hope I have provided you with enough information to give you a push into the right direction).

History

2008-10-09: First attempt to write the article.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

LiQuick



Location: Netherlands Netherlands

Other popular Microsoft Exchange articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 6 of 6 (Total in Forum: 6) (Refresh)FirstPrevNext
GeneralExchange 2007 properties and Javamemberjrvk2:09 11 Nov '08  
GeneralRe: Exchange 2007 properties and JavamemberLiQuick3:48 11 Nov '08  
GeneralRe: Exchange 2007 properties and Javamemberjrvk23:00 11 Nov '08  
GeneralRe: Exchange 2007 properties and JavamemberLiQuick3:16 12 Nov '08  
QuestionFind_DirectoryEntriesmemberKubisCopus0:53 15 Oct '08  
AnswerRe: Find_DirectoryEntriesmemberLiQuick4:15 15 Oct '08  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 9 Oct 2008
Editor: Smitha Vijayan
Copyright 2008 by LiQuick
Everything else Copyright © CodeProject, 1999-2009
Web18 | Advertise on the Code Project