|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionThis 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. BackgroundExchange 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 codeTo 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 InterestAs 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). History2008-10-09: First attempt to write the article.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||