Introduction
I spent quite a while finding and converting code-snippets to make an e-mail enabled contact. It seemed to me like it should be a relatively easy task to carry out, but I was missing the intricacies of CDO vs. ADSI users. There is a tech-note on Microsoft which is quite clear, but you have to have a bit of CDO experience to decode what it means. The tech-note is available here.
The key pieces of information are:
- You cannot use ADSI or an ADSI object to create a Mail Enabled anything.
- You must use CDO and CDOEXM and ADODB.
- You can only develop this on an Exchange server.
- You can only deploy it on an Exchange server.
The tech-note states that you can develop it on a Win200x machine with the Admin tools installed. This does not work. The reason is that the ADODB lib from Admin tools are not compatible with ADODB on .NET. You get a nasty error when trying to add a reference to CDOEXM with Admin Tools only. On a real Exchange Server, this does not seem to be a problem.
Eventually I downloaded the Exchange 2003 SDK and found the VB code for making a Mail Enabled Person. I then converted that into C#. That code can be found at MSDN.
A fairly serious fault I found with the original code one day later was that you must make sure that there will be no duplicate addresses in your domain. People were getting NDR reports, because of duplicate e-mail addresses.
LDAP could be used to repopulate so many things, and there are many attributes that contain e-mail addresses, that I was not sure how to test for "exchange enabled". Searching Proxy Addresses seemed to be a good way, because I read on tech boards that Proxy Addresses is what Exchange looked up to send email addresses. I found a relative tech-note that seemed to support this idea.
The way I chose to do it was to search all objects (this really takes a lot of processor and time). Because you can have mail enabled folders, contacts, persons, etc... I thought this the best way, as you might have "mail enabled" toasters ending up in Active Directory sometime in the future: sendto:popup@mytoaster.com, you never know.
As far as function naming goes, I always like to ask questions in the positive so the code reads easier (in my opinion). I think it is more understandable to write:
if (! EmailAddressExistInLDAP( "bsmith@mycompany", strRootDSE)
than to write:
if ( NotInAddressBook( ... ))
When you want to write the opposite, the logic can be difficult to follow.
if ( ! NotInAddressBook( ... ))
However in this case it does mean the function returns "true
" to not add the contact, and that might be confusing reading the EmailAddressExistInLDAP
through the first time.
This code takes about 5 minutes to run with the 600 contacts I am transferring so the *emailaddress* is an "expensive" way to go about it. If anyone knows something faster and better, I certainly would be interested.
Obviously as with all other freeware code in the world, this is as is and I recommend that you test it thoroughly in a development environment before releasing it on the real world.
You will also need to have created an ADSI contact, before this can MailEnable that contact. There are lots of code articles around about making a mail enabled contact.
Here is the code snippet:
using CDOEXM;
private bool MailEnablePerson(string strLDAPcn,
string strMailAddress, string strRootDSE)
{
CDO.Person cdoPerson = new CDO.PersonClass();
CDOEXM.IMailRecipient cdoRecipient;
bool bRetVal = false;
cdoPerson.DataSource.Open(strLDAPcn,null,
ADODB.ConnectModeEnum.adModeReadWrite,
ADODB.RecordCreateOptionsEnum.adFailIfNotExists,
ADODB.RecordOpenOptionsEnum.adOpenSource,"","");
cdoRecipient = (IMailRecipient) cdoPerson;
if (cdoRecipient.SMTPEmail == "")
{
if (! EmailAddressExistInLDAP(strMailAddress,strRootDSE) )
{
cdoRecipient.MailEnable(strMailAddress);
cdoPerson.DataSource.Save() ;
bRetVal = true;
}
}
return bRetVal ;
}
private bool EmailAddressExistInLDAP(string strMailAddress,
string strRootDSE)
{
bool bRetVal = true;
System.DirectoryServices.DirectorySearcher objSearch
= new DirectorySearcher(strRootDSE);
System.DirectoryServices.SearchResult objResult;
objSearch.Filter = "(& ( proxyAddresses=*"+strMailAddress+"*))";
objResult = objSearch.FindOne();
if (objResult == null)
bRetVal = false;
return bRetVal;
}
Links
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.