How to manage queues and links
In Exchange Server 2003, Microsoft expanded the Windows Management Instrumentation (WMI) capabilities by supplying five new providers and 15 new WMI classes. In "Managing Exchange 2003 with WMI, Part 1," January 2004, http://www.winnetmag.com/microsoftexchangeoutlook, InstantDoc ID 40755, and "Managing Exchange 2003 with WMI, Part 2," February 2004, InstantDoc ID 41022, I showed you how to use these new providers and classes to manage Exchange servers, logons, mailboxes, and public folders. In this article, I finish the exploration of the new WMI features by showing you how to use the new providers and classes to manage Exchange queues and links.
Because all messages that users exchange go through the queues and links of an Exchange system, monitoring those queues and links and changing their states are crucial tasks. Exchange 2000 Server lets you perform some monitoring, but Microsoft made several important enhancements in this area in Exchange 2003.
Exchange 2003 provides a new WMI queue provider called ExchangeQueue2Provider in the Root\MicrosoftExchangeV2 namespace. This new provider doesn't replace but rather complements the Exchange 2000 queue provider called ExchangeQueueProvider in the Root\CIMV2\Applications\Exchange namespace. Both providers support a set of classes, which Web Table 1 (http://www.winnetmag.com/microsoftexchangeoutlook, InstantDoc ID 41342) describes. From this point on in the article, I concentrate on the new WMI queue classes in Exchange 2003. If you want additional information about the WMI queue classes in Exchange 2000, see the Microsoft article "Automating Exchange 2000 Management with Windows Script Host" (http://www.microsoft.com/technet/treeview/default.asp?url=/technet/prodtechnol/exchange/exchange2000/maintain/featusability/ex2kwsh.asp?frame=true.
With the classes that the ExchangeQueue2Provider supports, you can use scripts that retrieve information about Exchange queues and links and perform some management tasks, such as thawing, freezing, and forcing links; disabling and enabling all outbound SMTP traffic; managing mail messages; and monitoring the cache refresh. Before I show you how to use these scripts, you need to understand the important distinction between queues and links.
Queues vs. Links
When you install Exchange 2003, the Exchange setup program creates a series of default queues and links. In a messaging topology, queues refer to the end destinations of the messages, whereas links establish connectivity to the adjacent SMTP nodes. Queues are built based on DNS domains, whereas links reflect TCP/IP connections used to route messages. When you send a message, Exchange places that message in the queues of the domains of all the targeted recipients. For example, if you send a message to users in the hp.com, compaq.com, and digital.com domains, Exchange places the message in three queues called hp.com, compaq.com, and digital.com, respectively.
In the simplest scenario, three outgoing links might correspond to each of these three queues. However, this scenario isn't necessarily the case. If a domain has multiple DNS MX records, Exchange might use more than one link per queue. Or if the domains' DNS MX records contain the same values (e.g., hp.com, compaq.com, and digital.com all point to the server smtp.hp.com), the queues might share the same link.
WMI clearly distinguishes between queues and links. It has classes to manage SMTP queues and links (i.e., Exchange_SMTPQueue and Exchange_SMTPLink) and X400 queues and links (i.e., Exchange_X400Queue and Exchange_X400Link). Because Exchange handles both SMTP and X400 messages, WMI also has classes to manage SMTP and X400 messages (i.e., Exchange_QueuedSMTPMessage and Exchange_QueuedX400Message). Virtual servers handle the queues, links, and messages, so WMI has classes that support SMTP and X400 virtual servers (i.e., Exchange_QueueSMTPVirtualServer and Exchange_QueueX400VirtualServer). Finally, WMI has the Exchange_QueueCacheReloadEvent class, which provides information about when the ExchangeQueue2Provider cache was last refreshed.
Now that you know the difference between queues and links, let's take a quick look at how you can use these nine new WMI classes in scripts. Taking the easiest task first, let's look at how you can retrieve queue and link information.
Retrieving Queue and Link Information
In Parts 1 and 2 of this series, I showed you how to use the script GetCollectionOfInstances.wsf to list all instances of a WMI class. (You can find GetCollectionOfInstances.wsf and all the other code that I discuss in this article on the Exchange & Outlook Administrator Web site. Go to http://www.winnetmag.com/microsoftexchangeoutlook, enter InstantDoc ID 41342 in the InstantDoc ID box, then click Download the Code.) You can use this script to retrieve instances of WMI's queue- and link-related classes. For example, to view SMTP queue information on an Exchange server, you can run GetCollectionOfInstances.wsf against the WMI Query Language (WQL) query
Select * From Exchange_SMTPQueue
On my Exchange server, this WQL query retrieved the properties of all SMTP queues, including the queues associated with a Routing Group Connector (RGC) and an outgoing Internet mail connector. Figure 1 contains an excerpt from this output. This excerpt shows the values for the QueueName property, which specifies a queue's name. Web Figure 1 (http://www.winnetmag.com/microsoftexchangeoutlook, InstantDoc ID 41342) shows the output in its entirety.
If you run GetCollectionOfInstances.wsf against the WQL query
Select * From Exchange_SMTPLink
you'll receive the properties of all the links on an Exchange server. Figure 2 contains an excerpt from the output I received. This excerpt shows the values for the LinkName property, which specifies a link's name. Web Figure 2 shows this output in its entirety. You can also run GetCollectionOfInstances.wsf against WQL queries that specify the Exchange_X400Queue and Exchange_X400Link classes to expose similar sets of properties.
Unfortunately, the queue and link information that you receive through WMI doesn't match the queue and link information you see in Exchange System Manager (ESM). WMI explicitly separates the queue and link information, whereas ESM shows queue and link information together without delineating which information is queue related and which information is link related. In Figure 3, I show which ESM elements correspond to the Exchange_SMTPQueue, Exchange_SMTPLink, Exchange_X400Queue, Exchange_X400Link, and Exchange_QueueSMTPVirtualServer classes.
ESM presents its queue and link information differently than WMI because ESM relies on the Queue API subsystem for its information. For example, when you disable queues from ESM, you're managing the Exchange queue subsystem at the link level. ESM's queue and link names are generally more user-friendly than WMI's queue and link names, but the correlation between them is fairly easy to discern, as Table 1 shows. However, four exceptions exist: Outgoing Internet mail - compaq.com (SMTP Connector), Outgoing Internet mail - hp.com (SMTP Connector), Routing Group Connector 1 (Routing Group Connector), and Local delivery.
Outgoing Internet mail - compaq.com (SMTP Connector) and Outgoing Internet mail - hp.com (SMTP Connector). At the bottom of the tree in Figure 3, notice the connector named Outgoing Internet Mail in the Connectors folder for the First Routing Group. This dedicated SMTP connector connects the Exchange organization called LissWareNET to the Internet. When users send mail messages to any external DNS domain (in this example, the compaq.com and hp.com domains), Exchange routes those messages to the external world through the Outgoing Internet Mail connector. For this reason, ESM uses Outgoing Internet mail - compaq.com (SMTP Connector) and Outgoing Internet mail - hp.com (SMTP Connector), respectively, as the name for the queue and its associated link. Unlike ESM, WMI uses only the domain name for the queue and link names.
Routing Group Connector 1 (Routing Group Connector). In Figure 3's tree, notice a connector named Routing Group Connector 1 in the Connectors folder. When you have an RGC setup, the SMTP-based RGC uses its own queue and link. When displaying the RGC's queue and link information, ESM simply shows the connector's name followed by the type of connector.
WMI's approach to naming an RGC link is much more complicated than ESM's approach. WMI uses the globally unique identifier (GUID) of the msExchRoutingGroupConnector object that represents the RGC in Active Directory (AD). Take, for example, the RGC named Routing Group Connector 1 in my AD forest. This object is in a container that has the distinguished name (DN) CN=Connections,CN=First Routing Group,CN=Routing Groups,CN=First Administrative Group,CN=AdministrativeGroups,CN=LissWareNET,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=LissWare,DC=NET. (The DN will vary slightly in your organization, depending on the names of your AD forest and Exchange organization.) When I use ADSI Edit to look at the objectGUID attribute of the msExchRoutingGroupConnector object that represents Routing Group Connector 1, I see that this attribute contains the following GUID, which is in binary format: CB E6 CB 6A C5 72 9A 4E B3 8C 2E F2 03 8A 99 C3.
WMI's LinkName property value is a modified version of that GUID. WMI concatenates each byte of the binary GUID to obtain a string, then lowercases the string's letters. WMI then precedes this string with an underscore and ends the string with an underscore followed by the capital letter D. Thus, the LinkName property value for Routing Group Connector 1 is _cbe6cb6ac5729a4eb38c2ef2038a99c3_D.
The queue name follows a different rule, however. Because the RGC connects two Exchange servers, the queue name for the RGC uses the Fully Qualified Domain Name (FQDN) of the target server, which is called vm10284346f.LissWare.Net in my Exchange network.
Local delivery. In Figure 3's tree, notice the queue called Local delivery. This representation of the ESM queue corresponds to the LissWare.Net (i.e., the link organization's DNS name) and the LocalAsyncQueue queue in WMI.
With the exception of the links and queues related to the RGC and the Outgoing Internet Mail connector, the Exchange setup program creates all links and queues in Table 1. These queues and links are associated with the default virtual server during the Exchange setup. Therefore, if you create an additional SMTP virtual server with ESM, you'll get an additional same set of links and queues. (WMI's VirtualServerName property of a queue and link specifies the virtual server name that the queue and link relate to.)
Retrieving In-Depth Link Information
As I just showed you, you can use GetCollectionOfInstances.wsf against WQL queries that specify WMI classes for SMTP and X400 queues and links. Using the property values that the results provide, you can retrieve more in-depth information about those queues and links. For example, to display information about a specific link, you can run GetCollectionOfInstances.wsf against the WQL query
Select * From Exchange_SMTPLink Where LinkName=_xxxx_D
where _xxxx_D is the LinkName property value of the RGC for which you want to obtain information.
Another way to obtain the same information about a link is to use the LinkDN property value. Although the name would suggest that the LinkDN property value is a DN, this value is a string that's based, once again, on the binary GUID that the msExchRoutingGroupConnector object's objectGUID attribute stores. WMI converts the binary GUID into a string by using the conversion scheme that Web Figure 3 shows. In this case, the WQL query is
Select * From Exchange_SMTPLink Where LinkDN='yyyy'
where yyyy is the LinkDN property value.
Finding the msExchRoutingGroupConnector object's objectGUID attribute value and making the necessary conversions to get the LinkName or LinkDN property value for the WQL query isn't easy. However, you can use a script to perform this task. For example, Listing 1 contains the script RGC1.wsf, which determines the LinkName and LinkDN properties of Routing Group Connector 1. As the code at callout A in Listing 1 shows, this script uses two custom helper functions: ReplaceByFunction (which performs string replacements within GUID strings) and TinyErrorHandler (which handles error checking during the script's execution). The script also uses an ActiveX control, WSHConvert, to help convert the binary GUID to a string. You must use regsvr32.exe to register this ActiveX control. (For more information about WSHConvert, see "Extending the AD Schema," November 2001, http://www.winnetmag.com, InstantDoc ID 22540.)
Next, RGC1.wsf binds to the AD object that represents Routing Group Connector 1 by referencing that object's DN. As the code at callout B shows, the DN includes the connector's display name, which the cRGSMTPLink constant stores. The script then obtains the objectGUID attribute value, which is the binary GUID. Finally, with the help of WSHConvert's Conversion function, the code at callout C converts the binary GUID to the various formats that the LinkName and LinkDN properties require.
Thawing, Freezing, and Forcing Links
When you right-click a queue in ESM, you can perform several operations that occur at the link level of the Exchange queue subsystem. You can perform those same operations with the Exchange_SMTPLink and Exchange_X400Link classes. Both classes expose three methods that correspond to three ESM options:
- The classes' Thaw method, which corresponds to ESM's Unfreeze option, enables a link.
- The classes' Freeze method, which corresponds to ESM's Freeze option, disables a link.
- The classes' ForceConnection method, which corresponds to ESM's Force connections option, recomputes a route through which to deliver all messages in the link immediately, rather than waiting for the next scheduled connection.
The Thaw, Freeze, and ForceConnection methods are simple to use because they don't require any parameters. The script LinkOps.wsf, which Listing 2, page 14, shows, demonstrates how to use the methods. As the code at callout A in Listing 2 shows, the script uses the TinyErrorHandler function and the SWbemLocator object, which lets you make WMI connections.
In the next section, LinkOps.wsf declares the constants and variables, as the code at callout B shows. To use this script, you need to customize some of the constants. If you're accessing a remote Exchange server, update the cUserID and cPassword constants, which define the credentials to use. If you're running the script locally on an Exchange server, update the cComputerName constant, which defines the name of the Exchange server to access. You don't have to update the cUserID and cPassword constants because local access is made within the security context of the user running the script.
LinkOps.wsf is configured to connect to the Messages pending submission link. If you want the script to connect to a different link, you need to customize the cSMTPLink constant. For example, if you want to connect to the Messages awaiting directory lookup link, you need to replace PreSubmissionQueue with PreCatQueue.
Next, the code at callout C makes the WMI connection and submits a WQL query to locate the specified link. The script then enumerates the collection that the query retrieved. As the code at callout D shows, during the enumeration, the script invokes the Freeze method. If you want the script to invoke the Thaw or ForceConnection method instead, you need to replace the word Freeze with either Thaw or ForceConnection.
Disabling or Enabling SMTP Traffic
If you want to disable or enable all outbound SMTP traffic, you use the Exchange_QueueSMTPVirtualServer class. This class, which represents an Exchange SMTP virtual server, exposes two methods: DisableAll and EnableAll. (The Exchange_QueueX400VirtualServer class doesn't expose any methods to enable or disable outbound traffic because X400 communication works differently.) The DisableAll method, which corresponds to the Disable Outbound Mail button in Figure 3, disables all queues that route mail messages outside the Exchange server (in this case, the hp.com, compaq.com, and Routing Group Connector 1 queues). After you execute the DisableAll method, the Disable Outbound Mail button in ESM changes to Enable Outbound Mail button, which corresponds to the EnableAll method. (You must refresh the ESM display to immediately see the button name change.)
DisableAll and EnableAll don't require input parameters. As a result, you can adapt LinkOps.wsf so that it disables or enables all outbound SMTP traffic by changing the WQL query and the invoked method. Let's take the easiest change first. At callout D in Listing 2, you simply replace Freeze with either DisableAll or EnableAll.
At callout C in Listing 2, you need to use a WQL query that locates a virtual server rather than a link. Thus, you need to specify the Exchange_QueueSMTPVirtualServer class in a query such as
Select * From Exchange_QueueSMTPVirtualServer Where VirtualMachine='VM10284346B' And VirtualServerName='1'"
In this query, you set the VirtualMachine property to the name of the Exchange server that hosts the virtual server. If you want to specify the default SMTP virtual server, you set the VirtualServerName property to 1, which represents the first virtual server. If you've used ESM to create an additional SMTP virtual server in your Exchange system, the VirtualServerName property value for that second virtual server is 2.
If you have several SMTP virtual servers, the Disable Outbound Mail button will change to Enable Outbound Mail only when you disable all outbound traffic of all the SMTP virtual servers. In other words, ESM's Disable Outbound Mail function is global to all SMTP virtual servers, whereas WMI's DisableAll method is local to the specified virtual server.
Managing Mail Messages
Now that you know how to retrieve information about and manage queues and links, you can manage mail messages. Before you can manage a mail message, you have to locate it. You can again use GetCollectionOfInstances.wsf, but this time you need to specify the Exchange_QueuedSMTPMessage class in the WQL query. However, WMI doesn't let you query all instances of the Exchange_QueuedSMTPMessage class that you might have across the various queues. You must specify the queue and link that contains the message. The WMI properties you need to include are the Exchange_SMTPQueue class's LinkID, LinkName, ProtocolName, QueueID, and QueueName properties. Fortunately, getting these properties' values is easy. You can simply run GetCollectionOfInstances.wsf against a WQL query that specifies the Exchange_SMTPQueue class, as I did to obtain the SMTP queue information in Web Figure 1. Figure 4 shows a sample WQL query that retrieves a mail message. Web Figure 4 contains the output from this query.
After you locate the message, you can use the Exchange_QueuedSMTPMessage class's methods to manage that message. The four methods and the corresponding options in ESM are as follows:
- The DeleteNDR method, which corresponds to ESM's Delete (with NDR) option, deletes a message and sends a nondelivery report (NDR).
- The DeleteNoNDR method, which corresponds to ESM's Delete (no NDR) option, deletes a message but doesn't send an NDR.
- The Freeze method, which corresponds to ESM's Freeze option, stops a message from leaving the queue.
- The Thaw method, which corresponds to ESM's Unfreeze option, releases a message that was previously stopped.
In ESM, you can find the options just listed by clicking the Find Messages button, which leads to a dialog box that lets you search for messages. If you right-click a search result, the Properties dialog box provides the four options, as Web Figure 5 shows.
None of the Exchange_QueuedSMTPMessage class methods requires an input parameter. Thus, you can adapt LinkOps.wsf so that it deletes, freezes, or thaws messages. You just need to adapt this script by changing the WQL query at callout C and the name of the invoked method at callout D. The WQL query would be similar to the one in Figure 4.
Monitoring the Cache Refresh
To improve the queue subsystem information access, ExchangeQueue2Provider has a cache to store management data. ExchangeQueue2Provider automatically refreshes this cache, following a schedule that it determines based on the Exchange server's configuration and activity level. (You can't control the refresh schedule.) On my Exchange system, ExchangeQueue2Provider refreshes its cache about every 5 minutes.
The Exchange_QueueCacheReloadEvent class is useful for monitoring when ExchangeQueue2Provider refreshes its cache. If you run the script GenericEventAsyncConsumer.wsf, which I used in Part 1, against the WQL query
Select * From Exchange_QueueCacheReloadEvent
you'll receive notifications each time ExchangeQueue2Provider refreshes its cache. Web Figure 6 shows the output from this query. Through these notifications, you can determine the refresh schedule of ExchangeQueue2Provider in your system.
Any information that ExchangeQueue2Provider returns through one of its supported classes is subject to the cache refresh. When submitting an event query to monitor a change on a queue or link instance, the submitted query uses the WITHIN statement to tell WMI to perform a polling. Because the ExchangeQueue2Provider updates its queue and link instances on a regular time frame depending on the cache updates, performing a monitoring with a polling frequency in the WQL event query that's inferior to the cache refresh timeout is useless because the provider won't reflect any change within the cache refresh timeout period.
Exchange 2003's new ExchangeQueue2Provider and its set of supported classes let you manage queue- and link-related tasks the same way you manage them through ESM. The ability to duplicate UI operations though programmable interfaces is a great asset when you want to automate the management of a system. In this regard, Exchange 2003 offers some real improvements over its predecessors, as this series has demonstrated.