如何创建的 Exchange 服务器的"catchall"邮箱接收器

注意:这篇文章是由无人工介入的微软自动的机器翻译软件翻译完成。微软很高兴能同时提供给您由人工翻译的和由机器翻译的文章, 以使您能使用您的语言访问所有的知识库文章。然而由机器翻译的文章并不总是完美的。它可能存在词汇,语法或文法的问题,就像是一个外国人在说中文时总是可能犯这样的错误。虽然我们经常升级机器翻译软件以提高翻译质量,但是我们不保证机器翻译的正确度,也不对由于内容的误译或者客户对它的错误使用所引起的任何直接的, 或间接的可能的问题负责。

点击这里察看该文章的英文版: 324021
概要
本文介绍如何创建以捕获所有的电子邮件发送到某个特定域中的事件接收器,然后将它们直接指向单个邮箱。

注意本文所述将示例事件接收器重定向发送到域中的所有电子邮件。有关如何创建更复杂的事件接收器,请参阅 Exchange 软件开发工具包 (SDK) 的信息。

创建脚本文件

创建了下面的五个脚本,然后将它们存储在 Exchange 计算机上的某个文件夹中。

Microsoft 提供的编程示例只,用于说明不附带任何明示或暗示保证。这包括,但不限于对适销性或针对特定用途的适用性的暗示的担保。本文假定您熟悉演示了正在使用的编程语言以及用于创建和调试过程的工具。Microsoft 支持工程师可以帮助解释某个特定过程的功能,但他们不会修改这些示例以提供额外的功能或构建过程来满足您的具体要求。

Catchall.cmd

Catchall.cmd 文件调用 SMTPReg.vbs 脚本,并注册统称事件接收器。若要进行此.cmd 文件,请按照下列步骤操作:
  1. 键入或粘贴下面的代码,如记事本是文本编辑器中:
    cscript smtpreg.vbs /add 1 onarrival SMTPScriptingCatchAll CDO.SS_SMTPOnArrivalSink "mail from=*"cscript smtpreg.vbs /setprop 1 onarrival SMTPScriptingCatchAll Sink ScriptName d:\mec\catchall\catchall.vbscscript smtpreg.vbs /delprop 1 onarrival SMTPScriptingCatchAll Source Rule						
    笔记 修改以反映统称文件的文件夹位置 Catchall.vbs 文件路径。
  2. 将文件另存为 Catchall.cmd

Enum.cmd

在服务器上运行列表事件接收器注册的 Enum.cmd。若要进行此文件,请按照下列步骤操作:
  1. 键入或粘贴下面的代码,如记事本是文本编辑器中:
    cscript smtpreg.vbs /enum |more					
  2. 将文件另存为 Enum.cmd

Catchall.vbs

若要创建统称帐户使用 Catchall.vbs 脚本。 此文件为您的 Exchange Server 环境进行自定义。
  1. 键入或粘贴下面的代码,如记事本是文本编辑器中。将此文件保存为 Catchall.vbs
    <SCRIPT LANGUAGE="VBSCRIPT">'' For information about this namespace, see '   http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cdosys/html/_cdosys_schema_smtpenvelope.asp'Const RECIP_LIST = "http://schemas.microsoft.com/cdo/smtpenvelope/recipientlist"'' For information about the CdoEventStatus enumeration, see '   http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cdosys/html/_cdosys_cdoeventstatus_enum.asp'Const CDO_RUN_NEXT_SINK = 0'' OnArrival sink entry point'Sub ISMTPOnArrival_OnArrival(ByVal Msg, EventStatus)  On Error Resume Next  Dim objFields    Set objFields = Msg.EnvelopeFields  objFields(RECIP_LIST).Value = FixupRecipList(objFields(RECIP_LIST).Value)  objFields.Update    Msg.DataSource.Save ' Commit changes  EventStatus = CDO_RUN_NEXT_SINKEnd Sub''  Change any @example.com recipient(s) to bob@company.com'Function FixupRecipList(strList)  On Error Resume Next  Dim strFixedList  Dim nDomainPart  Dim nNamePart  Dim nNextAddress  strFixedList = strList  While (InStr(LCase(strFixedList),"@example.com"))    nDomainPart = InStr(LCase(strFixedList),"@example.com")    nNamePart = InStrRev(strFixedList,";",nDomainPart)    nNextAddress = InStr(nDomainPart+Len("@example.com;"),strFixedList,"SMTP:")    If (0 = nNamePart) Then      ' @example.com is first name in recipient list      If (0 = nNextAddress) Then        ' @example.com is the last name in the recipient list        strFixedList = "SMTP:bob@company.com;"      Else        ' @example.com is not the last name in the recipient list        strFixedList = "SMTP:bob@company.com;" & Right(strFixedList,Len(strFixedList)-nNextAddress+1)      End If    Else      ' @example.com is not the first name in recipient list      If (0 = nNextAddress) Then        ' @example.com is the last name in the recipient list        strFixedList = Left(strFixedList,nNamePart) & "SMTP:bob@company.com;"      Else        ' @example.com is not the last name in the recipient list        strFixedList = Left(strFixedList,nNamePart) & "SMTP:bob@company.com;" & Right(strFixedList,Len(strFixedList)-nNextAddress+1)      End If    End If  Wend  FixupRecipList = strFixedListEnd Function</SCRIPT>					
  2. 编辑 Catchall.vbs 文件,以用 @ yourdomain.com,其中 yourdomain.com 是要重定向电子邮件的域。
  3. bob@company.com 的所有匹配项替换为要重定向为您在步骤 2 中指定域的所有电子邮件的邮箱的 SMTP 地址。

    注意从不同的域,从中您想要重定向电子邮件的域不是您要重定向 必须 的所有邮件的电子邮件地址。例如对于如果您在步骤 2 中指定的域是 @ company.com,您在步骤 3 中指定的电子邮件地址不能为 bob @ company.com。如果域是相同的该消息将连续地循环,最终将返回给发件人,作为无法传递。

    如果收件人必须有 catchall 域的电子邮件地址 (要将电子邮件消息重定向到域) 如 bob@company.com,将 @ company.local 如一个额外的域添加到收件人策略中为用户,然后将 bob@company.local 的 SMTP 地址添加到用户的电子邮件地址。bob@company.local 的地址来指定在步骤 3 中然后作为电子邮件地址使用。

SMTPReg.vbs

创建一个脚本来注册统称事件接收器。若要这样做,请按照下列步骤操作:
  1. 键入或粘贴下面的代码,如记事本是文本编辑器中:
    'THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT 'WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, 'INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES 'OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR 'PURPOSE'------------------------------------------------------------------------------'FILE DESCRIPTION: Script for registering for SMTP Protocol sinks. ''File Name: smtpreg.vbs' '' Copyright (c) Microsoft Corporation 1993-1998. All rights reserved.'------------------------------------------------------------------------------Option Explicit''' the OnArrival event GUIDConst GUIDComCatOnArrival = "{ff3caa23-00b9-11d2-9dfb-00C04FA322BA}"' the SMTP source typeConst GUIDSourceType = "{FB65C4DC-E468-11D1-AA67-00C04FA345F6}"' Const GUIDCat = "{871736c0-fd85-11d0-869a-00c04fd65616}"Const GUIDSources = "{DBC71A31-1F4B-11d0-869D-80C04FD65616}"' the SMTP service display name.  This is used to key which service to' editConst szService = "smtpsvc"' the event manager object.  This is used to communicate with the ' event binding database.Dim EventManagerSet EventManager = WScript.CreateObject("Event.Manager")'' register a new sink with event manager'' iInstance - the instance to work against' szEvent - OnArrival' szDisplayName - the display name for this new sink' szProgID - the progid to call for this event' szRule - the rule to set for this event'public sub RegisterSink(iInstance, szEvent, szDisplayName, szProgID, szRule)	Dim SourceType	Dim szSourceDisplayName	Dim Source	Dim Binding	Dim GUIDComCat	Dim PrioVal	' figure out which event they are trying to register with and set	' the comcat for this event in GUIDComCat	select case LCase(szEvent)		case "onarrival"			GUIDComCat = GUIDComCatOnArrival		case else			WScript.echo "invalid event: " & szEvent			exit sub	end select	' enumerate through each of the registered instances for the SMTP source	' type and look for the display name that matches the instance display	' name	set SourceType = EventManager.SourceTypes(GUIDSourceType)	szSourceDisplayName = szService & " " & iInstance	for each Source in SourceType.Sources		if Source.DisplayName = szSourceDisplayName then			' You have found the instance that you want. Now add a new binding			' with the right event GUID.  by not specifying a GUID to the			' Add method you get server events to create a new ID for this			' event			set Binding = Source.GetBindingManager.Bindings(GUIDComCat).Add("")			' set the binding properties			Binding.DisplayName = szDisplayName			Binding.SinkClass = szProgID			' register a rule with the binding			Binding.SourceProperties.Add "Rule", szRule			' register a priority with the binding			PrioVal = GetNextPrio(Source, GUIDComCat)			If PrioVal < 0 then				WScript.Echo "assigning priority to default value (24575)"				Binding.SourceProperties.Add "Priority", 24575			else					WScript.Echo "assigning priority (" & PrioVal & " of 32767)"				Binding.SourceProperties.Add "Priority", PrioVal			end if			' save the binding			Binding.Save			WScript.Echo "registered " & szDisplayName			exit sub		end if	nextend sub'' iterate through the bindings in a source, find the binding' with the lowest priority, and return the next priority value.' If the next value exceeds the range, return -1.'public function GetNextPrio(oSource, GUIDComCat)	' it's possible that priority values will not be	' numbers, so you add error handling for this case	on error resume next	Dim Bindings	Dim Binding	Dim nLowestPrio	Dim nPrioVal	nLowestPrio = 0	set Bindings = oSource.GetBindingManager.Bindings(GUIDComCat)	' if the bindings collection is empty, then this is the first	' sink. It receives the highest priority (0).	if Bindings.Count = 0 then		GetNextPrio = 0	else		' get the lowest existing priority value		for each Binding in Bindings			nPrioVal = Binding.SourceProperties.Item("Priority")			if CInt(nPrioVal) > nLowestPrio then				if err.number = 13 then					err.clear				else					nLowestPrio = CInt(nPrioVal)				end if			end if		next 		' assign priority values in increments of 10 so priorities		' can be shuffled later without the need to reorder all		' binding priorities.  Valid priority values are 0 - 32767		if nLowestPrio + 10 > 32767 then			GetNextPrio = -1		else			GetNextPrio = nLowestPrio + 10		end if	end ifend function  '' Search for a previously registered sink with the passed in name'' iInstance - the instance to work against' szEvent - OnArrival' szDisplayName - the display name of the event to check' bCheckError - Any errors returnedpublic sub CheckSink(iInstance, szEvent, szDisplayName, bCheckError)	Dim SourceType	Dim GUIDComCat	Dim szSourceDisplayName	Dim Source	Dim Bindings	Dim Binding	bCheckError = FALSE	select case LCase(szEvent)		case "onarrival"			GUIDComCat = GUIDComCatOnArrival		case else			WScript.echo "invalid event: " & szEvent			exit sub	end select	' find the source for this instance	set SourceType = EventManager.SourceTypes(GUIDSourceType)	szSourceDisplayName = szService & " " & iInstance	for each Source in SourceType.Sources		if Source.DisplayName = szSourceDisplayName then			' find the binding by display name.  to do this, enumerate			' all of the bindings and try to match on the display name			set Bindings = Source.GetBindingManager.Bindings(GUIDComCat)			for each Binding in Bindings				if Binding.DisplayName = szDisplayName then					' you have found the binding, now log an error					WScript.Echo "Binding with the name " & szDisplayName & " already exists"					exit sub 				end if			next		end if	next	bCheckError = TRUEend sub'' unregister a previously registered sink'' iInstance - the instance to work against' szEvent - OnArrival' szDisplayName - the display name of the event to remove'public sub UnregisterSink(iInstance, szEvent, szDisplayName)	Dim SourceType	Dim GUIDComCat	Dim szSourceDisplayName	Dim Source	Dim Bindings	Dim Binding	select case LCase(szEvent)		case "onarrival"			GUIDComCat = GUIDComCatOnArrival		case else			WScript.echo "invalid event: " & szEvent			exit sub	end select	' find the source for this instance	set SourceType = EventManager.SourceTypes(GUIDSourceType)	szSourceDisplayName = szService & " " & iInstance	for each Source in SourceType.Sources		if Source.DisplayName = szSourceDisplayName then			' find the binding by display name.  to do this, enumerate			' all of the bindings and try to match on the display name			set Bindings = Source.GetBindingManager.Bindings(GUIDComCat)			for each Binding in Bindings				if Binding.DisplayName = szDisplayName then					' you have found the binding, now remove it					Bindings.Remove(Binding.ID)					WScript.Echo "removed " & szDisplayName & " " & Binding.ID				end if			next		end if	nextend sub'' add or remove a property from the source or sink propertybag for an event'' iInstance - the SMTP instance to edit' szEvent - the event type (OnArrival)' szDisplayName - the display name of the event' szPropertyBag - the property bag to edit ("source" or "sink")' szOperation - "add" or "remove"' szPropertyName - the name to edit in the property bag' szPropertyValue - the value to assign to the name (ignored for remove)'public sub EditProperty(iInstance, szEvent, szDisplayName, szPropertyBag, szOperation, szPropertyName, szPropertyValue)	Dim SourceType	Dim GUIDComCat	Dim szSourceDisplayName	Dim Source	Dim Bindings	Dim Binding	Dim PropertyBag	select case LCase(szEvent)		case "onarrival"			GUIDComCat = GUIDComCatOnArrival		case else			WScript.echo "invalid event: " & szEvent			exit sub	end select	' find the source for this instance	set SourceType = EventManager.SourceTypes(GUIDSourceType)	szSourceDisplayName = szService & " " & iInstance	for each Source in SourceType.Sources		if Source.DisplayName = szSourceDisplayName then			set Bindings = Source.GetBindingManager.Bindings(GUIDComCat)			' find the binding by display name.  to do this, enumerate			' all of the bindings and try to match on the display name			for each Binding in Bindings				if Binding.DisplayName = szDisplayName then					' figure out which set of properties you want to modify					' based on the szPropertyBag parameter					select case LCase(szPropertyBag)						case "source"							set PropertyBag = Binding.SourceProperties						case "sink"							set PropertyBag = Binding.SinkProperties						case else							WScript.echo "invalid propertybag: " & szPropertyBag							exit sub					end select					' figure out what operation you want to perform					select case LCase(szOperation)						case "remove"							' they want to remove szPropertyName from the							' property bag							PropertyBag.Remove szPropertyName							WScript.echo "removed property " & szPropertyName						case "add"							' add szPropertyName to the property bag and 							' set its value to szValue.  if this value							' already exists then this will change  the value							' it to szValue.							PropertyBag.Add szPropertyName, szPropertyValue							WScript.echo "set property " & szPropertyName & " to " & szPropertyValue						case else							WScript.echo "invalid operation: " & szOperation							exit sub					end select					' save the binding					Binding.Save				end if			next		end if	nextend sub'' this helper function takes an IEventSource object and a event category' and dumps all of the bindings for this category under the source'' Source - the IEventSource object to display the bindings for' GUIDComCat - the event category to display the bindings for'public sub DisplaySinksHelper(Source, GUIDComCat)	Dim Binding	Dim propval	' walk each of the registered bindings for this component category	for each Binding in Source.GetBindingManager.Bindings(GUIDComCat)		' display the binding properties		WScript.echo "    Binding " & Binding.ID & " {"		WScript.echo "      DisplayName = " & Binding.DisplayName		WScript.echo "      SinkClass = " & Binding.SinkClass		if Binding.Enabled = True then			WScript.echo "      Status = Enabled"		else			WScript.echo "      Status = Disabled"		end if		' walk each of the source properties and display them		WScript.echo "      SourceProperties {"		for each propval in Binding.SourceProperties			WScript.echo "        " & propval & " = " & Binding.SourceProperties.Item(propval)		next		WScript.echo "      }"		' walk each of the sink properties and display them		WScript.echo "      SinkProperties {"		for each Propval in Binding.SinkProperties			WScript.echo "        " & propval & " = " & Binding.SinkProperties.Item(Propval)		next		WScript.echo "      }"		WScript.echo "    }"	nextend sub'' dumps all of the information in the binding database related to SMTP'public sub DisplaySinks	Dim SourceType	Dim Source	' look for each of the sources registered for the SMTP source type	set SourceType = EventManager.SourceTypes(GUIDSourceType)	for each Source in SourceType.Sources		' display the source properties		WScript.echo "Source " & Source.ID & " {"		WScript.echo "  DisplayName = " & Source.DisplayName		' display all of the sinks registered for the OnArrival event		WScript.echo "  OnArrival Sinks {"		call DisplaySinksHelper(Source, GUIDComCatOnArrival)		WScript.echo "  }"	nextend sub'' enable/disable a registered sink'' iInstance - the instance to work against' szEvent - OnArrival' szDisplayName - the display name for this new sink'public sub SetSinkEnabled(iInstance, szEvent, szDisplayName, szEnable)	Dim SourceType	Dim GUIDComCat	Dim szSourceDisplayName	Dim Source	Dim Bindings	Dim Binding	select case LCase(szEvent)		case "onarrival"			GUIDComCat = GUIDComCatOnArrival		case else			WScript.echo "invalid event: " + szEvent			exit sub	end select	' find the source for this instance	set SourceType = EventManager.SourceTypes(GUIDSourceType)	szSourceDisplayName = szService + " " + iInstance	for each Source in SourceType.Sources		if Source.DisplayName = szSourceDisplayName then			' find the binding by display name.  to do this, enumerate			' all of the bindings and try to match on the display name			set Bindings = Source.GetBindingManager.Bindings(GUIDComCat)			for each Binding in Bindings				if Binding.DisplayName = szDisplayName then					' You have found the binding, now enable/disable it					' You do not need "case else' because szEnable's value					' is set internally, not by users					select case LCase(szEnable)						case "true"							Binding.Enabled = True							Binding.Save							WScript.Echo "enabled " + szDisplayName + " " + Binding.ID						case "false"							Binding.Enabled = False							Binding.Save							WScript.Echo "disabled " + szDisplayName + " " + Binding.ID						end select				end if			next		end if	nextend sub' ' display usage information for this script'public sub DisplayUsage	WScript.echo "usage: cscript smtpreg.vbs <command> <arguments>"	WScript.echo "  commands:"	WScript.echo "    /add <Instance> <Event> <DisplayName> <SinkClass> <Rule>"	WScript.echo "    /remove <Instance> <Event> <DisplayName>"	WScript.echo "    /setprop <Instance> <Event> <DisplayName> <PropertyBag> <PropertyName> "	WScript.echo "             <PropertyValue>"	WScript.echo "    /delprop <Instance> <Event> <DisplayName> <PropertyBag> <PropertyName>"	WScript.echo "    /enable <Instance> <Event> <DisplayName>"	WScript.echo "    /disable <Instance> <Event> <DisplayName>"	WScript.echo "    /enum"	WScript.echo "  arguments:"	WScript.echo "    <Instance> is the SMTP instance to work against"	WScript.echo "    <Event> can be OnArrival"	WScript.echo "    <DisplayName> is the display name of the event to edit"	WScript.echo "    <SinkClass> is the sink class for the event"	WScript.echo "    <Rule> is the rule to use for the event"		WScript.echo "    <PropertyBag> can be Source or Sink"	WScript.echo "    <PropertyName> is the name of the property to edit"	WScript.echo "    <PropertyValue> is the value to assign to the property"end subDim iInstanceDim szEventDim szDisplayNameDim szSinkClassDim szRuleDim szPropertyBagDim szPropertyNameDim szPropertyValuedim bCheck'' this is the main body of our script.  it reads the command line parameters' specified and then calls the appropriate function to perform the operation'if WScript.Arguments.Count = 0 then	call DisplayUsageelse 	Select Case LCase(WScript.Arguments(0))		Case "/add"			if not WScript.Arguments.Count = 6 then				call DisplayUsage			else				iInstance = WScript.Arguments(1)				szEvent = WScript.Arguments(2)				szDisplayName = WScript.Arguments(3)				szSinkClass = WScript.Arguments(4)				szRule = WScript.Arguments(5)				call CheckSink(iInstance, szEvent, szDisplayName, bCheck)				if bCheck = TRUE then					call RegisterSink(iInstance, szEvent, szDisplayName, szSinkClass, szRule)				End if			end if		Case "/remove"			if not WScript.Arguments.Count = 4 then				call DisplayUsage			else				iInstance = WScript.Arguments(1)				szEvent = WScript.Arguments(2)				szDisplayName = WScript.Arguments(3)				call UnregisterSink(iInstance, szEvent, szDisplayName)			end if			Case "/setprop"			if not WScript.Arguments.Count = 7 then				call DisplayUsage			else				iInstance = WScript.Arguments(1)				szEvent = WScript.Arguments(2)				szDisplayName = WScript.Arguments(3)				szPropertyBag = WScript.Arguments(4)				szPropertyName = WScript.Arguments(5)				szPropertyValue = WScript.Arguments(6)				call EditProperty(iInstance, szEvent, szDisplayName, szPropertyBag, "add", szPropertyName, szPropertyValue)			end if		Case "/delprop"			if not WScript.Arguments.Count = 6 then				call DisplayUsage			else				iInstance = WScript.Arguments(1)				szEvent = WScript.Arguments(2)				szDisplayName = WScript.Arguments(3)				szPropertyBag = WScript.Arguments(4)				szPropertyName = WScript.Arguments(5)				call EditProperty(iInstance, szEvent, szDisplayName, szPropertyBag, "remove", szPropertyName, "")					end if		Case "/enable"			if not WScript.Arguments.Count = 4 then				call DisplayUsage			else				iInstance = WScript.Arguments(1)				szEvent = WScript.Arguments(2)				szDisplayName = WScript.Arguments(3)				call SetSinkEnabled(iInstance, szEvent, szDisplayName, "True")			end if		Case "/disable"			if not WScript.Arguments.Count = 4 then				call DisplayUsage			else				iInstance = WScript.Arguments(1)				szEvent = WScript.Arguments(2)				szDisplayName = WScript.Arguments(3)				call SetSinkEnabled(iInstance, szEvent, szDisplayName, "False")			end if		Case "/enum"			if not WScript.Arguments.Count = 1 then				call DisplayUsage			else				call DisplaySinks			end if		Case Else			call DisplayUsage	End Selectend if					
  2. 将文件另存为 Smtpreg.vbs

Removecatchall.cmd

创建一个.cmd 文件以删除 (卸载) 统称事件接收器,如果您认为您可能希望以后将其删除。若要这样做,请按照下列步骤操作:
  1. 键入或粘贴下面的代码,如记事本是文本编辑器中:
    cscript smtpreg.vbs /remove 1 onarrival SMTPScriptingCatchAll					
  2. 此文件另存为 Removecatchall.cmd

    注意如果要删除统称事件接收器可以通过从命令提示符处运行 Removecatchall.cmd 执行操作。

注册 catchall 事件接收器

  1. 验证您已创建了一个有效的电子邮件帐户,用来收集已重定向的电子邮件。
  2. 从包含您创建的.vbs 文件的目录中运行该 Catchall.cmd。
  3. 重新启动 SMTP 服务在 Exchange 系统管理器中。
  4. 测试事件接收器通过电子邮件邮件发送到您在本文的"Catchall.vbs"节的第 2 步中指定 catchall 域中的电子邮件地址。将邮件传递到收件人的邮箱与您在同一文章节的第 3 步中指定的地址。
参考
有关如何获取 Exchange 2000 SDK 的其他信息,请访问下面的 Microsoft 网站:

警告:本文已自动翻译

属性

文章 ID:324021 - 上次审阅时间:12/03/2007 04:54:46 - 修订版本: 5.6

Microsoft Exchange 2000 Server 标准版, Microsoft Exchange Server 2003 Enterprise Edition, Microsoft Exchange Server 2003 Standard Edition, Microsoft Windows Small Business Server 2003 Premium Edition, Microsoft Windows Small Business Server 2003 Standard Edition

  • kbmt kbhowtomaster KB324021 KbMtzh
反馈