Thursday, October 20, 2005

Mail Enabling a Public folder via MAPI and WebDAV

I’ve had a few questions from people recently asking about the different methods you can mail enable a folder when your running Exchange 2003 in Native Mode. The standard method for mail enabling objects programmatically is to use CDOEXM and the IRecipient Interface . To mail enable a public folder you need to combine this with a little CDOEX like this

FolderURL = "http://server/public/folder/"
set objFolder1 = createobject("CDO.Folder")
objFolder1.DataSource.Open FolderURL, , 3,-1
Set objRecip1 =
objFolder1.Getinterface("IMailRecipient")
objRecip1.MailEnable
objFolder1.DataSource.Save

Now because this uses CDOEX which runs over Exoledb it will only work locally on an Exchange server. To do this remotely you can use the Exchange_PublicFolder WMI class I posted a sample of doing the here previously.

I was curious at the way Exchange System Manger went about mail enabling folders when you where using this on a remote machine as this obviously wasn’t using CDOEX. I did some network captures on a remote machine and the only conversation that the remote machine was having with any server when mailenabling a folder was that it was doing a proppatch on two properties on the public folder via webdav. There was no discernable LDAP traffic at all. I decided to give that go in script myself on a non enabled public folder to see if this would mail enable it and it seemed to work just fine and the RUS seemed to be happy enough to populate the email address’s and also deal with the directory object in Active Directory. I tried the same thing with a CDO script that created a new public folder in the root and mail enabled it via setting these two mapi properties and it seemed to work equally as well.

Now wether this method would be a supported way to mail enable public folders I don’t know it does seem to be how ESM is doing it. There’s also a little more discussion in a recent post on the Exchange Team blog and also in the following KB .

The two properties in question are

PR_PUBLISH_IN_ADDRESS_BOOK = &H3FE6000B
PR_PF_PROXY_REQUIRED = &H671F000B

I’ve only tested this on Exchange 2003 in Native mode as I said this is probably unsupported but the WebDAV to do this would look like

server = "server"
folderpath = "folder"
sDestinationURL = "http://" & server & "/public/" & folderpath & "/"
xmlstr = "<?xml version=""1.0"" ?><a:propertyupdate xmlns:a=""DAV:"" xmlns:b=""urn:schemas-microsoft-com:datatypes""
" _
& "xmlns:c=""xml:"" xmlns:d=""http://schemas.microsoft.com/mapi/proptag/"" " _
& "xmlns:e=""http://schemas.microsoft.com/exchange/events/"" xmlns:f=""http://schemas.microsoft.com/exchange/"">
" _
& "<a:set><a:prop>" _
& "<d:0x3FE6000B b:dt=""boolean"">1</d:0x3FE6000B>" _
& "<d:0x671F000B b:dt=""boolean"">1</d:0x671F000B>" _
& "</a:prop></a:set></a:propertyupdate>"
Set XMLreq = CreateObject("Microsoft.xmlhttp")
XMLreq.open "PROPPATCH", sDestinationURL, False
XMLreq.setRequestHeader "Content-Type", "text/xml;"
XMLreq.setRequestHeader "Translate", "f"
XMLreq.setRequestHeader "Content-Length:", Len(xmlstr)
XMLreq.send(xmlstr)
If (XMLreq.Status >= 200 And XMLreq.Status < 300) Then
Wscript.echo "Success! " & "Results = " & XMLreq.Status & ": " &
XMLreq.statusText
ElseIf XMLreq.Status = 401 then
Wscript.echo "You don't have permission to do the job! Please check your
permissions on this item."
Else
Wscript.echo "Request Failed. Results = " & XMLreq.Status & ": " &
XMLreq.statusText
End If


A CDO example would look like.

MailServer = "servername"
Mailbox = "mailbox"
PR_PUBLISH_IN_ADDRESS_BOOK = &H3FE6000B
PR_PF_PROXY_REQUIRED = &H671F000B
set objSession = CreateObject("MAPI.Session")
strProfile = MailServer & vbLf & Mailbox
objSession.Logon "",,, False,, True, strProfile
Set objInfoStores = objSession.InfoStores
set objInfoStore = objSession.GetInfoStore
Set objpubstore = objSession.InfoStores("Public Folders")
Set objTopFolder = objSession.GetFolder(objpubstore.Fields(&H66310102),objpubstore.ID)
Set objFolder = objTopFolder.Folders.Add("YellowCab1")
Set objFields = objFolder.Fields
objfields.add PR_PUBLISH_IN_ADDRESS_BOOK, true
objfields.add PR_PF_PROXY_REQUIRED, true
objFolder.Update

8 comments:

Anonymous said...

Thanks, you really helped me!

Anonymous said...

I am trying to implement this but getting following error when it executes "objFields = objFolder.Fields" line :

An unhandled exception of type 'System.MissingMemberException' occurred in microsoft.visualbasic.dll

Additional information: Public member 'Fields' on type 'MAPIFolder' not found.

Any help is highly appreciated
thanks

Glen said...

If you are trying to use CDO 1.2 in .NET the this library is not supported and you'll get lots of these types of errors. To do this in .NET use the WebDAV method or look at using a library like Redemption or the Outlook Object Model to use MAPI in .NET.

Anonymous said...

Can you please suggest any samples?

Glen said...

There a WebDAV sample in this post all you need is the XML thats used in the Proppatch. There is .net Proppatch sample in the SDK http://msdn2.microsoft.com/en-us/library/aa563069.aspx

Anonymous said...

Have you perhaps found a similar workaround to force RUS to mail-disable a folder? Unfortunately I'm getting 401's when trying to remove the pr_pf_proxy_required prop, so I'm not sure that just clearing these two would have the desired effect.

Glen said...

cont clear them just set them to False. That seems to work okay for me anyway after the RUS updates.

Paresh Masani said...

Glen, I have been trying to write this code in C#. My code is given below. Could you please tell me why it does not work? It does not set mail enabled property and neither set smtp address.

I have posted my code at

http://social.technet.microsoft.com/Forums/en-US/exchangesvrdevelopment/thread/6ea8b5c9-3814-4b0a-905a-4738bdbe70d2
because here it is not allowing me to do so. Could you please help me on this.

Thanks,
Megha