Here is the information on setting up and using Exchange Web Services impersonation in Exchange 2007. Notice that it is a two part process, it is not just setting permissions on the target account, the service account also needs permissions on the Client Access Server itself...
Configuring Exchange Impersonation (Exchange Web Services)
http://msdn2.microsoft.com/en-us/library/bb204095.aspx
…Notice that you have to set to rights “ms-Exch-EPI-Impersonation” must be on the Client Access server for the service account which will do the impersonation. Additionally the service account will have to have the “ms-Exch-EPI-May-Impersonate” right granted to it on each mailbox it will impersonate. This right is inherited down to mailboxes if you were to set it at the store, storage group, server, or organizational level.
The second piece is using impersonation in your Exchange Web Services application…
Using Exchange Impersonation (Exchange Web Services)
http://msdn2.microsoft.com/en-us/library/bb204088.aspx
…This documentation does a good job of explaining things and provides examples of the raw XML requests however it does not provide a C# sample using the proxy classes. It is actually just a matter of adding a object to the ExchangeServiceBinding used to submit your requests. Here is a sample of adding the object to the binding in C#...
_esb.ExchangeImpersonation = new ExchangeImpersonationType();
_esb.ExchangeImpersonation.ConnectingSID = new ConnectingSIDType();
_esb.ExchangeImpersonation.ConnectingSID.PrimarySmtpAddress = mailbox;
…In this code sample “_esb” is an ExchangServiceBinding object and mailbox is the SMTP address of the mailbox I want to impersonate.
The Outlook 2003 Object Model does not have anyway to delete Search Folders, although you can create them. The only way to delete them is to use CDO 1.21 code. However, it is not supported to run CDO 1.21 or MAPI code (yes, this includes Redemption any third party APIs or components you write that use MAPI/CDO 1.21 directly) *in-process* with managed .NET code. This means that simply wrapping the CDO 1.21 code below in a COM component is not enough, the code must live in its own process. The easiest way I know of to do that is hop back over to good ‘ole VB6 and create a very simple ActiveX EXE. This is a very simple way to run all CDO code in one process while the managed OOM code runs in another process (such as Outlook.EXE) without having to do too many configuration or deployment backflips.
In fact, the code below comes directly from an ActiveX EXE created to allow the deleting of Search Folders…
'-------------------------------------------------------
' DeleteSearchFolder
' mstehle, 07.27.07
' This CDO 1.21 code is hosted in an simple ActiveX EXE
' so that it can be called from a .NET application. The
' code runs in a seperate process which allows us to
' call it from the managed process without fear of memory
' issues.
'--------------------------------------------------------
Public Sub DeleteSearchFolder(ByVal strName As String)
Dim oSession As MAPI.Session
oSession = New MAPI.Session
' Assume we are already logged in to a session and
' piggy-back the session...
oSession.Logon, , False, False
Dim oFinderFolder As MAPI.Folder
oFinderFolder = GetFinderFolder(oSession)
' Throw error if folder not found
If oFinderFolder Is Nothing Then
Err.Raise(MAPI.CdoE_NOT_FOUND, "DeleteSearchFolder", _
"Finder folder not found.")
End If
Dim oSearchFolder As MAPI.Folder
oSearchFolder = GetFolder(strName, oFinderFolder)
If oSearchFolder Is Nothing Then
"Search folder not found with name " & strName)
' If found, delete it
oSearchFolder.Delete()
End Sub
Private Function GetFolder(ByVal strName As String, _
ByVal oParentFolder As MAPI.Folder) As Folder
Dim oFolder As MAPI.Folder
For Each oFolder In oParentFolder.Folders
If oFolder.Name = strName Then
GetFolder = oFolder
Exit For
Next
End Function
Private Function GetFinderFolder(ByVal oSession As MAPI.Session) _
As MAPI.Folder
If oSession Is Nothing Then
Err.Raise(MAPI.CdoE_LOGON_FAILED, _
"DeleteSearchFolder", "No session established.")
' Get root mailbox store folder
Dim oInbox As MAPI.Folder
oInbox = oSession.Inbox
Dim oStore As MAPI.InfoStore
oStore = oSession.GetInfoStore(oInbox.StoreID)
Dim oRootFolder As MAPI.Folder
oRootFolder = oSession.GetFolder("", oStore.ID)
For Each oFolder In oRootFolder.Folders
Debug.Print(oFolder.Name)
' In a PST the folder is called "Search Root", in an online
' profile it is called "Finder"
If oFolder.Name = "Finder" Or oFolder.Name = "Search Root" Then
GetFinderFolder = oFolder
...Here are the details of a new KB article I just submitted. I will update this post when it is published...
Symptoms
When using CDOEXM to manage Exchange 2003 and Powershell cmdlets to manage Exchange 2007 in the same application you may come across the following error:
"Retrieving the COM class factory for component with CLSID {08D1AA55-704E-4397-AB29-55D2A3972BCB} failed due to the following error: 8007007f.”
This would typically be seen when calling Invoke on a System.Management.Automation Pipeline when automating a cmdlet such as Move-Mailbox.
…To indentify this issue use a couple simple WinDbg commands to identify if CDOEXM is loaded in the process and see where CDOEXM, EXCHMEM, and other dependencies are loading from as well as their version numbers. Here are some of the commands I used and what the output was in the traces I saw. Simply snap a hang dump or attach WinDbg to your application’s process and run these commands…
lmf – This command lists all the loaded modules and the file path they are loaded from. Look for CDOEXM and EXCHMEM to see if they have been loaded yet and if so where they are loading from. For Exchange 2000/2003 the path to Exchange components should be “C:\Program Files\exchsvr\bin” for Exchange 2007 it will be “C:\Program Files\Microsoft\Exchange Server\bin”.
lmvm [module name] – This will gives verbose output about a particular loaded module. Use this to get the version number and path for a particular module like EXCHMEM. Exchange 2000 binaries’ version numbers are 6.0.*, Exchange 2003 binaries are 6.5.*, and Exchange 2007 binaries are 8.0.*. Be sure that Exchange system modules like ESE, EXCHMEM, PTTRACE, ADDRESS, and GLBLNAME match the version of Exchange you are testing…
Cause
This is caused when Exchange 2003 System Manager and Exchange 2007 Management Console are installed on the same application server for an application that is intended to manage Exchange 2003 and Exchange 2007. Calls to Exchange 2003’s management API, CDOEXM, load the Exchange 2003 version of libraries such as EXCHMEM.dll into the application process. When the Exchange 2007 cmdlets are used they end up using the already loaded Exchange 2003 library. This causes the Exchange 2007 cmdlet to fail.
Resolution
To avoid this conflict Exchange 2003 CDOEXM should not be loaded in the same process where Exchange 2007 cmdlets will loaded or automated.
More Information
Exchange 2007 cmdlets should not be used to create or edit objects such as mailboxes or storage groups on an Exchange 2003 server. CDOEXM and Exchange 2003 System Manager should be used to manage these servers. For more information on managing Exchange 2003 in a coexistence environment with Exchange 2007 see the following articles on TechNet:
Managing Exchange 2003 Settings in a Coexistence Environment
http://technet.microsoft.com/en-us/library/aa995972.aspx
Planning for Coexistence
http://technet.microsoft.com/en-us/library/aa998186.aspx
For more information about automating Exchange 2007 Powershell cmdlets see the following article on MSDN:
Using Exchange Management Shell Commands With Managed Code
http://msdn2.microsoft.com/en-us/library/bb332449.aspx