如何以编程方式获得 Exchange 中邮箱的大小

来源: 作者: 2007-12-03 出处:pcdog.com

exchange server  office  qq  xml  
本页
如何以编程方式获得 Exchange 中邮箱的大小概要
如何以编程方式获得 Exchange 中邮箱的大小更多信息
如何以编程方式获得 Exchange 中邮箱的大小扩展 MAPI 方法
如何以编程方式获得 Exchange 中邮箱的大小CDO 1.21 方法
如何以编程方式获得 Exchange 中邮箱的大小ActiveX 数据对象 (ADO) 方法
如何以编程方式获得 Exchange 中邮箱的大小WebDAV 方法
如何以编程方式获得 Exchange 中邮箱的大小这篇文章中的信息适用于:

概要

本文描述如何使用 Microsoft Visual C、Microsoft Visual C++、Microsoft Visual Basic 和 Microsoft Visual Basic Scripting Edition (VBScript) 在运行 Microsoft Exchange 的服务器上以编程方式检索有关邮箱大小的信息。

更多信息

扩展 MAPI 方法

可用的编程语言:Visual C 和 Visual C++
Exchange Server 版本:Exchange Server 5.5、Exchange 2000 和 Exchange 2003

扩展 MAPI 提供了 IExchangeManageStore 接口以从 Exchange 信息存储区获得管理信息。此接口提供了 GetMailboxTable 函数,该函数返回包含有关特定服务器上邮箱信息的 IMAPITable 接口。请注意此函数要求具有对运行 Exchange Server 的服务器的管理权限。

此表包含的列提供了有关每个邮箱大小的信息。PR_MESSAGE_SIZE 属性包含邮箱的大小(以字节为单位)。

有关其他信息,请访问下面的 Microsoft Developer Network (MSDN) 网站:
IExchangeManageStore::GetMailboxTable
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/exchserv/html/intrface_24it.asp (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/exchserv/html/intrface_24it.asp)
有关其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
200160 (http://support.microsoft.com/kb/200160/) 如何使用 GetMailboxTable 循环完 Exchange 上的邮箱

CDO 1.21 方法

可用的编程语言:VBScript、Visual Basic、Visual C 和 Visual C++
Exchange Server 版本:Exchange Server 5.5、Exchange 2000 和 Exchange 2003

可以使用协作数据对象 (CDO) 1.21 通过 CDO InfoStore 对象,检查用户邮箱存储上的相同属性。在此方法中,应用程序必须先登录到邮箱,然后才可以检查此属性。这意味着应用程序必须能够访问服务器上的所有邮箱。此方法还要求生成服务器上邮箱的列表,并在代码中循环完这些邮箱。

下面的示例是一个简单的 VBScript 代码示例,可以检查邮箱上的此属性。要使用此示例,请将下面的代码粘贴到一个新的文本文件,然后将此文件命名为 Mailboxsize.vbs:
'This script logs on to a server that is running Exchange Server and'displays the current number of bytes that are used in the user's'mailbox and the number of messages.' USAGE: cscript MailboxSize.vbs SERVERNAME MAILBOXNAME' This requires that CDO 1.21 is installed on the computer.' This script is provided AS IS. It is intended as a SAMPLE only.' Microsoft offers no warranty or support for this script.' Use at your own risk.' Get command line arguments.Dim obArgsDim cArgsSet obArgs = WScript.ArgumentscArgs = obArgs.CountMainSub Main()   Dim oSession   Dim oInfoStores   Dim oInfoStore   Dim StorageUsed   Dim NumMessages   Dim strProfileInfo   Dim sMsg   On Error Resume Next   If cArgs <> 2 Then      WScript.Echo "Usage: cscript MailboxSize.vbs SERVERNAME MAILBOXNAME"      Exit Sub   End If   'Create Session object.   Set oSession = CreateObject("MAPI.Session")   if Err.Number <> 0 Then      sMsg = "Error creating MAPI.Session."      sMsg = sMsg %26amp; "Make sure CDO 1.21 is installed. "      sMsg = sMsg %26amp; Err.Number %26amp; " " %26amp; Err.Description      WScript.Echo sMsg      Exit Sub   End If   strProfileInfo = obArgs.Item(0) %26amp; vbLf %26amp; obArgs.Item(1)   'Log on.   oSession.Logon , , False, True, , True, strProfileInfo   if Err.Number <> 0 Then      sMsg = "Error logging on: "      sMsg = sMsg %26amp; Err.Number %26amp; " " %26amp; Err.Description      WScript.Echo sMsg      WScript.Echo "Server: " %26amp; obArgs.Item(0)      WScript.Echo "Mailbox: " %26amp; obArgs.Item(1)      Set oSession = Nothing      Exit Sub   End If   'Grab the information stores.   Set oInfoStores = oSession.InfoStores   if Err.Number <> 0 Then      sMsg = "Error retrieving InfoStores Collection: "      sMsg = sMsg %26amp; Err.Number %26amp; " " %26amp; Err.Description      WScript.Echo sMsg      WScript.Echo "Server: " %26amp; obArgs.Item(0)      WScript.Echo "Mailbox: " %26amp; obArgs.Item(1)      Set oInfoStores = Nothing      Set oSession = Nothing      Exit Sub   End If   'Loop through information stores to find the user's mailbox.   For Each oInfoStore In oInfoStores      If InStr(1, oInfoStore.Name, "Mailbox - ", 1) <> 0 Then         '%26amp;HE080003 = PR_MESSAGE_SIZE         StorageUsed = oInfoStore.Fields(%26amp;HE080003)         if Err.Number <> 0 Then            sMsg = "Error retrieving PR_MESSAGE_SIZE: "            sMsg = sMsg %26amp; Err.Number %26amp; " " %26amp; Err.Description            WScript.Echo sMsg            WScript.Echo "Server: " %26amp; obArgs.Item(0)            WScript.Echo "Mailbox: " %26amp; obArgs.Item(1)            Set oInfoStore = Nothing            Set oInfoStores = Nothing            Set oSession = Nothing            Exit Sub         End If         '%26amp;H33020003 = PR_CONTENT_COUNT         NumMessages = oInfoStore.Fields(%26amp;H36020003)         if Err.Number <> 0 Then            sMsg = "Error Retrieving PR_CONTENT_COUNT: "            sMsg = sMsg %26amp; Err.Number %26amp; " " %26amp; Err.Description            WScript.Echo sMsg            WScript.Echo "Server: " %26amp; obArgs.Item(0)            WScript.Echo "Mailbox: " %26amp; obArgs.Item(1)            Set oInfoStore = Nothing            Set oInfoStores = Nothing            Set oSession = Nothing            Exit Sub         End If         sMsg = "Storage Used in " %26amp; oInfoStore.Name         sMsg = sMsg %26amp; " (bytes): " %26amp; StorageUsed         WScript.Echo sMsg         WScript.Echo "Number of Messages: " %26amp; NumMessages      End If   Next   ' Log off.   oSession.Logoff   ' Clean up memory.   Set oInfoStore = Nothing   Set oInfoStores = Nothing   Set oSession = NothingEnd Sub				

ActiveX 数据对象 (ADO) 方法

可用的编程语言:VBScript、Visual Basic、Visual C 和 Visual C++
Exchange Server 版本:Exchange 2000 和 Exchange 2003

在 Exchange 2000 和 Exchange 2003 中,您可以通过 ActiveX 数据对象 (ADO) 访问 Exchange 信息存储区。存储在邮箱上的属性均不包含总计大小。但是,用户邮箱中的每个文件夹各自的大小存储在名为 http://schemas.microsoft.com/mapi/proptag/x0e080003 的字段中。这与 MAPI 属性 (PR_MESSAGE_SIZE) 对应。

通过将用户邮箱中所有文件夹的大小相加,可以计算出邮箱的总计大小。为此,请使用 SHALLOW 遍历以递归方式遍历邮箱中的文件夹。虽然可以使用 DEEP 遍历,但由于 DEEP 遍历会引起问题,因此,避免使用此方法。 有关 DEEP 遍历问题的其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
216076 (http://support.microsoft.com/kb/216076/) 在 Exchange 中访问信息存储文件夹的速度可能会变慢
使用此方法时,必须在运行 Exchange 2000 的服务器上运行代码。Exchange 的 OLE DB 提供程序 (EXOLEDB) 无法远程访问邮箱。

下面的示例是一个简单的 VBScript 代码示例,可以检索邮箱的大小。要使用此示例,请将下面的代码粘贴到一个新的文本文件,然后将此文件命名为 Mailboxsize.vbs:
'This script logs on to a server that is running Exchange 2000 or 2003 and'displays the current number of bytes that are used in the user's'mailbox.' USAGE: cscript MailboxSize.vbs DOMAINNAME MAILBOXNAME' You must run this code on the computer that is running Exchange 2000 or 2003.' This script is provided AS IS. It is intended as a SAMPLE only.' Microsoft offers no warranty or support for this script.' Use at your own risk.' Get command line argumentsDim obArgsDim cArgsDim iSizeSet obArgs = WScript.ArgumentscArgs = obArgs.CountMainSub Main()   Dim sConnString   On Error Resume Next   If cArgs <> 2 Then      WScript.Echo "Usage: cscript MailboxSize.vbs DOMAINNAME MAILBOXNAME"      Exit Sub   End If   ' Set up connection string to mailbox.   sConnString = "file://./backofficestorage/" %26amp; obArgs.Item(0)   sConnString = sConnString %26amp; "/mbx/" %26amp; obArgs.Item(1) %26amp; "/NON_IPM_SUBTREE"   WScript.Echo sConnString   iSize = 0   RecurseFolder(sConnString)   WScript.Echo "Mailbox Size: " %26amp; iSizeEnd SubPublic Sub RecurseFolder(sConnString)   Dim oConn   Dim oRecSet   Dim sSQL   ' Set up SQL SELECT statement.   sSQL = "SELECT ""http://schemas.microsoft.com/mapi/proptag/x0e080003"", "   sSQL = sSQL %26amp; """DAV:href"", "   sSQL = sSQL %26amp; """DAV:hassubs"" "   sSQL = sSQL %26amp; "FROM SCOPE ('SHALLOW TRAVERSAL OF """ %26amp; sConnString   sSQL = sSQL %26amp; """') WHERE ""DAV:isfolder"" = true"   WScript.Echo sSQL   ' Create Connection object.   Set oConn = CreateObject("ADODB.Connection")   if Err.Number <> 0 then      WScript.Echo "Error creating ADO Connection object: " %26amp; Err.Number %26amp; " " %26amp; Err.Description   end if   ' Create RecordSet object.   Set oRecSet = CreateObject("ADODB.Recordset")   if Err.Number <> 0 then      WScript.Echo "Error creating ADO RecordSet object: " %26amp; Err.Number %26amp; " " %26amp; Err.Description      Set oConn = Nothing      Exit Sub   end if   ' Set provider to EXOLEDB.   oConn.Provider = "Exoledb.DataSource"   ' Open connection to folder.   oConn.Open sConnString   if Err.Number <> 0 then      WScript.Echo "Error opening connection: " %26amp; Err.Number %26amp; " " %26amp; Err.Description      Set oRecSet = Nothing      Set oConn = Nothing      Exit Sub   end if   ' Open Recordset of all subfolders in folder.   oRecSet.CursorLocation = 3   oRecSet.Open sSQL, oConn.ConnectionString   if Err.Number <> 0 then      WScript.Echo "Error opening recordset: " %26amp; Err.Number %26amp; " " %26amp; Err.Description      oRecSet.Close      oConn.Close      Set oRecSet = Nothing      Set oConn = Nothing      Exit Sub   end if   if oRecSet.RecordCount = 0 then      oRecSet.Close      oConn.Close      Set oRecSet = Nothing      Set oConn = Nothing      Exit Sub   end if   ' Move to first record.   oRecSet.MoveFirst   if Err.Number <> 0 then      WScript.Echo "Error moving to first record: " %26amp; Err.Number %26amp; " " %26amp; Err.Description      oRecSet.Close      oConn.Close      Set oRecSet = Nothing      Set oConn = Nothing      Exit Sub   end if   ' Loop through all of the records, and then add the size of the   ' subfolders to obtain the total size.   While oRecSet.EOF <> True      ' Increment size.      iSize = iSize + oRecSet.Fields.Item("http://schemas.microsoft.com/mapi/proptag/x0e080003")      ' If the folder has subfolders, recursively call RecurseFolder to process them.      If oRecSet.Fields.Item("DAV:hassubs") = True then         RecurseFolder oRecSet.Fields.Item("DAV:href")      End If      ' Move to next record.      oRecSet.MoveNext      if Err.Number <> 0 then         WScript.Echo "Error moving to next record: " %26amp; Err.Number %26amp; " " %26amp; Err.Description         Set oRecSet = Nothing         Set oConn = Nothing         Exit Sub      end if   wend   ' Close Recordset and Connection.   oRecSet.Close   if Err.Number <> 0 then      WScript.Echo "Error closing recordset: " %26amp; Err.Number %26amp; " " %26amp; Err.Description      Set oRecSet = Nothing      Set oConn = Nothing      Exit Sub   end if   oConn.Close   if Err.Number <> 0 then      WScript.Echo "Error closing connection: " %26amp; Err.Number %26amp; " " %26amp; Err.Description      Set oRecSet = Nothing      Set oConn = Nothing      Exit Sub   end if   ' Clean up memory.   Set oRecSet = Nothing   Set oConn = NothingEnd Sub				
有关此主题和检索邮箱大小的 Visual C++ 示例的其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
291368 (http://support.microsoft.com/kb/291368/) 如何在 C++ 中使用 ADO 确定 Exchange 2000 Server 邮箱的大小

WebDAV 方法

语言:VBScript、Visual Basic 和 Visual C
Exchange Server 版本:Exchange 2000 和 Exchange 2003

也可以使用 WebDAV 方法(类似于 ADO 方法)。属性和算法是相同的,因为可以从邮箱的所有子文件夹添加 http://schemas.microsoft.com/mapi/proptag/x0e080003 的值。使用 WebDAV 代替 ADO 的一个好处是:代码无须在运行 Exchange 2000 或 Exchange 2003 的计算机上运行。

要使用此示例,请将下面的代码粘贴到一个新的文本文件,然后将此文件命名为 Mailboxsize.vbs:
'This script logs on to a server that is running Exchange Server and'displays the current number of bytes that are used in the user's'mailbox.' USAGE: cscript MailboxSize.vbs SERVERNAME MAILBOXNAME USERNAME PASSWORD' SERVERNAME: Name of your Exchange Server' MAILBOXNAME: Your alias (Note: depending on your environment, you may need to use the portion of your' SMTP address left of the '@' symbol instead of your alias.' USERNAME: Your domainname\username '' PASSWORD: Your domain password' This script is provided AS IS. It is intended as a SAMPLE only.' Microsoft offers no warranty or support for this script.' Use at your own risk.' Get command line arguments.Dim obArgsDim cArgsDim iSumSet obArgs = WScript.ArgumentscArgs = obArgs.CountMainSub Main()   Dim sUrl   Dim sMsg   On Error Resume Next   iSum = 0   ' Check argument count.   If cArgs <> 4 Then      sMsg = "Usage: cscript MailboxSize.vbs "      sMsg = sMsg %26amp; "SERVERNAME MAILBOXNAME USERNAME PASSWORD"      WScript.Echo sMsg      Exit Sub   End If   sUrl = "http://" %26amp; obArgs.Item(0) %26amp; "/exchange/" %26amp; obArgs.Item(1) %26amp; "/NON_IPM_SUBTREE"   wscript.echo sUrl   RecurseFolder(sUrl)   WScript.Echo "Mailbox Size: " %26amp; iSumEnd SubPublic Sub RecurseFolder(sUrl)   Dim oXMLHttp   Dim oXMLDoc   Dim oXMLSizeNodes   Dim oXMLHREFNodes   Dim oXMLHasSubsNodes   Dim sQuery   Set oXMLHttp = CreateObject("Microsoft.xmlhttp")   If Err.Number <> 0 Then      WScript.Echo "Error Creating XML object"      WScript.Echo Err.Number %26amp; ": " %26amp; Err.Description      Set oXMLHttp = Nothing   End If   ' Open DAV connection.   oXMLHttp.open "SEARCH", sUrl, False, obArgs.Item(2), obArgs.Item(3)   If Err.Number <> 0 Then      WScript.Echo "Error opening DAV connection"      WScript.Echo Err.Number %26amp; ": " %26amp; Err.Description      Set oXMLHttp = Nothing   End If   ' Set up query.   sQuery = ""   sQuery = sQuery %26amp; ""   sQuery = sQuery %26amp; "SELECT ""http://schemas.microsoft.com/"   sQuery = sQuery %26amp; "mapi/proptag/x0e080003"", ""DAV:hassubs"" FROM SCOPE "   sQuery = sQuery %26amp; "('SHALLOW TRAVERSAL OF """ %26amp; sUrl %26amp; """') "   sQuery = sQuery %26amp; "WHERE ""DAV:isfolder"" = true"   sQuery = sQuery %26amp; ""   sQuery = sQuery %26amp; ""   ' Set request headers.   oXMLHttp.setRequestHeader "Content-Type", "text/xml"   oXMLHttp.setRequestHeader "Translate", "f"   oXMLHttp.setRequestHeader "Depth", "0"   oXMLHttp.setRequestHeader "Content-Length", "" %26amp; Len(sQuery)   ' Send request.   oXMLHttp.send sQuery   If Err.Number <> 0 Then      WScript.Echo "Error Sending Query"      WScript.Echo Err.Number %26amp; ": " %26amp; Err.Description      Set oXMLHttp = Nothing   End If   ' Load XML.   Set oXMLDoc = oXMLHttp.responseXML   ' Get the XML nodes that contain the individual sizes.   Set oXMLSizeNodes = oXMLDoc.getElementsByTagName("d:x0e080003")   ' Get the XML nodes that contain the individual HREFs.   Set oXMLHREFNodes = oXMLDoc.getElementsByTagName("a:href")   ' Get the XML nodes that contain the individual HasSubs.   Set oXMLHasSubsNodes = oXMLDoc.getElementsByTagName("a:hassubs")   ' Loop through the nodes, and then add all of the sizes.   For i = 0 to oXMLSizeNodes.length - 1      WScript.Echo oXMLHREFNodes.Item(i).nodeTypedValue      WScript.Echo "Size: " %26amp; oXMLSizeNodes.Item(i).nodeTypedValue      iSum = iSum + oXMLSizeNodes.Item(i).nodeTypedValue      ' If the folder has subfolders, call your recursive function to      ' process subfolders.      If oXMLHasSubsNodes.Item(i).nodeTypedValue = True Then         RecurseFolder oXMLHREFNodes.Item(i).nodeTypedValue      End If   Next   ' Clean up.   Set oXMLSizeNodes = Nothing   Set oXMLDoc = Nothing   Set oXMLHttp = NothingEnd Sub				

注意:除了本节介绍的编程方法外,还可以通过使用 Exchange 系统管理器将文件夹大小信息导出到文本文件。

这篇文章中的信息适用于:
%26#8226;Microsoft Exchange Server 2003 Enterprise Edition
%26#8226;Microsoft Exchange Server 2003 Standard Edition
%26#8226;Microsoft Exchange 2000 Server 标准版
%26#8226;Microsoft Exchange Server 5.5 标准版
关键字:
kbhowto KB320071

更多内容请看PCdog.com--Exchange服务器  微软邮件服务器专题
上一篇:修改Exchange Server邮件提示
下一篇:如何在ISA2004中实现EXCHANGE的OWA密码修改功能