How to loop through mailboxes on Exchange by using the GetMailboxTable method (200160)
The information in this article applies to:
- Microsoft Extended Messaging Application Programming Interface (MAPI)
This article was previously published under Q200160 SUMMARY
When you create mailbox maintenance utility programs, it may be useful to loop through all of the mailboxes on a server and gather information. The code below lists a count of the messages within the Deleted Items folder for each mailbox. The logic used in this code can be used to determine the number of messages in any folder of a mailbox.MORE INFORMATION
To determine the number of messages in a folder, follow these steps: - Create a MAPI Session pointer and open the private information store of a mailbox that is associated with the service account or some other account with administrative privileges.
- Use the GetMailboxTable() method to retrieve the table of mailboxes.
- Use the HrMailboxLogon() function to log on to each of the mailboxes.
- Specify a folder path included in a call to the HrMAPIOpenFolderEx() function to create a folder pointer.
The following libraries should be included on the Link tab of the Project settings dialog box when the code below is compiled and linked: - Advapi32.lib
- Exchsdk.lib
- Edkdebug.lib
//This code requires the following libraries: advapi32.lib exchsdk.lib edkdebug.lib
#include <stdio.h>
#include <edk.h>
HRESULT LoopMailboxes(LPMAPISESSION lpMAPISession,
LPSTR pszExchangeServerName);
void main()
{
HRESULT hRes = S_OK;
char pszExchangeServerName[500];
LPMAPISESSION lpMAPISession = NULL;
LPMDB lpMDB = NULL;
hRes = MAPIInitialize(NULL);
if(FAILED(hRes))
{
printf("Failed to initialise MAPI\n");
return;
}
// Get the Exchange Server name from the user
//
printf("Please enter the name of your Exchange Server: ");
gets(pszExchangeServerName);
// TODO: Logon using a profile for the service account or an Exchange admin
hRes = MAPILogonEx(
0,
"",
NULL,
MAPI_LOGON_UI | MAPI_NEW_SESSION | MAPI_EXPLICIT_PROFILE ,
&lpMAPISession);
if (FAILED(hRes))
{
printf("MAPI Logon failed: %d\n",hRes);
return;
}
printf("MAPI session created.\n");
hRes = LoopMailboxes(lpMAPISession, pszExchangeServerName);
if(FAILED(hRes))
printf("LoopMailboxes failed: %x\n",hRes);
else
printf("Finished looping through mailboxes.\n");
printf("Hit a key to exit.\n");
while (!_kbhit()) Sleep(50);
_getch();
if(lpMAPISession) lpMAPISession->Release();
}
HRESULT LoopMailboxes(LPMAPISESSION lpMAPISession, LPSTR pszServerName)
{
HRESULT hRes = S_OK;
LPMAPITABLE lpMailBoxTable = NULL;
LPSRowSet lpRows = NULL;
LPENTRYID lpMsgStoreID = NULL;
ULONG cbMsgStoreID = 0;
LPMDB lpMDB = NULL;
LPMDB lpUserMDB = NULL;
LPMAPIFOLDER lpFolder = NULL;
LPSPropValue lpProp = NULL;
LPEXCHANGEMANAGESTORE lpIManageStore = NULL;
char pszServerDN[500];
if (FAILED(hRes = HrOpenExchangePrivateStore(lpMAPISession,&lpMDB)))
{
printf("Message Store Not Available.\n");
return MAPI_E_NOT_FOUND;
}
if (FAILED(hRes = lpMDB->QueryInterface(IID_IExchangeManageStore,
(void **) &lpIManageStore)))
{
printf("QueryInterace Failed.\n");
return MAPI_E_NOT_FOUND;
}
// Create server DN
sprintf(pszServerDN,"/o=microsoft/cn=servers/cn=%s",
pszServerName);
if (FAILED(hRes = lpIManageStore->GetMailboxTable(pszServerDN,
&lpMailBoxTable,0)))
{
printf("Mailbox Table Not Available.\n");
return MAPI_E_NOT_FOUND;
}
// Get a list of Mailboxes taking up resources
hRes = HrQueryAllRows(lpMailBoxTable, NULL, NULL, NULL, 0, &lpRows);
if(SUCCEEDED(hRes))
{
if (lpRows->cRows > 0)
{
for (UINT i=0; i < lpRows->cRows; i++)
{
LPSPropValue lpspv = PpropFindProp( lpRows->aRow[i].lpProps,
lpRows->aRow[i].cValues,
PR_EMAIL_ADDRESS );
//Create Information Store DN
sprintf(pszServerDN,
"/o=microsoft/cn=servers/cn=%s%s",
pszServerName,
"/cn=Microsoft Private MDB");
hRes = HrMailboxLogon(
lpMAPISession,
lpMDB,
pszServerDN,
lpspv->Value.lpszA,
&lpUserMDB);
if(FAILED(hRes))
{
printf(
"%d Mailbox (%s) Not Available: %d\n",
i,
lpspv->Value.lpszA,hRes);
hRes = S_OK;
//Since we failed to open the mailbox, skip to the next one.
continue;
}
else
{
printf("%d Opened %s \n",i,lpspv->Value.lpszA);
}
// ********** Place Mailbox Processing Here **********
hRes = HrGetOneProp(
lpUserMDB,
PR_MESSAGE_SIZE,
&lpProp);
if (FAILED(hRes))
{
printf("HrGetOneProp error %x\n",hRes);
}
else
{
printf("Total Message Size = %d\n",lpProp->Value);
}
if (lpProp) MAPIFreeBuffer(lpProp);
lpProp = NULL;
hRes = HrGetOneProp(
lpUserMDB,
PR_CONTENT_COUNT,
&lpProp);
if (FAILED(hRes))
{
printf("HrGetOneProp error %x\n",hRes);
}
else
{
printf("Total Message Count = %d\n",lpProp->Value);
}
if (lpProp) MAPIFreeBuffer(lpProp);
lpProp = NULL;
hRes = HrMAPIOpenFolderEx(
lpUserMDB,
'\\',
"Top of Information Store\\Deleted Items",
&lpFolder);
if (FAILED(hRes))
{
printf("HrMAPIOpenFolderEx error %x\n",hRes);
//Q194435 PRB: Error "800b0001" From HrMAPIOpenFolderEx()
if (hRes == 0x800b0001)
{
printf("Mailbox does not contain desired path.\n");
//Don't return an error
hRes = S_OK;
}
}
else
{
hRes = HrGetOneProp(
lpFolder,
PR_CONTENT_COUNT,
&lpProp);
if (FAILED(hRes))
{
printf("HrGetOneProp error %x\n",hRes);
}
else
{
printf("Delete Message Count = %d\n",lpProp->Value);
}
if (lpProp) MAPIFreeBuffer(lpProp);
lpProp = NULL;
if (lpFolder) lpFolder->Release();
}
if (lpUserMDB) lpUserMDB->Release();
}
}
}
if(lpRows) FreeProws(lpRows);
if(lpMailBoxTable) lpMailBoxTable->Release();
return hRes;
} REFERENCES You can export folder size information to a text file by using Exchange System Manager. If you want this kind of information in a report to use for management purposes, you can use the text file that is generated from Exchange System Manager without programming.
For more information, click the following article numbers to view the articles in the Microsoft Knowledge Base:
194435
Error "800b0001" from HrMAPIOpenFolderEx()
260141 OpenMsgStore() and HrMailboxLogon() may fail when you open more than 255 mailboxes
Modification Type: | Minor | Last Reviewed: | 1/13/2006 |
---|
Keywords: | kbhowto KB200160 kbAudDeveloper |
---|
|