Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part...

75
Technical Guide [email protected] October 2000 20001008 Prepared by: Alain Lissoir - Technology Consultant Professional Services Division Compaq Computer Corporation Acknowledgments Jerry Cochran (Compaq Computer) Andrew Gent (Compaq Computer) Vlad Joanovic (Microsoft Corporation) Naveen Kachroo (Microsoft Corporation) Jan Kelly (Compaq Computer) Kevin Laahs (Compaq Computer) Travis Muhlestein (Microsoft Corporation) Lev Novik (Microsoft Corporation) Dominic Pouzin (Microsoft Corporation) Tony Redmond (Compaq Computer) Barry Steinglass (Microsoft Corporation) Caroline Takeuchi (Compaq Computer) Patrick Tousignant (Microsoft Corporation) Vladimir Vulovic (Microsoft Corporation) Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Abstract: The purpose of this white paper is to explain some scripting techniques using Windows Script Host (WSH) and Exchange 2000 components. Through the use of examples, the reader will discover the Exchange 2000 COM object hierarchy. During this exploration, the document will focus on the features present in Exchange 2000 to ease the day-to-day management task from the scripting world. The second part of this document presents two advanced WSH scripts based upon the new Exchange 2000 COM technologies. These scripts are able to perform automated management tasks in a real Windows 2000/Exchange 2000 environment.

Transcript of Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part...

Page 1: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Technical Guide

[email protected]

October 2000 20001008 Prepared by:

Alain Lissoir - Technology Consultant

Professional Services Division Compaq Computer Corporation

Acknowledgments Jerry Cochran (Compaq Computer) Andrew Gent (Compaq Computer) Vlad Joanovic (Microsoft Corporation) Naveen Kachroo (Microsoft Corporation) Jan Kelly (Compaq Computer) Kevin Laahs (Compaq Computer) Travis Muhlestein (Microsoft Corporation) Lev Novik (Microsoft Corporation) Dominic Pouzin (Microsoft Corporation) Tony Redmond (Compaq Computer) Barry Steinglass (Microsoft Corporation) Caroline Takeuchi (Compaq Computer) Patrick Tousignant (Microsoft Corporation) Vladimir Vulovic (Microsoft Corporation)

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Abstract:

The purpose of this white paper is to explain some scripting techniques using Windows Script Host (WSH) and Exchange 2000 components. Through the use of examples, the reader will discover the Exchange 2000 COM object hierarchy. During this exploration, the document will focus on the features present in Exchange 2000 to ease the day-to-day management task from the scripting world.

The second part of this document presents two advanced WSH scripts based upon the new Exchange 2000 COM technologies. These scripts are able to perform automated management tasks in a real Windows 2000/Exchange 2000 environment.

Page 2: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 2

20001008

Notice The information in this publication is subject to change without notice and is provided “AS IS” WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK ARISING OUT OF THE USE OF THIS INFORMATION REMAINS WITH RECIPIENT. IN NO EVENT SHALL COMPAQ BE LIABLE FOR ANY DIRECT, CONSEQUENTIAL, INCIDENTAL, SPECIAL, PUNITIVE, OR OTHER DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, OR LOSS OF BUSINESS INFORMATION), EVEN IF COMPAQ HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

The limited warranties for Compaq products are exclusively set forth in the documentation accompanying such products. Nothing herein should be construed as constituting a further or additional warranty.

This publication does not constitute an endorsement of the product or products that were tested. The configuration or configurations tested or described may or may not be the only available solution. This test is not a determination of product quality or correctness, nor does it ensure compliance with any federal, state or local requirements.

Compaq, Compaq Insight Manager, Deskpro, FASTART, NetFlex, NonStop, PaqFax, Proliant, Prosignia, QuickFind, Qvision, RomPaq, SmartStart, and Systempro/LT are registered with the United States Patent and Trademark Office.

ActiveAnswers is a trademark and/or service mark of Compaq Information Technologies Group, L.P.

Microsoft, Windows and Windows NT are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries.

Intel, Pentium and Pentium® III Xeon are trademarks and/or registered trademarks of Intel Corporation.

Other product names mentioned herein may be trademarks and/or registered trademarks of their respective companies.

©2000 Compaq Computer Corporation. All rights reserved. Printed in the U.S.A.

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide prepared by Alain Lissoir - Professional Services Division

First Edition (October 2000)

Document Number 20001008

Page 3: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 3

20001008

Dedication To the memory of my dad

Page 4: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 4

20001008

Table of contents INTRODUCTION ................................................................................................................................10

PREREQUISITES................................................................................................................................11

WINDOWS 2000 COMPONENTS USABLE FROM THE SCRIPTING WORLD ......................12 ACTIVE DIRECTORY SERVICE INTERFACES (ADSI) .............................................................................12 WINDOWS MANAGEMENT INSTRUMENTATION (WMI)........................................................................12 ACTIVEX DATA OBJECTS (ADO)........................................................................................................12

EXCHANGE 2000 COMPONENTS USABLE FROM THE SCRIPTING WORLD....................13 ACTIVE DIRECTORY (AD) SCHEMA.....................................................................................................13 EXCHANGE WMI PROVIDERS (WMI)..................................................................................................13 CDO FOR EXCHANGE 2000 (CDOEX)................................................................................................13 CDO FOR EXCHANGE MANAGEMENT (CDOEXM).............................................................................14 EXCHANGE OLE DB PROVIDER (EXOLEDB) ....................................................................................14 EXCHANGE INSTALLABLE FILE SYSTEM (EXIFS) ................................................................................14

EXCHANGE 2000 ARCHITECTURE OVERVIEW .......................................................................15 WHAT IS THE LINK BETWEEN CDOEX AND ADO? .............................................................................16 WHAT IS THE LINK BETWEEN CDOEXM WITH ADSI AND CDOEX?..................................................16

EXCHANGE 2000 COM COMPONENTS LOGICAL VIEW ........................................................18

EXPLORING THE EXCHANGE 2000 COM LOGICAL VIEW BY SCRIPTS ...........................21 RETRIEVING THE LIST OF EXCHANGE 2000 SERVERS IN THE ENTERPRISE............................................21

Using WMI to retrieve the Exchange 2000 server states ................................................................21 Using ExchangeServerState from WSH .....................................................................................22 Using ExchangeConnectorState from WSH ...............................................................................23 Using ExchangeLink from WSH ................................................................................................23 Using ExchangeQueue from WSH .............................................................................................24 Using ExchangeClusterResource from WSH .............................................................................25

A SCRIPT TO EXPLORE THE EXCHANGE 2000 LOGICAL VIEW...............................................................26 Getting Information about the Exchange Server.............................................................................28

Retrieving more Exchange 2000 Server information with CDOEXM .......................................28 Retrieving Exchange 2000 Storage Group information with CDOEXM....................................30 Retrieving Exchange 2000 Mailbox Store information with CDOEXM ....................................31

Getting Information about Mailboxes.............................................................................................33 Retrieving mailboxes homed in a Mailbox Store with ADSI .....................................................33 Retrieving mailbox-enabled object properties with ADSI..........................................................35 Retrieving the mailbox properties with CDOEXM from ADSI .................................................37 Retrieving mailbox-enabled object properties with CDOEX .....................................................39 Retrieving the mailbox properties with CDOEXM from CDOEX .............................................41 Retrieving the mail-enabled object properties with CDOEXM from ADSI or CDOEX ............42

Getting information about Public Folders.......................................................................................45 Retrieving Exchange 2000 Public Store information with CDOEXM .......................................45 Retrieving the Public Folder Tree properties ..............................................................................47

Getting information about Folder tree in Mailboxes and Public Folders........................................48 Building the Web Store path to explore the content of a Folder in a Mailbox............................48 Building the Web Store pointer to explore the Folders content in a Public Folder hierarchy.....50 Exploring the Folders content .....................................................................................................51

Performing Simple Exchange Management tasks with Scripts ......................................................54 Creating a folder and enabling its E-mail address ......................................................................55 Examining message content........................................................................................................56

Going deeper into the Exchange 2000 CDOEX COM objects hierarchy .......................................58 Exploration Output result................................................................................................................59

Page 5: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 5

20001008

Formatting the collected data..........................................................................................................62 CONCLUSION .....................................................................................................................................64

APPENDIX............................................................................................................................................65 AN OVERVIEW OF THE EXCHANGE 2000 WMI PROVIDERS .................................................................65

Exchange 2000 WMI Routing Table Provider ...............................................................................65 The ExchangeServerState class ..................................................................................................66 The ExchangeConnectorState class ............................................................................................68

Exchange 2000 WMI Queue Provider ............................................................................................69 Exchange 2000 WMI Cluster Provider...........................................................................................72

ADSI FUNCTIONS HELPER...................................................................................................................73 Getting the Exchange Organization Name......................................................................................73 Querying the Active Directory with ADSI and ADO.....................................................................74

Page 6: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 6

20001008

Table of Samples Sample 1 Using the ExchangeServerState WMI class............................................................................22 Sample 2 Using the ExchangeConnectorState WMI class .....................................................................23 Sample 3 Using the ExchangeLink WMI class.......................................................................................23 Sample 4 Using the ExchangeQueue WMI class....................................................................................24 Sample 5 Using the ExchangeClusterResource WMI class....................................................................25 Sample 6 The basic foundation to drill-down the object hierarchy ........................................................26 Sample 7 Getting more Exchange 2000 server information with CDOEXM.........................................28 Sample 8 Retrieving Storage Group information with CDOEXM .........................................................30 Sample 9 Retrieving Mailbox Store information with CDOEXM..........................................................32 Sample 10 Retrieving the mailbox homed on a Mailbox Store and the associated mailbox-enabled

object properties from ADSI...........................................................................................................35 Sample 11 Retrieving the mailbox properties with CDOEXM from ADSI............................................37 Sample 12 Retrieving the mailbox homed on a Mailbox Store and the associated mailbox-enabled

object properties from CDOEX ......................................................................................................39 Sample 13 Retrieving the mailbox properties with CDOEXM from CDOEX .......................................41 Sample 14 Creating a mail-enabled object with CDOEXM from ADSI ................................................43 Sample 15 Creating a mail-enabled object with CDOEXM from CDOEX............................................44 Sample 16 Retrieving Public Store information with CDOEXM...........................................................45 Sample 17 Retrieving the Public Folder Tree properties ........................................................................47 Sample 18 Building the Web Store pointer to explore the Folders content in a mailbox via ADSI .......49 Sample 19 Building the Web Store pointer to explore the Folders content in a mailbox via CDOEX...50 Sample 20 Building the Web Store pointer to explore the Folders content in a Public Folder hierarchy

........................................................................................................................................................51 Sample 21 Exploring the Folders content ...............................................................................................53 Sample 22 Enabling E-mail on a Folder located in a Public Store .........................................................55 Sample 23 Examining mail message content..........................................................................................56 Sample 24 Enumerating the Fields collection and formatting the collected data ...................................62 Sample 25 Retrieving the Exchange Organization name........................................................................73 Sample 26 Searching in the Active Directory.........................................................................................74

Page 7: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 7

20001008

Table of Figures Figure 1: Exchange 2000 Web Store COM interfaces............................................................................15 Figure 2: Windows 2000 Active Directory COM interfaces ..................................................................17 Figure 3: Symbols used to represent Exchange 2000 COM objects hierarchy .......................................18 Figure 4: Exploring the Exchange 2000 COM Architecture ..................................................................19 Figure 5: The Web Store file system ......................................................................................................49 Figure 6: Exchange 2000 ESM Window ................................................................................................59 Figure 7: The "EnumE2KInXL" Sample output.....................................................................................60 Figure 8: Exchange 2000 WMI Providers ..............................................................................................65 Figure 9: Exchange System Manager configuration settings for monitoring .........................................66 Figure 10: Exchange System Manager configuration settings for CPU monitoring...............................67 Figure 11: The ESM Status view............................................................................................................67 Figure 12: The IncreasingTime property behavior from the ExchangeLink and ExchangeQueue classes

........................................................................................................................................................69

Page 8: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 8

20001008

Table of tables Table 1 The CDOEXM object for the Exchange 2000 Server................................................................29 Table 2 The CDOEXM.StorageGroup object.........................................................................................31 Table 3 The CDOEXM object for the Mailbox Store.............................................................................32 Table 4 The CDOEXM Interface for Mailbox management ..................................................................38 Table 5 The CDOEXM interface for Mail-Enabled recipients management..........................................42 Table 6 The CDOEXM object to manage the Exchange Public Store....................................................46 Table 7 The CDOEXM object to manage Exchange Folder Trees.........................................................47 Table 8 The ExchangeServerState WMI Class.......................................................................................68 Table 9 The ExchangeConnectorState WMI class .................................................................................69 Table 10 The ExchangeLink WMI class.................................................................................................71 Table 11 The ExchangeQueue WMI class..............................................................................................72 Table 12 The ExchangeClusterResource WMI class .............................................................................72

Page 9: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 9

20001008

Table of Management points Management Point 1 Retrieving server information from WMI and CDOEXM....................................30 Management Point 2 Retrieving Storage Group information with CDOEXM .......................................31 Management Point 3 Retrieving Mailbox Store information with CDOEXM .......................................33 Management Point 4 Retrieving the homed mailboxes in a Mailbox Store with ADO/ADSI................34 Management Point 5 Retrieving mailbox-enabled object properties with ADSI....................................37 Management Point 6 Retrieving the mailbox properties with CDOEXM from ADSI ...........................38 Management Point 7 Retrieving mailbox-enabled object properties with CDOEX ...............................41 Management Point 8 Retrieving the mailbox properties with CDOEXM from CDOEX.......................42 Management Point 9 Retrieving the mail-enabled object properties with CDOEXM from ADSI or

CDOEX ..........................................................................................................................................45 Management Point 10 Retrieving Exchange 2000 Public Store information with CDOEXM ...............47 Management Point 11 Retrieving the Public Folder Tree properties with CDOEXM............................48 Management Point 12 The Folder tree exploration ................................................................................54 Management Point 13 Enabling e-mail on a Folder ...............................................................................56 Management Point 14 The message object.............................................................................................58

Page 10: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 10

20001008

Introduction Managing systems has always been an important task to guarantee system availability. In the early stages, managing a system consisted of some very simple tasks such as taking a backup, watching the free disk space and ensuring system availability. First networked PCs were running 10 or 20 users on a local LAN at 1 megabit per seconds and one administrator was able to manage it easily. With the evolution of the technology and the market demand, administrators are facing more and more complicated day-to-day tasks. Current systems must be up and running 24 hours a day, 365 days a year. With the growth of the Internet and e-commerce, administrators are now responsible for thousands of users distributed on different systems around the world. This evolution demands that the modern network operating systems offer more and more features to address these needs. Email has contributed to the popularity of the Internet and today it would be extremely unusual to find a company that does not have their email system connected to the external world. With the popularity of Exchange, the administrator faces some new administration challenges. Microsoft, with the latest version of Exchange, has addressed some of these needs but large infrastructures continue to ask that more and more functions be available. Administrators are doing the biggest part of their administration with automated tasks. An administrator is not a developer, so the method used to automate the administration must be easy. That’s why the scripting capabilities of a product are important because scripting is a quick way to write logic with easy to use, yet powerful, languages (JavaScript, VBScript or Perl). To reach this goal, it means that the network operating system structures must be accessible from the scripting environment. With the release of Windows 2000 and Exchange 2000, Microsoft has made serious efforts to provide an enormous set of new features usable from the scripting world. This new set of features gives the administrators the capability to use, create and extend the basic management functions included in the products. The access to these functions is made via scriptable COM objects usable from any automation language.

The purpose of this document is to illustrate how the available technologies in Exchange 2000 can be helpful for management purposes. The document will examine the existing scriptable COM technologies and provide server-centric samples developed under Windows Scripting Host (WSH). The reader will discover with some samples how he can take advantage of these technologies to ease his Exchange 2000 day-to-day management tasks.

Page 11: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 11

20001008

Prerequisites The reader must have an understanding of the following technologies:

• Windows 2000 global architecture • Active Directory • Exchange 2000 global architecture • VBScript or JavaScript especially from the Windows Scripting Host (WSH)

environment • Active Directory Service Interfaces (ADSI) • Windows Management Instrumentation (WMI) • ActiveX Data Objects (ADO)

Page 12: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 12

20001008

Windows 2000 components usable from the scripting world

Exchange 2000 is tightly integrated with Windows 2000. A Windows 2000 network is the foundation for Exchange 2000. It is important to understand which components of Windows 2000 are involved with Exchange 2000. The Windows 2000 Active Directory, Windows Management Instrumentation and Internet Information Server are some examples of Windows 2000 components used by Exchange 2000. From Windows 2000, three important COM technologies are essential for Exchange 2000 management:

Active Directory Service Interfaces (ADSI) ADSI is a COM scriptable technology that is part of Windows 2000 Professional and Windows 2000 Server. ADSI enables applications to access, create and modify Active Directory Objects. ADSI is an API into the Active Directory. For instance, ADSI allows an administrator to write a script to create users in bulk in the Active Directory. Managing Exchange 2000 will likely require the use of ADSI because Active Directory is the underlying directory for Exchange 2000. For more information about ADSI, see http://msdn.microsoft.com/library/psdk/adsi/adsistartpage_7wrp.htm

Note: The reader may refer to the Compaq Active Answer web site for other publications about ADSI (from the same author):

http://www.compaq.com/ActiveAnswers

“Part 1 - Understanding Microsoft WSH and ADSI in Windows 2000”

“Part 2 - The powerful combination of WSH and ADSI under Windows 2000”

Windows Management Instrumentation (WMI) WMI is the Microsoft implementation of Web Based Enterprise Management (WBEM). WMI provides a uniform way of accessing information on windows systems. WMI enables systems, applications, networks and other managed components to be represented using the Common Information Model (CIM). Because Exchange 2000 exposes management information through WMI, and because Exchange 2000 relies on the base features available in Windows 2000, WMI is a great way to manage some server components (CPU usage per process, disk space, available memory, Exchange connector state, queue information, Exchange server state, Exchange services, Store file sizes, etc). WMI offers COM scriptable interfaces and ease the management information access. For more information about WMI and its architecture, see http://msdn.microsoft.com/library/psdk/wmisdk/wmistart_5kth.htm

ActiveX Data Objects (ADO) ADO enables client applications to access and manipulate data from a database server through an OLE DB provider. Under Exchange 5.5, the Information Store is not accessible with ADO because Exchange 5.5 does not have an OLE DB provider. Exchange 2000 implements an OLE DB provider for the Web Store enabling access to information via ADO 2.5. For more information about ADO and its architecture, see http://msdn.microsoft.com/library/psdk/dasdk/ados4piv.htm

Page 13: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 13

20001008

Exchange 2000 components usable from the scripting world

During Exchange 2000 installation, features are added to or modified in the Windows 2000 base operating system. Some of these changes are dedicated to Exchange 2000 management.

Active Directory (AD) Schema The first Exchange 2000 installation in the Forest creates a set of new classes and properties in the Active Directory to support Exchange 2000 specific objects. This change is realized at the enterprise level. Once the schema is modified, the Exchange 2000 installation process will create a specific container in the Active Directory Configuration Naming context to hold the configuration data of the Exchange organization. For more information about Active Directory and Active Directory schema, see http://msdn.microsoft.com/library/psdk/adsi/glns2(1)_5kit.htm

Exchange WMI Providers (WMI) During the Exchange 2000 installation, three WMI providers specific to Exchange 2000 are added to enhance Exchange manageability. These providers create a new namespace in the WMI CIM repository and add five new WMI classes. Each class is related to a different part of Exchange 2000. The WMI ExchangeRoutingTable provider creates the ExchangeServerState and ExchangeConnectorState classes. The WMI ExchangeQueue provider creates the ExchangeLink and the ExchangeQueue classes. The WMI ExchangeCluster provider creates the ExchangeClusterResource class.

For more information about the WMI Exchange Providers, see APPENDIX on page 65 “An overview of the Exchange 2000 WMI Providers”.

CDO for Exchange 2000 (CDOEX) CDO for Exchange 2000 is a new version of CDO built from the ground up to use specific features related to Exchange 2000 such as Internet Standards and the Web Store (through the Exchange OLE DB provider). CDO for Exchange 2000 relies only on the use of Internet standards protocols and does not use MAPI. During Exchange 2000 installation, CDO for Windows 2000 (CDOSYS) is upgraded to CDO for Exchange 2000. CDO for Exchange 2000 is a superset of CDO for Windows 2000. The difference is that CDO for Exchange 2000 brings additional functionality related to Exchange 2000. For more background information about CDO for Windows 2000 and CDO for Exchange 2000, refer to http://msdn.microsoft.com/library/techart/cdo_roadmap.htm

Page 14: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 14

20001008

CDO for Exchange Management (CDOEXM) CDO for Exchange Management provides objects and interfaces for the management of many Exchange 2000 components. For instance, CDOEXM can configure Exchange Servers and stores, mount and dismount stores and create and configure mailboxes. This document will examine everything possible through CDOEXM. CDOEXM acts as an extension for ADSI and CDOEX to ease the creation of and access to mailbox definitions stored in the Active Directory and in the stores. At the server level, CDOEXM allows retrieval of specific information about the server itself, as well as Storage Groups present in the server and stores created in the Storage Groups. CDOEXM is an important companion to ADSI and CDOEX when working with Exchange 2000. For more information about CDO for Exchange 2000 management, see further reading.

Exchange OLE DB Provider (ExOLEDB) OLE DB is a set of interfaces that allow applications to uniformly access data stored in diverse information sources. These interfaces support the amount of DBMS functionality appropriate to the data source, enabling it to share its data.

Exchange 2000 supports the OLE DB for Documents interface (2.5). OLE DB for Documents is a collection of OLE DB interfaces that allows the traversal of folders and documents as well as reference, via URL, individual rows, each of which may have distinct schema from other rows in the same rowset. The OLE DB for Documents interface is the preferred access method for applications to access the Exchange 2000 Web Store

There are two ways in which Exchange 2000 provides OLE DB support. The first way is by leveraging the OLE DB Provider for Internet Publishing (also known as the Internet Publishing Provider) that is remoted over HTTP-DAV to an Exchange 2000 server.

The second way in which Exchange 2000 provides OLE DB 2.5 support is by having a native OLE DB 2.5 provider for the Web Store. The primary purpose of this provider is to achieve better performance than the OLE DB over HTTP-DAV provider. This provider will be able to access the Exchange Web Store directly (via COM) rather than making a round trip through HTTP-DAV. Office 2000, CDO for Exchange 2000 and CDO for Exchange Management will use the OLE DB COM provider. For more information about the Exchange OLE DB provider for Exchange 2000 and the Web Store, see http://msdn.microsoft.com/library/psdk/exchsv2k/_exch2k_web_storage_system.htm.

Exchange Installable File System (ExIFS) The Web Store is accessible using the file system via the Exchange Installable File System (ExIFS). The Web Store exists as a file system folder mounted. By default, under the M: drive of the Exchange 2000 sever. The M: drive can be shared just as any other drive.

When viewed via the Windows Explorer you can see default folder names for the first Public and Mailbox Stores – namely are “Public Folders” and “MBX”. When using the file-system access, no COM abstraction mechanism is available to access properties for an item. Only the access to each item's stream is accessible and no parsing of item content is made. To access item properties with a COM abstraction technique, an alternate mechanism must be used, such as the HTTP-DAV protocol, the Web Store OLE DB provider (ExOLEDB) with ADO 2.5, CDO for Exchange 2000 (CDOEX) or the Messaging API (MAPI). For more information about the Exchange 2000 File System, see http://msdn.microsoft.com/library/psdk/exchsv2k/_exch2k_web_storage_system.htm.

Page 15: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 15

20001008

Exchange 2000 Architecture overview Exchange 2000 offers many different technologies to access its components. Figure 1 below represents a simplified view of the interaction and relationships between the COM technologies present.

Figure 1: Exchange 2000 Web Store COM interfaces

From an application point of view, the Exchange 2000 Store can be accessed via CDO 1.21 and MAPI. This method is the backward compatibility access method. With Exchange 2000, the new client access method to items in the store is based on HTTP-DAV via IIS. This access method is based on Internet standard protocols as opposed to MAPI, which uses RPC. These two methods represent the client-server access to the store and are the only valid remote access methods to the store. HTTP-DAV is the recommended method.

Note: Figure 1 does not represent the WMI components because there is no direct interaction between WMI and the store with Exchange 2000. See APPENDIX on page 65 for more information about the Exchange 2000 WMI providers.

Note: In the same way, the ExIFS is not represented on the figure because it is seen as a file system component part of the Exchange 2000 Web Store and not as a COM component part of the Exchange 2000 object model.

If the application is running locally on the Exchange 2000 Server, the store can also be accessed through the Exchange OLE DB Provider. Another way of accessing the store via the Exchange OLE DB provider is to use ADO 2.5. With the help of the Exchange OLE DB Provider, ADO 2.5 offers a navigation model allowing the store’s exploration. This is the easiest COM technology to use to explore mailboxes and Public Folder hierarchies. ADO 2.5 implements new features such as:

Page 16: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 16

20001008

• The GetChildren method to return a RecordSet of items in a Folder (See Sample 21 on page 53).

• The MoveRecord and CopyRecord methods to allow prune and graft operations in a Folder tree.

ADO 2.5 does not allow a direct content examination of an item. CDOEX implements the business logic of the collaboration-related items contained in the Store such as emails, folders, calendaring items, contacts, etc. ADO and CDOEX are designed to work together, one for the navigation through the folders hierarchy, the other one to manipulate the item content. On top of CDOEX, Exchange 2000 implements another layer called CDOEXM. CDOEXM is a COM technology to ease the management tasks of Exchange 2000. CDOEXM is a technology helper handling operations between the Store and the Active Directory based on objects instantiated with ADSI or CDOEX. It is very important to clearly distinguish the purpose of CDOEXM from the purpose of CDOEX. CDOEXM is made for the management of Exchange 2000 (i.e. Store properties, mounting and dismounting stores, mailbox- and mail-enabled recipient’s properties, mailbox- and mail-enabled recipient creation or deletion, etc), CDOEX is for manipulating item content in the store (i.e. messages, contacts, calendar, notes, etc). In short, CDOEXM manages the component containers (Servers, Stores, Mailboxes) and CDOEX manipulates the content of these containers. The Admin Logic Layer is not accessible from the application level. It implements business logic related to the administration so that both CDOEXM and the ESM user interface exhibit consistent behavior.

What is the link between CDOEX and ADO? CDOEX provides a convenient object model for managing folders, messages, appointments, contacts, and other items as well as the properties about those items. CDOEX is specifically designed to operate against the Web Store. It leverages the OLE DB 2.5 interfaces for accessing data in the Web Store. CDOEX integrates with ADO 2.5 to provide a consistent data-access interface to the Web Store and the Active Directory. When assigning values to CDOEX properties, CDOEX saves the data to the correct locations whether it's the Web Store or the Active Directory. Some CDOEX objects (such as Folders, Person, and many others) provide a Fields collection on the default interface, allowing access to the Web Store item’s properties directly. Please refer to the Exchange 2000 SDK for more information about objects supporting the Fields collection. The CDOEX properties provide essential functionality for collaborative applications using the Web Store. There are situations, however, when using ADO (See Sample 21 on page 53) or OLE DB may be more appropriate. When an item is accessed using an ADO Record object, all of the data, including the stream, is presented in a Fields collection. The stream, which has a special semantic definition within the ADO 2.5 specification, is accessed using the ADO Stream object from the GetStream method or from within the Fields collection (See Sample 6 on page 26 and its related parts to explore the content of the Store and associated Fields collection). However, ADO assumes no correlation between the properties for the item, and the default stream.

What is the link between CDOEXM with ADSI and CDOEX?

CDOEX and ADSI objects are designed to work in tandem. You can use CDOEX and/or ADSI objects to retrieve users information and their associated Exchange 2000 mailboxes (See Sample 11 on page 37 with ADSI and Sample 13 on page 41 with CDOEX).

Page 17: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 17

20001008

Like a script retrieves information about users and Exchange 2000 mailboxes, the same logic can be used to create or delete users and their associated Exchange 2000 mailboxes. It is also possible to manage user and contact information in Active Directory using the principle.

Figure 2: Windows 2000 Active Directory COM interfaces

Configuration information primarily resides in the Active Directory. ADSI is a generic API into the Active Directory that has no functions specifically for managing the Exchange data in the Active Directory. ADSI cannot access data in the Web Store. CDOEXM encapsulates and simplifies Exchange 2000 management tasks so that data in the Active Directory and resources in the Web Store are managed as needed. CDOEXM relies also on the Admin Logic Layer containing business logic for Exchange 2000 management. In most cases, there is no need to work at the granular level of the Active Directory using ADSI except if CDOEXM does not implement logic for a particular management task. In the same way, CDOEX has no specific function for managing the Active Directory and the Exchange data in the Active Directory. CDOEX makes usage of ADSI and CDOEXM to perform tasks in both the Active Directory and the Web Store. To be sure, ADSI is still useful. For instance, to create (or retrieve information from) a user with his associated mailbox in an Exchange 2000 server, an ADSI.User object must be first instantiated to create (or bind to) the user in the Active Directory. Next, the piece of code must switch to CDOEXM to create (or retrieve) the user’s mailbox in the store (See Sample 10 on page 35 and Sample 11 on page 37). With CDOEX, the logic is exactly the same (See Sample 12 on page 39 and Sample 13 on page 41) but in this case a CDO.Person object is instantiated.

When CDOEXM creates the mailbox (or retrieves the mailbox information), it automatically sets (or gets) the properties in the Web Store to associate the Exchange mailbox to the user in the Active Directory. CDOEXM acts as an extension to ADSI and CDOEX.

Page 18: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 18

20001008

Exchange 2000 COM components logical view To manage Exchange 2000 by script, the script code will use various COM technologies. The COM technology to use will be determined by the component to manage and the information to retrieve. An easy way to look at Exchange 2000 is to compare it to a Russian doll. In a Russian doll, when you open the first doll, you find another doll inside. If you open the second one, you find another one and so on. With Exchange 2000, we can use the same kind of approach. When an administrator looks at Exchange 2000 from a logical point of view, he looks at the server first. But if he explores the Exchange 2000 server, the administrator will find different Storage Groups. Inside each Storage Group, he will find different kinds of Stores (Mailbox or Public). Next, if he looks at the Mailbox Store, he will find mailboxes located in this Mailbox Store. Inside a Mailbox, the administrator will discover some folders. Inside a Public Store, he will also find some Folders. Inside Folders, depending on if they are in a Public or a Mailbox Store, he may find different kind of objects, such as documents, schedule information, application data, messages, etc. Finally, if he looks at the message content, the administrator will find different parts such as the body text, the attachments and so on. Exchange 2000 implements a specific technology to access each level of detail. To manage Exchange 2000 from scripts, it is important to understand which COM technology to use to access each specific kind of data. To help in this task, a logical view of Exchange 2000 will be helpful. Figure 3 below presents each Exchange 2000 component used in the logical view on Figure 4 on page 19.

Figure 3: Symbols used to represent Exchange 2000 COM objects hierarchy

Each icon represents a manageable Exchange 2000 component. If we combine each of these with respect to the Exchange 2000 object hierarchy we obtain the Figure 4 on page 19.

Page 19: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 19

20001008

An Exchange 2000 server may contain several Storage Groups. To ease this representation, we symbolize only 1 Storage Group. In the same way, Storage Groups may contain many mailbox stores and many Public Folder hierarchies but to ease the representation, only 1 Mailbox Store and 1 Public Folder hierarchy is represented. On the left and right sides, the arrows represent the path used to explore the Exchange 2000 objects hierarchy from the Enterprise level down to the message level. The two paths are mostly the same but we will see that there are some few differences related to the mailbox access method (ADSI with steps marked with numbers versus CDOEX with steps marked with letters). This is why there is an arrow on each side. Both arrows represent a different access method. At each step, the figure shows which technology is used to access the Exchange 2000 component (i.e. WMI, CDOEX, ADSI, …). This information will be retrieved from each COM component available for each level of this logical view. A script named “EnumE2KinXL.Wsf” will be presented piece-by-piece in this document to correspond to each level. Each level is marked by a letter or a number encircled on the Figure 4 below and will correspond to the scripts Sample 6 (on page 26) to Sample 24 (on page 62) which constitute the complete “EnumE2KinXL.Wsf” script.

Figure 4: Exploring the Exchange 2000 COM Architecture

Page 20: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 20

20001008

The script sample pieces are presented in the section “Exploring the Exchange 2000 COM logical view by scripts" on page 21. This section explores the Exchange 2000 objects hierarchy. Each sample piece in this section will point to the Figure 4 by referencing the corresponding letter or number for each step. This will give a good understanding of the existing COM technologies and their interactions.

Each time a COM object offers some Exchange 2000 management capabilities, it will be mentioned and the possible actions listed.

Management Point 1

This summary will be presented in the document as a management point and symbolized by an icon in a frame as shown in this sample.

Page 21: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 21

20001008

Exploring the Exchange 2000 COM logical view by scripts

Retrieving the list of Exchange 2000 servers in the Enterprise Getting the list of Exchange servers present in the organization and retrieving associated information about each is a key feature for administrators. Of course, it is possible to use ADSI to get the list of Exchange servers in the enterprise (i.e. by using an ADSI query in the Active Directory configurationNaming context).

On the other hand, ADSI does not contain business logic related to an Exchange 2000 server. This means that ADSI does not implement a COM abstraction object representing an Exchange 2000 server with its specific characteristics. With ADSI, a script must retrieve the information data related to Exchange 2000 property by property from the Active Directory. The problem is to know which properties to read and how to interpret their values. Another point to note is that ADSI will never provide real-time status or health information about the Exchange 2000 server (i.e. Is the server up or down?). This is the reason why the Figure 4 on page 19 starts to retrieve the Exchange 2000 servers in the Organization with WMI.

Using WMI to retrieve the Exchange 2000 server states

The installation of Exchange 2000 adds three WMI providers to the Windows 2000 WMI infrastructure on each machine:

• The WMI ExchangeRoutingTable provider, which defines the following WMI classes:

o ExchangeServerState: This class has information about the status of the relevant services, the memory used, the processor utilization, the disk space available and the mail queue growth of the Exchange 2000 server itself. This class works in conjunction with the monitoring configuration defined with the Exchange System Manager (ESM).

o ExchangeConnectorState: In the same way as the ExchangeServerState class, this WMI class retrieves information about the status of the Exchange 2000 mail connectors.

Both classes retrieve this information from the Exchange Routing Table. This allows any server in the Enterprise to know the status of all other Exchange 2000 servers. In the same way, by contacting this provider on a specific Exchange 2000 server, an Administrator can have a status of all the Exchange 2000 servers in the Enterprise as they are seen from that server. For more information about the ExchangeRoutingTable provider, see APPENDIX on page 65 “Exchange 2000 WMI Routing Table Provider”.

• The WMI ExchangeQueue provider, which defines the following WMI classes:

o ExchangeQueue: This class retrieves information through the queue API about the existing queues on an Exchange 2000 server.

o ExchangeLink: This class retrieves information through the queue API about the existing links on an Exchange 2000 server.

For more information about the ExchangeQueue provider, see APPENDIX on page 69 ”Exchange 2000 WMI Queue Provider”.

• The WMI ExchangeCluster provider, which defines the following WMI class:

1 A

Page 22: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 22

20001008

o ExchangeClusterResource: This class retrieves information through the cluster API about the status of Exchange 2000 clustered resources.

For more information about the ExchangeClusterResource provider, see APPENDIX on page 72 ”Exchange 2000 WMI Cluster Provider”.

The next script samples show how to use these three WMI providers from WSH. The first sample using the ExchangeServerState WMI class will be re-used later as a basis of a more complex script (See “EnumE2KinXL.Wsf” sample on page 26).

Using ExchangeServerState from WSH Sample 1 below shows how the ExchangeServerState WMI provider can be used from WSH. Lines 11 to 13 define three constants to be used in the WMI moniker (Lines 24 to 26). The cComputerName constant is the Exchange 2000 server name to contact. The cWMINameSpace is defined as the Exchange 2000 WMI namespace. When the Exchange 2000 setup program installs the WMI provider classes in the WMI CIM repository, it creates this dedicated namespace for these 5 classes. Next, the constant cWMIinstance provides the class name to be instantiated at lines 24 to 26, in this case: the ExchangeServerState class. Sample 1 Using the ExchangeServerState WMI class

1:' VB Script listing all the ExchangeServerState names & properties available with '2:' the WMI Exchange 2000 provider 'ExchangeServerState' '3:' '4:' Version 1.00 - Alain Lissoir '5:' Compaq Computer Corporation - Professional Services - Belgium - '6:' '7:' Any comments or questions: EMail:[email protected] '8:9:Option Explicit10:11:Const cComputerName = "LocalHost"12:Const cWMINameSpace = "root/cimv2/applications/exchange"13:Const cWMIInstance = "ExchangeServerState"..:..:24:Set ExchangeServerList = GetObject("winmgmts:{impersonationLevel=impersonate}!//" & _25: cComputerName & "/" & _26: cWMINameSpace).InstancesOf(cWMIInstance)27:28:For each ExchangeServer in ExchangeServerList29: WScript.Echo "---------------------------------------------"30: WScript.Echo "Name: " & ExchangeServer.Name31: WScript.Echo "DN: " & ExchangeServer.Dn32: WScript.Echo "GUID: " & ExchangeServer.Guid33: WScript.Echo "Version: " & ExchangeServer.Version34: WScript.Echo "GroupDN: " & ExchangeServer.GroupDN35: WScript.Echo "Unreachable: " & ExchangeServer.Unreachable36:37: WScript.Echo "ServerMaintenance: " & ExchangeServer.ServerMaintenance38:39: WScript.Echo "ServerStateString: " & ExchangeServer.ServerStateString40: WScript.Echo "ServerState: " & ExchangeServer.ServerState41:42: WScript.Echo "QueuesStateString: " & ExchangeServer.QueuesStateString43: WScript.Echo "QueuesState: " & ExchangeServer.QueuesState44:45: WScript.Echo "DisksStateString: " & ExchangeServer.DisksStateString46: WScript.Echo "DisksState: " & ExchangeServer.DisksState47:48: WScript.Echo "MemoryStateString: " & ExchangeServer.MemoryStateString49: WScript.Echo "MemoryState: " & ExchangeServer.MemoryState50:51: WScript.Echo "CPUStateString: " & ExchangeServer.CPUStateString52: WScript.Echo "CPUState: " & ExchangeServer.CPUState53:54: WScript.Echo "ClusterStateString: " & ExchangeServer.ClusterStateString55: WScript.Echo "ClusterState: " & ExchangeServer.ClusterState56:57: WScript.Echo "ServicesStateString: " & ExchangeServer.ServicesStateString

Page 23: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 23

20001008

58: WScript.Echo "ServicesState: " & ExchangeServer.ServicesState59:Next..:..:..:

Once the instantiation is completed, the returned object is a collection of Exchange servers, stored in cComputerName. The “For Each” loop (lines 28 to 59) enumerates all the servers in this collection.

For each server found, a set of properties with its associated status is retrieved from the Exchange 2000 routing table (Lines 30 to 58) with the help of the WMI Provider. The routing table includes data containing the status of all the servers and connectors in the Enterprise. The ExchangeServerState class is reading this data.

Using ExchangeConnectorState from WSH The logic is the same as Sample 1. Only the class to be instantiated is different. Line 13 is changed to use the ExchangeConnectorState class name. This script will list all the ExchangeConnectorState objects visible from the server in cComputerName. So, this script gives an enterprise view of all the connectors with their status, as seen by the cComputerName used to instantiate the class. Sample 2 Using the ExchangeConnectorState WMI class

1:' VB Script listing all the ExchangeConnectorState names & properties available with '2:' the WMI Exchange 2000 provider 'ExchangeConnectorState' '3:' '4:' Version 1.00 - Alain Lissoir '5:' Compaq Computer Corporation - Professional Services - Belgium - '6:' '7:' Any comments or questions: EMail:[email protected] '8:9:Option Explicit10:11:Const cComputerName = "LocalHost"12:Const cWMINameSpace = "root/cimv2/applications/exchange"13:Const cWMIInstance = "ExchangeConnectorState"..:..:24:Set ExchangeConnectorList = GetObject("winmgmts:{impersonationLevel=impersonate}!//" &_25: cComputerName & "/" & _26: cWMINameSpace).InstancesOf(cWMIInstance)27:28:For each ExchangeConnector in ExchangeConnectorList29: WScript.Echo "---------------------------------------------"30: WScript.Echo "DN: " & ExchangeConnector.Dn31: WScript.Echo "Name: " & ExchangeConnector.Name32: WScript.Echo "GUID: " & ExchangeConnector.Guid33: WScript.Echo "GroupDN: " & ExchangeConnector.GroupDN34: WScript.Echo "IsUP: " & ExchangeConnector.IsUP35:Next..:..:..:

Using ExchangeLink from WSH The logic is the same as Sample 2. Line 13 instantiates the ExchangeLink class. Instances of this class represent the links (the objects under the queues container in ESM) that exist on the specified cComputerName (line 11) only. This WMI class does not work with the routing table and therefore does not offer an enterprise view of the links. Sample 3 Using the ExchangeLink WMI class

1:' VB Script listing all the ExchangeLink names & properties available with '2:' the WMI Exchange 2000 provider 'ExchangeLink' '3:' '4:' Version 1.00 - Alain Lissoir '5:' Compaq Computer Corporation - Professional Services - Belgium - '6:' '

Page 24: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 24

20001008

7:' Any comments or questions: EMail:[email protected] '8:9:Option Explicit10:11:Const cComputerName = "LocalHost"12:Const cWMINameSpace = "/root/cimv2/applications/exchange"13:Const cWMIInstance = "ExchangeLink"..:..:24:Set ExchangeLinkList = GetObject("winmgmts:{impersonationLevel=impersonate}!//" & _25: cComputerName & "/" & _26: cWMINameSpace).InstancesOf(cWMIInstance)27:28:For each ExchangeLink in ExchangeLinkList29: WScript.Echo "---------------------------------------------"30: WScript.Echo "LinkName: " & ExchangeLink.LinkName31: WScript.Echo " ProtocolName: " & ExchangeLink.ProtocolName32: WScript.Echo " VirtualServerName: " & ExchangeLink.VirtualServerName33: WScript.Echo " VirtualMachine: " & ExchangeLink.VirtualMachine34: WScript.Echo " Version: " & ExchangeLink.Version35: WScript.Echo " NumberOfMessages: " & ExchangeLink.NumberOfMessages36: WScript.Echo " NextScheduledConnection: " & ExchangeLink.NextScheduledConnection37: WScript.Echo " OldestMessage: " & ExchangeLink.OldestMessage38: WScript.Echo " SizeOfQueue: " & ExchangeLink.SizeOfQueue39: WScript.Echo " LinkDN: " & ExchangeLink.LinkDN40: WScript.Echo " ExtendedStateInfo: " & ExchangeLink.ExtendedStateInfo41: WScript.Echo " IncreasingTime: " & ExchangeLink.IncreasingTime42: WScript.Echo " StateFlags: 0x" & Hex (ExchangeLink.StateFlags)43: WScript.Echo " StateActive: " & ExchangeLink.StateActive44: WScript.Echo " StateReady: " & ExchangeLink.StateReady45: WScript.Echo " StateRetry: " & ExchangeLink.StateRetry46: WScript.Echo " StateScheduled: " & ExchangeLink.StateScheduled47: WScript.Echo " StateRemote: " & ExchangeLink.StateRemote48: WScript.Echo " StateFrozen: " & ExchangeLink.StateFrozen49: WScript.Echo " TypeRemoteDelivery: " & ExchangeLink.TypeRemoteDelivery50: WScript.Echo " TypeLocalDelivery: " & ExchangeLink.TypeLocalDelivery51: WScript.Echo " TypePendingRouting: " & ExchangeLink.TypePendingRouting52: WScript.Echo " TypePendingCategorization: " & _53: ExchangeLink.TypePendingCategorization54: WScript.Echo " TypeCurrentlyUnreachable: " & ExchangeLink.TypeCurrentlyUnreachable55: WScript.Echo " TypeDeferredDelivery: " & ExchangeLink.TypeDeferredDelivery56: WScript.Echo " TypeInternal: " & ExchangeLink.TypeInternal57: WScript.Echo " SupportedLinkActions: " & ExchangeLink.SupportedLinkActions58: WScript.Echo " ActionKick: " & ExchangeLink.ActionKick59: WScript.Echo " ActionFreeze: " & ExchangeLink.ActionFreeze60: WScript.Echo " ActionThaw: " & ExchangeLink.ActionThaw61:Next..:..:..:

Using ExchangeQueue from WSH Again the logic is the same as Sample 3. The class to be instantiated is the ExchangeQueue at line 13. Note this script retrieves the instances of the queues on the specified cComputerName (line 11) only. The behavior is the same as the ExchangeLink WMI class. Sample 4 Using the ExchangeQueue WMI class

1:' VB Script listing all the ExchangeQueue names & properties available with '2:' the WMI Exchange 2000 provider 'ExchangeQueue' '3:' '4:' Version 1.00 - Alain Lissoir '5:' Compaq Computer Corporation - Professional Services - Belgium - '6:' '7:' Any comments or questions: EMail:[email protected] '8:9:Option Explicit10:11:Const cComputerName = "LocalHost"12:Const cWMINameSpace = "root/cimv2/applications/exchange"13:Const cWMIInstance = "ExchangeQueue"..:..:24:Set ExchangeServerQueueList=GetObject("winmgmts:{impersonationLevel=impersonate}!//"&_

Page 25: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 25

20001008

25: cComputerName & "/" & _26: cWMINameSpace).InstancesOf(cWMIInstance)27:28:For each ExchangeServerQueue in ExchangeServerQueueList29: WScript.Echo "---------------------------------------------"30: WScript.Echo "QueueName: " & ExchangeServerQueue.QueueName31: WScript.Echo " ProtocolName: " & ExchangeServerQueue.ProtocolName32: WScript.Echo " VirtualServerName: " & ExchangeServerQueue.VirtualServerName33: WScript.Echo " QueueName: " & ExchangeServerQueue.QueueName34: WScript.Echo " VirtualMachine: " & ExchangeServerQueue.VirtualMachine35: WScript.Echo " Version: " & ExchangeServerQueue.Version36: WScript.Echo " NumberOfMessages: " & ExchangeServerQueue.NumberOfMessages37: WScript.Echo " SizeOfQueue: " & ExchangeServerQueue.SizeOfQueue38: WScript.Echo " IncreasingTime: " & ExchangeServerQueue.IncreasingTime39: WScript.Echo " MsgEnumFlagsSupported: 0x" & _40: Hex (ExchangeServerQueue.MsgEnumFlagsSupported)41: WScript.Echo " GlobalStop: " & ExchangeServerQueue.GlobalStop42: WScript.Echo " CanEnumFirstNMessages: " & _43: ExchangeServerQueue.CanEnumFirstNMessages44: WScript.Echo " CanEnumSender: " & ExchangeServerQueue.CanEnumSender45: WScript.Echo " CanEnumRecipient: " & ExchangeServerQueue.CanEnumRecipient46: WScript.Echo " CanEnumLargerThan: " & ExchangeServerQueue.CanEnumLargerThan47: WScript.Echo " CanEnumLargerThan: " & ExchangeServerQueue.CanEnumOlderThan48: WScript.Echo " CanEnumFrozen: " & ExchangeServerQueue.CanEnumFrozen49: WScript.Echo " CanEnumNLargestMessages: " & _50: ExchangeServerQueue.CanEnumNLargestMessages51: WScript.Echo " CanEnumNOldestMessages: " & _52: ExchangeServerQueue.CanEnumNOldestMessages53: WScript.Echo " CanEnumFailed: " & ExchangeServerQueue.CanEnumFailed54: WScript.Echo " CanEnumAll: " & ExchangeServerQueue.CanEnumAll55: WScript.Echo " CanEnumInvertSense: " & ExchangeServerQueue.CanEnumInvertSense56:Next..:..:..:

Using ExchangeClusterResource from WSH The ExchangeClusterResource class retrieves the status of a clustered Exchange resource such as a virtual server’s name. Except for this point and the list of properties available from this class the script logic is exactly the same as the previous samples. This WMI class does not work with the routing table and therefore does not offer an enterprise view of the clustered resources. Sample 5 Using the ExchangeClusterResource WMI class

1:' VB Script listing all the ExchangeServerCluster names & properties available '2:' with the WMI Exchange 2000 provider 'ExchangeClusterResource' '3:' '4:' Version 1.00 - Alain Lissoir '5:' Compaq Computer Corporation - Professional Services - Belgium - '6:' '7:' Any comments or questions: EMail:[email protected] '8:9:Option Explicit10:11:Const cComputerName = "LocalHost"12:Const cWMINameSpace = "/root/cimv2/applications/exchange"13:Const cWMIInstance = "ExchangeClusterResource"..:..:24:Set ExchangeServerClusterList = _25: GetObject("winmgmts:{impersonationLevel=impersonate}!//" & _26: cComputerName & "/" & _27: cWMINameSpace).InstancesOf(cWMIInstance)28:29:For each ExchangeServerCluster in ExchangeServerClusterList30: WScript.Echo "---------------------------------------------"31: WScript.Echo "VirtualMachine: " & ExchangeServerCluster.VirtualMachine32: WScript.Echo "Name: " & ExchangeServerCluster.Name33: WScript.Echo "Type: " & ExchangeServerCluster.Type34: WScript.Echo "State: " & ExchangeServerCluster.State35:Next..:

Page 26: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 26

20001008

..:

..:

A script to explore the Exchange 2000 logical view Sample 1 through Sample 5 shows how to access the Exchange 2000 WMI classes. With Sample 1 as a base, it is possible to build a more complex script that will retrieve the complete set of information shown in Figure 4 on page 19.

The script, named “EnumE2KinXL.Wsf”, will exploit all the COM technology available in Exchange 2000 to load the information in an Excel sheet. This script will act as a “browser” or an “explorer” for Exchange 2000.

Each COM technology provides its own set of properties and methods to realize the management of Exchange 2000. This script will illustrate how it is possible to combine the different COM technologies available and how to reuse a set of information retrieved from one COM object type with another COM object type.

This “Exchange 2000 Explorer” will be the base of all subsequent scripts because it will show how to access a specific Exchange 2000 component, what is available from this COM component and how to pass each step as shown in Figure 4 on page 19. This will help to understand how to script Exchange 2000 management. Each step has its corresponding sample (From Sample 7 on page 28 to Sample 24 on page 62). Sample 6 The basic foundation to drill-down the object hierarchy

1:<!-- VB Script loading the complete Exchange 20000 object hierarchy -->2:<!-- into an Excel sheet by using WMI, CDOEXM, ADSI, CDO and ADO -->3:<!-- (with Values of different properties) -->4:<!-- -->5:<!-- Version 1.00 - Alain Lissoir -->6:<!-- Compaq Computer Corporation - Professional Services - Belgium - -->7:<!-- -->8:<!-- Any comments or questions: EMail:[email protected] -->9:10:<job>11: <script language="VBScript" src=".\Functions\GetMSExchangeOrgFunction.vbs" />12:13: ' Here we can use CDOEX or ADSI to enumerate mailbox properties14: <script language="VBScript" _15: src=".\Functions\EnumMailboxStoreFunction (CDOEX).vbs" />16:<!-- <script language="VBScript" _17: src=".\Functions\EnumMailboxStoreFunction (ADSI).vbs" /> -->18:19: <script language="VBScript" _20: src=".\Functions\BrowseStoreFolderFunction (ADO).vbs" />21: <script language="VBScript" _22: src=".\Functions\ADSearchFunction1.vbs" />23: <script language="VBScript" _24: src=".\Functions\EnumMessageContentFunction.vbs" />25: <script language="VBScript" _26: src=".\Functions\EnumFieldsCollectionFunction.vbs" />27:28: <script language="VBScript">29:30: Option Explicit31:32: Const cEnumMaiboxTree = True33: Const cEnumFolderTree = True34: Const cEnumFieldsCollection = False35: Const cEnumMessageContent = False36:37:38: Const cComputerName = "LocalHost"39: Const cWMINameSpace = "/root/cimv2/applications/exchange"40: Const cWMIInstance = "ExchangeServerState"..:..:69: ' -----------------------------------------------------------------------------70: ' By default this script expects to run on the local Exchange server.71: Set WNetwork = Wscript.CreateObject("Wscript.Network")

Page 27: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 27

20001008

72: strCurrentComputerName = WNetwork.ComputerName73: strCurrentUserName = WNetwork.UserName74: Wscript.DisconnectObject (WNetwork)75: Set WNetwork = Nothing76:77: ' -----------------------------------------------------------------------------78: ' Getting the current default domain. (DN and FQDN)79:80: Set objRoot = GetObject("LDAP://RootDSE")81: strDefaultDomainNC = objRoot.Get("DefaultNamingContext")82: Set objRoot = Nothing83:84: ' Bind to the Root Domain to get its canonical name for UPN contruction85: Set objDefaultDomainNC = GetObject("LDAP://" & strDefaultDomainNC)86:87: ' Retrieve a constructed property,88: ' so 1st we do a GetInfoEx (For UPN construction)89: objDefaultDomainNC.GetInfoEx Array("canonicalName"), 090: strCanonicalNameDefaultDomain = objDefaultDomainNC.Get("canonicalName")91:92: Set objDefaultDomainNC = Nothing..:..:97: ' Bind to an Excel worksheet object98: Set objXL = WScript.CreateObject("EXCEL.application")99:100: ' Make it visible101: objXL.Visible = True102:103: ' Open Excel and start an empty workbook104: objXL.workbooks.Add105:106: ' Put the cursor on the A1 cell107: objXL.ActiveSheet.range("A1").Activate...:...:112: ' -----------------------------------------------------------------------------113: ' Start at the higher object level: The Exchange Server itself.114:115: Set objWMIExchangeServers = _116: GetObject("winmgmts:{impersonationLevel=impersonate}!//" & _117: cComputerName & _118: cWMINameSpace).InstancesOf(cWMIInstance)119:120: EnumExchangeServers objWMIExchangeServers121:122: ' Close the Workbook,123: ' this will prompt the user to choose where to save the generated XLS.124: objXL.workbooks.close125: objXL.Quit126: WScript.DisconnectObject objXL127: Set objXL = Nothing128:129: WScript.Quit (0)...:...:...:

Sample 6 must be run on an Exchange 2000 Server with Excel 2000 installed. The usage of Excel 2000 eases the review and the display of the collected data. To minimize the amount of data collected and to get an understanding of what this script is doing it is strongly suggested to run it in an Exchange 2000 test organization. (It can be a single server).

From lines 11 to 26, the script starts with the inclusion of miscellaneous functions. These functions will be explained in the next pages of this document. Each of them has a dedicated purpose related to the COM technology used.

Note: By default the script uses CDOEX to access user information. As explained in section “What is the link between CDOEXM with ADSI and CDOEX?” on page

Page 28: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 28

20001008

16, ADSI can be used instead of CDOEX. This is why lines 16 and 17 are commented out. This eases the switch between CDOEX or ADSI.

From lines 32 to 35, some constants are defined to help control the depth of the exploration. Each of these contains a Boolean value.

• cEnumMaiboxTree: When True, the script will explore the mailbox folder hierarchy. To minimize the amount of data collected and for security reasons, the only mailbox accessed is the mailbox of the currently logged-on user.

• cEnumFolderTree: When True, the script will explore the Public Folder hierarchy. Be careful though, because this will cause the script to explore the complete hierarchy. If you have a large number of public folders this could take a lot of resources. That’s why it is important to run it in a test environment.

• cEnumFieldsCollection: When True, the script will enumerate the CDO Fields collection associated with the CDOEX object. This constant is used in every function retrieving an ADO Fields collection from an object.

• cEnumMessageContent: When cEnumMaiboxTree or cEnumFolderTree are true, if a folder contains messages, then the message properties will be examined. (header, bodyparts, attachment present, etc.)

The Sample 6 (Lines 38 to 40) defines constants already explained in Sample 1 on page 22.

From lines 69 to 92, the script gets some information about the domain name and the computer name. This will be used later by some other functions.

From lines 97 to 107, the script initializes the Excel 2000 COM objects to load the retrieved data in a new Excel sheet.

Now that the basic steps are complete, the script explores the Exchange 2000 server using the different COM technologies.

At lines 115 to 118, the scripts instantiates the ExchangeServerState WMI class. The returned result is a collection of Exchange 2000 servers visible in the Enterprise. This collection is passed to the EnumExchangeServers() function (line 120).

Here starts the real Exchange 2000 COM exploration from the scripting world.

Getting Information about the Exchange Server

To reuse the concept of the Russian doll, when looking in Exchange, the first doll visible is the Exchange server itself with its associated Storage Groups containing Mailbox stores and Public stores. The next section will examine these elements.

Retrieving more Exchange 2000 Server information with CDOEXM In Sample 7 below, lines 140 to 177, the EnumExchangeServers() function uses the WMI information retrieved at line 120 in Sample 6 on page 26. The peculiarity is the way the information is displayed. The function DisplayText() is actually loading the information in the Excel sheet (Lines 140 to 177). The interesting piece of code is where CDOEXM is invoked at lines 137 and 181-209. Sample 7 Getting more Exchange 2000 server information with CDOEXM

...:

...:132: Private Function EnumExchangeServers (objWMIExchangeServers)...:...:137: Set objCDOEXMExchangeServer = CreateObject("CDOEXM.ExchangeServer")

A1

2 B

Page 29: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 29

20001008

138:139: For each objWMIExchangeServer in objWMIExchangeServers140: DisplayText "Name(WMI)", objWMIExchangeServer.Name...:...:176: DisplayText "ServicesState(WMI)", _177: objWMIExchangeServer.ServicesState178:179: ' Switch to CDOEXM to get CDOEXM information180: ' by using the WMI Server Name181: objCDOEXMExchangeServer.DataSource.Open(objWMIExchangeServer.Name)...:...:188: DisplayText "ExchangeVersion(CDOEXM)", _189: objCDOEXMExchangeServer.ExchangeVersion190: DisplayText "SubjectLoggingEnabled(CDOEXM)", _191: objCDOEXMExchangeServer.SubjectLoggingEnabled192: DisplayText "MessageTrackingEnabled(CDOEXM)", _193: objCDOEXMExchangeServer.MessageTrackingEnabled194: DisplayText "DaysBeforeLogFileRemoval(CDOEXM)", _195: objCDOEXMExchangeServer.DaysBeforeLogFileRemoval196: DisplayText "Name(CDOEXM)", objCDOEXMExchangeServer.Name197: DisplayText "ServerType(CDOEXM)", _198: objCDOEXMExchangeServer.ServerType199: DisplayText "DirectoryServer(CDOEXM)", _200: objCDOEXMExchangeServer.DirectoryServer201:202: If cEnumFieldsCollection Then _203: EnumFieldsCollection objCDOEXMExchangeServer.Fields204:205: ' Enumerate the Storage Group of the current server206: ' (Where the script is running)207: If strCurrentComputerName = objCDOEXMExchangeServer.Name Then208: EnumStorageGroups objCDOEXMExchangeServer209: End If...:...:213: Next...:...:218: End Function

CDOEXM comes with a set of new objects and interfaces related to Exchange 2000 Server. The object used in Sample 7 on page 28 is the CDOEXM.ExchangeServer object instantiated at line 137.

With this object, the script can retrieve CDOEXM information by opening a data source with the Exchange server name retrieved from WMI (line 181). Table 1 The CDOEXM object for the Exchange 2000 Server

Name (ro) The name of the Exchange Server (line 196)

ExchangeVersion (ro) The version of the Exchange Server (lines 188 and 189)

StorageGroups (ro) The list of URLs to the Storage Groups on this server. This parameter will beused in EnumStorageGroups() function called line 208.

SubjectLoggingEnabled (rw) Indicates whether subject logging and display is enable for this server (lines190 and 191)

MessageTrackingEnabled (rw) Indicates whether message tracking is enable for this server (lines 192 and193)

DaysBeforeLogFileRemoval (rw) The number of days log files are retained on the server (lines 194 and 195)

ServerType (rw) Indicates whether this server is a front-end only server relaying commands to a back-end server for execution (lines 197 and 198) 0=FrontEnd, 1=BackEnd

DirectoryServer (ro) The domain controller used by services on this machine (lines 199 and 200)

GetInterface (ro) Returns the specified interface on the object

DataSource (ro) Returns the IDataSource interface on the object (line 181)

Fields (ro) Returns the Fields collection for the object (lines 202 and 203)

Lines 202 and 203 retrieve the ADO Fields collection associated with the Exchange 2000 server. See Sample 24 on page 62 for the EnumFieldsCollection() function.

Page 30: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 30

20001008

Management Point 1 Retrieving server information from WMI and CDOEXM

At this stage of the script, the following information is available:

• The complete list of the Exchange 2000 servers in the Enterprise with some information details (Version, server type, etc).

• The associated status of each Exchange 2000 server in the Enterprise.

• The possibility to read and set the configuration of logging and message tracking for each Exchange server in the Enterprise.

• The state of the Exchange server as a Front-End (FE) or Back-End (BE) Server.

• A pointer to get the configuration of the Storage Groups for each Exchange server.

See points 1,2 and A,B on Figure 4 on page 19 to locate this WMI and CDOEXM operation in the Exchange 2000 logical view.

Retrieving Exchange 2000 Storage Group information with CDOEXM Sample 7 on page 28 at line 208 calls the EnumStorageGroups() function with the CDOEXM.ExchangeServer object as parameter. This function (See Sample 8 below) will retrieve the list of Storage Groups configured on this server.

It is important to note the presence of the condition at line 207. This condition restricts the exploration to the local Exchange server only because the Exchange OLE DB provider (used later in Sample 21 on page 53) does not allow any remote connection. The second purpose is to minimize the amount of data collected to the local Exchange server only.

In Sample 8 below, the CDOEXM object used is CDOEXM.StorageGroup, which is instantiated at line 226. Line 228 loops through the Storage Groups in the collection. Inside the loop, a data source is opened (line 232) based on the distinguishedName retrieved from the collection. For each Storage Group, the script will extract the properties’ values (lines 239 to 245). Sample 8 Retrieving Storage Group information with CDOEXM

221: Private Function EnumStorageGroups (objCDOEXMExchangeServer)...:...:226: Set objStorageGroup = CreateObject("CDOEXM.StorageGroup")227:228: For Each urlStorageGroup In objCDOEXMExchangeServer.StorageGroups...:232: objStorageGroup.DataSource.Open (urlStorageGroup)...:...:239: DisplayText "Storage Group Name(CDOEXM)", objStorageGroup.Name240: DisplayText "LogFilePath(CDOEXM)", objStorageGroup.LogFilePath241: DisplayText "SystemFilePath(CDOEXM)", _242: objStorageGroup.SystemFilePath243: DisplayText "CircularLogging(CDOEXM)", _244: objStorageGroup.CircularLogging245: DisplayText "ZeroDatabase(CDOEXM)", objStorageGroup.ZeroDatabase246:247: ' At this level of the object hierarchy, we can move the Logs file248: ' and System files of the Storage Group to an other location.249: ' objStorageGroup.MoveLogFiles <New File System Path>250: ' objStorageGroup.MoveSystemFiles <New File System Path>251:252: If cEnumFieldsCollection Then _253: EnumFieldsCollection objStorageGroup.Fields254:255: EnumMailboxStoreDBs objStorageGroup256:257: EnumPublicStoreDBs objStorageGroup

3 C

Page 31: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 31

20001008

...:

...:261: Next...:...:266: End Function

Note: Lines 249 and 250 are commented out. Their presence is for information only. We do not want to move the logs or the System files when this script is executed.

Table 2 The CDOEXM.StorageGroup object

Name (rw) The name of the object (line 239)

PublicStoreDBs (ro) The list of URLs to the public store databases on this server. This parameter will be used in theEnumPublicStoreDBs() function at line 257.

MailboxStoreDBs (ro) The list of URLs to the mailbox store databases on this server. This parameter will be used in the EnumMailboxStoreDBs() function at line 255.

LogFilePath (ro) The transaction log location (line 240)

SystemFilePath (ro) The system path location (lines 241 and 242)

CircularLogging (rw) Indicates whether circular logging is enabled (lines 243 and 244)

ZeroDatabase (rw) Indicates whether deleted database pages should be zeroed out (lines 245)

MoveLogFiles Changes the log file path. LogFilePath is a directory in the file system. For new objects, this willset the initial value of the LogFilePath property. For an existing object, the path can only bechanged if running on the local machine (line 249).

MoveSystemFiles Changes the system file path. SystemFilePath is a directory in the file system. For new objects, this will set the initial value of the SystemFilePath property. For an existing object, the path canonly be changed if running on the local machine (line 250)

GetInterface Returns the specified interface on the object

DataSource (ro) Returns the IDataSource interface on the object (line 232)

Fields (ro) Returns the Fields collection for the object (lines 252 and 253)

Lines 252 and 253 retrieve the ADO Fields collection associated with an Exchange 2000 server. See Sample 24 on page 62 for the EnumFieldsCollection() function.

Management Point 2 Retrieving Storage Group information with CDOEXM

At this stage of the script, we have the following information:

• The Storage Group configuration (log file and system file location with ability to move them to another location).

• The ability to enable/disable circular logging per Storage Group. • The ability to enable/disable the zeroDatabase feature. • A pointer to get the configuration of all Mailboxes and Public

Stores present in the Storage Group. See points 3 and C on Figure 4 on page 19 to locate this CDOEXM operation in the Exchange 2000 logical view.

Retrieving Exchange 2000 Mailbox Store information with CDOEXM The Sample 8 on page 30 at line 255 calls the EnumMailboxStoreDBs() function with the CDOEXM.StorageGroup object as a parameter. The EnumMailboxStoreDBs() function will retrieve the list of Mailbox Stores present in this Storage Group.

4 D

Page 32: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 32

20001008

In Sample 9 below, the list of Mailbox Stores is retrieved from a collection (line 276). Inside the “For Each” loop, a data source is opened (line 280) based on the distinguishedName retrieved from the collection. For each Mailbox Store, the script will extract the values of the object’s properties (lines 287 to 303). Sample 9 Retrieving Mailbox Store information with CDOEXM

269: Private Function EnumMailboxStoreDBs (objStorageGroup)...:...:274: Set objMailboxStoreDB = CreateObject("CDOEXM.MailBoxStoreDB")275:276: For Each urlMailboxStoreDB In objStorageGroup.MailboxStoreDBs...:...:280: objMailboxStoreDB.DataSource.Open (urlMailboxStoreDB)...:...:287: DisplayText "Name(CDOEXM)", objMailboxStoreDB.Name288: DisplayText "DaysBeforeGarbageCollection", _289: objMailboxStoreDB.DaysBeforeGarbageCollection290: DisplayText "DaysBeforeDeletedMailboxCleanup", _291: objMailboxStoreDB.DaysBeforeDeletedMailboxCleanup292: DisplayText "GarbageCollectOnlyAfterBackup", _293: objMailboxStoreDB.GarbageCollectOnlyAfterBackup294: DisplayText "DBPath", objMailboxStoreDB.DBPath295: DisplayText "SLVPath", objMailboxStoreDB.SLVPath296: DisplayText "PublicStoreDB", objMailboxStoreDB.PublicStoreDB297: DisplayText "OfflineAddressList", _298: objMailboxStoreDB.OfflineAddressList299: DisplayText "Status", objMailboxStoreDB.Status300: DisplayText "Enabled", objMailboxStoreDB.Enabled301: DisplayText "StoreQuota", objMailboxStoreDB.StoreQuota302: DisplayText "OverQuotaLimit", objMailboxStoreDB.OverQuotaLimit303: DisplayText "HardLimit", objMailboxStoreDB.HardLimit304:305: ' At this level of the object hierarchy,306: ' we can Mount/Dismount the Mailbox Store.307: ' objMailboxStoreDB.Dismount308: ' objMailboxStoreDB.Mount309:310: ' At this level of the object hierarchy,311: ' we can move the Mailbox Store312: ' to an other location.313: ' objMailboxStoreDB.MoveDataFiles <New Data File Path>314:315: If cEnumFieldsCollection Then _316: EnumFieldsCollection objMailboxStoreDB.Fields317:318: EnumMailboxStore urlMailboxStoreDB...:...:322: Next...:...:327: End Function

Note: Lines 307, 308 and 313 are commented out. Their presence is for information only. We do not want to mount/dismount or move the database files when this script is executed.

Table 3 The CDOEXM object for the Mailbox Store

Name (rw) The name of the object (line 287)

PublicStoreDB (rw) The default public store for mailboxes on this database (line 296)

OfflineAddressList (rw) The offline address list for mailboxes on this database (lines 297 and 298)

DBPath (ro) The path to the Exchange database file (line 294)

Page 33: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 33

20001008

SLVPath (ro) The path to the Exchange streaming database file (line 295)

Status (ro) The current online status of the database (line 299)

Enabled (rw) Indicates whether this store should be mounted at start-up (line 300)

StoreQuota (rw) The quota limit at which mailboxes will recieve warning messages (line 301)

OverQuotaLimit (rw) The quota limit at which sending messages will be prohibited (line 302)

HardLimit (rw) The quota limit at which incoming messages will be rejected (line 303)

DaysBeforeGarbageCollection (rw) The number of days to keep deleted items (line 289)

DaysBeforeDeletedMailboxCleanup (rw) The number of days deleted mailboxes are retained in the database (lines 290 and 291)

GarbageCollectOnlyAfterBackup (rw) Indicates whether items should not be permanently deleted until the store has been backed up (lines 292 and 293)

MoveDataFiles Changes the database file paths. DBPath and SLVPath parameters are file paths on the server. Flags parameter is ignored. For an existing object, the path can only be changed if running on the local machine (line 313)

Mount Mounts this store for use. Timeout parameter is ignored (line 308)

Dismount Dismount this store. Timeout parameter is ignored (line 307)

GetInterface Returns the specified interface on the object

DataSource (ro) Returns the IDataSource interface on the object (line 280)

Fields (ro) Returns the Fields collection for the object (lines 315 and 316)

Lines 315 and 316 retrieve the ADO Fields collection associated to an Exchange 2000 server. See Sample 24 on page 62 for the EnumFieldsCollection() function.

Management Point 3 Retrieving Mailbox Store information with CDOEXM

At this stage of the script, we have the following information:

• The Database and Stream files location of each Mailbox Store present in the Storage Groups.

• The distinguishedName of the default Public Store for the Mailbox Store.

• The OfflineAddressList for the Mailbox Store. • The status of the Mailbox Store (Mounted / Dismounted) and its

default state at the Exchange startup. • A set of information about the Store quotas. • A set of information about the Store cleanup process. • The ability to mount and dismount the Mailbox Store and to move the Mailbox

Store data files to another location. See points 4 and D on Figure 4 on page 19 to locate this operation in the Exchange 2000 logical view.

Getting Information about Mailboxes

Once the Russian doll has been opened, the discovery of the server (with the Storage Groups containing Mailbox stores and Public stores) allows the exploration of the first store type: The Mailbox store containing the mailboxes.

Retrieving mailboxes homed in a Mailbox Store with ADSI The Sample 9 on page 32 at line 318 calls the EnumMailboxStore() function with the distinguishedName of the Mailbox Store as a parameter. The first part of the EnumMailboxStore() function (See Sample 10 on page 35) will retrieve the list of the mailboxes homed on the Mailbox Store (lines 31 to 35).

5 E

6 F

Page 34: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 34

20001008

The list of mailboxes is retrieved from a query based on ADO and performed by the ADSearch() function. The key in this query is that ADO uses the ADSI OLE DB provider (See Figure 2 on page 17). From the scripting world an LDAP search operation is implemented on top of ADO. The LDAP query is realized by an ADSI component (the iDirectorySearch interface) used by the ADSI OLE DB provider. The key is to understand that the search operation is executed by ADSI based on an ADO query. This is why the steps 5 and E show ADO on Figure 4 on page 19.

Note: This document does not focus on ADSI, for more information about ADSI search operations see the Compaq Active Answers Web site at location:

http://vcmproapp02.compaq.com/ActiveAnswers/Global/en/solutions.1128/offline.8588/default.asp

For more information, the ADSearch() function is provided in APPENDIX on page 74 “Querying the Active Directory with ADSI and ADO”.

The query selection is based on the homeMDB attribute initialized for any mailbox-enabled object in the Active Directory. The homeMDB attribute (line 32) is simply the distinguishedName of the Mailbox Store homing the mailbox.

The result of the search operation is a collection of ADsPath objects stored in a Dictionary object (line 31). The Dictionary Object is part of the Scripting Run-Time Library. (See Microsoft Visual Basic Scripting/Java Scripting on-line Documentation for more information about the Scripting Run-Time Library.) The Dictionary object is like an array where heterogeneous data can be stored and accessed by keying off of an ordinal position or a string used as key.

The ADSearch() function can retrieve other attributes besides the homeMDB attribute. It will also be used in “Moving mailboxes from ADSI.User and CDO.Person objects based on a LDAP query” sample included in the second part of this document.

Note: The Mailbox Store object in the Active Directory contains an attribute named homeMDBBL. This multi-valued attribute contains a list of the distinguishedName of users with mailboxes in the Mailbox Store. It is important to understand that our LDAP search operation is more efficient because in most “real world” scenarios, we will want to retrieve additional object properties besides the distinguishedName. With an LDAP Search, it is possible to get more information on the returned object list. If the homeMDBBL property is used, it will be mandatory to make a bind operation with each distinguishedName to get more information on the object itself, which is far less efficient than the LDAP search operation.

Management Point 4 Retrieving the homed mailboxes in a Mailbox Store with ADO/ADSI

At this stage of the script, we have the following information:

• The distinguishedName of the examined Mailbox Store. • A distinguishedName list of the mailbox-enabled Active Directory

Users homed on this Mailbox Store.

See points 5, 6 and E, F on Figure 4 on page 19 to locate this operation in the Exchange 2000 logical view.

Page 35: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 35

20001008

Retrieving mailbox-enabled object properties with ADSI At line 54, the Sample 10 below starts the enumeration of the distinguishedNames retrieved by the ADSearch() function. For each loop, the script binds to the Active Directory mailbox-enabled object (lines 56 and 57). It retrieves the list of properties associated with the mailbox-enabled object (lines 60 to 177). Note at lines 60 and 61, the script saves the mail alias (mailNickName and the displayName properties in two variables for later usage).

Note: In this case, it is mandatory to make a bind operation because the script will use the IMailboxStore aggregated interface (See Sample 12 on page 39, lines 200 to 212) to retrieve the mailbox properties associated with the ADSI.User object. In a “real world” scenario, if the objective is not to retrieve the mailbox properties, the bind operation is not required and the LDAP Search operation can retrieve the ADSI.User properties from the search. This will make the code more efficient. See prior note about the homeMDBBL property above.

Note: To make the script more readable, some parts of the code getting the ADSI.User properties are removed from the Sample 10.

Note: Accessing the Active Directory from ADSI implies the usage of the LDAP namespace. It is important to notice that some ADSI.User object properties are not supported in the LDAP namespace (lines 80, 101, 104, 111, 132, 145, 150, and 163). These properties are related to the user logon management and are part of the GPO under Windows 2000. Under the ADSI WinNT: namespace (Windows NT 4.0), these properties are supported. For more information about ADSI, see http://msdn.microsoft.com/library/psdk/adsi/adsistartpage_7wrp.htm.

Sample 10 Retrieving the mailbox homed on a Mailbox Store and the associated mailbox-enabled object properties from ADSI

1:' VB Script function to enumerate the mailboxes in a Mailbox Store from an '2:' ADSI user object class. '3:' '4:' Version 1.00 - Alain Lissoir '5:' Compaq Computer Corporation - Professional Services - Belgium - '6:' '7:' Any comments or questions: EMail:[email protected] '8:9:Option Explicit10:11:' ---------------------------------------------------------------------------------12:Function EnumMailboxStore (urlMailboxStoreDB)..:..:26: ' -------------------------------------------------------------------------27: WScript.Echo Space (intX + 1) & _28: "Retrieving User/mailbox list via 'ADSI/ADO' LDAP Query."29:30: ' Query for the user's mailbox to move to.31: Set objResultList = ADSearch ("LDAP://" & strDefaultDomainNC, _32: "(homeMDB=" & urlMailboxStoreDB & ")", _33: "ADsPath", _34: "subTree", _35: False)36:37: ' -------------------------------------------------------------------------38: objResult = objResultList.Items..:..:54: For intIndice = 1 to (objResultList.Count - 1)55:56: Set objUser = GetObject (objResult (intIndice))57: objUser.GetInfo58:

7

Page 36: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 36

20001008

59: ' Getting two properties for display facilities.60: strAlias = objUser.Get ("mailNickName")61: strDisplayName = objUser.Get ("displayName")..:..:76: strTemp = "" : strTemp = objUser.AccountDisabled77: DisplayText "AccountDisabled(ADSI)", strTemp78: strTemp = "" : strTemp = objUser.AccountExpirationDate79: DisplayText "AccountExpirationDate(ADSI)", strTemp80: ' objUser.BadLoginAddress81: strTemp = "" : strTemp = "(Not supported in LDAP namespace)"82: DisplayText "BadLoginAddress(ADSI)", strTemp83: strTemp = "" : strTemp = objUser.BadLoginCount84: DisplayText "BadLoginCount(ADSI)", strTemp85: strTemp = "" : strTemp = objUser.Department86: DisplayText "Department(ADSI)", strTemp..:..:98: DisplayText "FirstName(ADSI)", strTemp99: strTemp = "" : strTemp = objUser.FullName100: DisplayText "FullName(ADSI)", strTemp101: ' objUser.GraceLoginsAllowed102: strTemp = "" : strTemp = "(Not supported in LDAP namespace)"103: DisplayText "GraceLoginsAllowed(ADSI)", strTemp104: ' objUser.GraceLoginsRemaining105: strTemp = "" : strTemp = "(Not supported in LDAP namespace)"106: DisplayText "GraceLoginsRemaining(ADSI)", strTemp107: strTemp = "" : strTemp = objUser.HomeDirectory108: DisplayText "HomeDirectory(ADSI)", strTemp109: strTemp = "" : strTemp = objUser.HomePage110: DisplayText "HomePage(ADSI)", strTemp111: ' objUser.IsAccountLocked112: strTemp = "" : strTemp = "(Not supported in LDAP namespace)"113: DisplayText "IsAccountLocked(ADSI)", strTemp114: strTemp = "" : strTemp = objUser.Languages115: DisplayText "Languages(ADSI)", strTemp...:...:126: strTemp = "" : strTemp = objUser.LoginScript127: DisplayText "LoginScript(ADSI)", strTemp128: strTemp = "" : strTemp = objUser.LoginWorkstations129: DisplayText "LoginWorkstations(ADSI)", strTemp130: strTemp = "" : strTemp = objUser.Manager131: DisplayText "Manager(ADSI)", strTemp132: ' objUser.MaxLogins133: strTemp = "" : strTemp = "(Not supported in LDAP namespace)"134: DisplayText "MaxLogins(ADSI)", strTemp...:...:143: strTemp = "" : strTemp = objUser.OtherName144: DisplayText "OtherName(ADSI)", strTemp145: ' objUser.PasswordExpirationDate146: strTemp = "" : strTemp = "(Not supported in LDAP namespace)"147: DisplayText "PasswordExpirationDate(ADSI)", strTemp148: strTemp = "" : strTemp = objUser.PasswordLastChanged149: DisplayText "PasswordLastChanged(ADSI)", strTemp150: ' objUser.PasswordMinimumLength151: strTemp = "" : strTemp = "(Not supported in LDAP namespace)"152: DisplayText "PasswordMinimumLength(ADSI)", strTemp153: strTemp = "" : strTemp = objUser.PasswordRequired...:...:161: strTemp = "" : strTemp = objUser.Profile162: DisplayText "Profile(ADSI)", strTemp163: ' objUser.RequireUniquePassword164: strTemp = "" : strTemp = "(Not supported in LDAP namespace)"165: DisplayText "RequireUniquePassword(ADSI)", strTemp166: strTemp = "" : strTemp = objUser.SeeAlso167: DisplayText "SeeAlso(ADSI)", strTemp168: strTemp = "" : strTemp = objUser.TelephoneHome...:...:174: strTemp = "" : strTemp = objUser.TelephonePager175: DisplayText "TelephonePager(ADSI)", strTemp176: strTemp = "" : strTemp = objUser.Title177: DisplayText "Title(ADSI)", strTemp

Page 37: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 37

20001008

178:179: ' At this level of the object hierarchy,180: ' we can determine the group appartenance, set and change181: ' the password of a user object182: ' objUser.Groups183: ' objUser.SetPassword184: ' objUser.ChangePassword...:...:

After the mailbox-enabled object’s properties are retrieved, three lines are commented out (lines 182 to 184). A mailbox-enabled object is a user object class in the Active Directory. This is the reason why it is possible to retrieve the group membership of the object (line 182). In the same way, a password reset (line 183) or change (line 184) can be done at this level of the object hierarchy. Note that these features are purely ADSI related.

Once the Active Directory mailbox-enabled object properties are retrieved, the script will use CDOEXM to retrieve the mailbox properties associated with this object (See Sample 11 below, lines 200 to 224). This is the point where CDOEXM acts as an extension for ADSI by providing the IMailboxStore interface to the ADSI.User object. The IMailboxStore interface is an aggregated interface to the ADSI.User object class. For more information about the ADSI.User object class, see http://msdn.microsoft.com/library/psdk/adsi/if_pers_488i.htm

Management Point 5 Retrieving mailbox-enabled object properties with ADSI

At this stage of the script, we have the following information:

• The property list of the ADSI.User mailbox-enabled object. • The possibility the get and change the ADSI.User group

membership. • The possibility to change or reset the ADSI.User password. • An interface to retrieve the information of the mailbox configuration with the help

of the IMailboxStore interface of CDOEXM. See points 7 on Figure 4 on page 19 to locate this operation in the Exchange 2000 logical view.

Retrieving the mailbox properties with CDOEXM from ADSI When the Exchange System Manager (ESM) is installed in a Windows 2000 machine, CDOEXM is registered under Windows 2000 and is installed as an extension to ADSI. This is the reason why it is possible to get from the mailbox-enabled ADSI object (instantiated at line 56 in Sample 10 on page 35) a set of properties and methods (Sample 11 below, lines 200 to 217) directly related to the mailbox. Sample 11 Retrieving the mailbox properties with CDOEXM from ADSI

...:196: DisplayText "Data retrieved via 'IMailboxStore CDOEXM' interface", ""...:200: DisplayText "DaysBeforeGarbageCollection(CDOEXM)", _201: objUser.DaysBeforeGarbageCollection202: DisplayText "EnableStoreDefaults(CDOEXM)", _203: objUser.EnableStoreDefaults204: DisplayText "GarbageCollectOnlyAfterBackup(CDOEXM)", _205: objUser.GarbageCollectOnlyAfterBackup206: DisplayText "Hardlimit(CDOEXM)", objUser.Hardlimit207: DisplayText "HomeMDB(CDOEXM)", objUser.HomeMDB208: DisplayText "OverQuotaLimit(CDOEXM)", objUser.OverQuotaLimit209: DisplayText "OverrideStoreGarbageCollection(CDOEXM)", _210: objUser.OverrideStoreGarbageCollection211: DisplayText "RecipientLimit(CDOEXM)", objUser.RecipientLimit212: DisplayText "StoreQuota(CDOEXM)", objUser.StoreQuota...:

8

9

Page 38: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 38

20001008

215: For Each strDelegate In objUser.Delegates216: DisplayText "Delegate(CDOEXM)", strDelegate217: Next...:220: ' At this level of the object hierarchy,221: ' we can create, move or delete a mailbox from the Private Store.222: ' objUser.CreateMailBox223: ' objUser.DeleteMailBox224: ' objUser.MoveMailBox...:...:249:End Function

Note: The lines 222, 223 and 224 are commented out. Their presence is for information only. We do not want create, move or delete mailboxes when this script is executed.

Table 4 The CDOEXM Interface for Mailbox management

DaysBeforeGarbageCollection (rw) The number of days deleted mail is retained before it is permanently deleted.(lines 200 and 201)

Delegates (rw) The list of URLs of all users that have access to the mailbox (lines 215 to 217). Note that the Delegates property is a multi-value property containing the delegated users distinguishedName.

EnableStoreDefaults (rw) Dictates whether to use only default store values for storage limits, or to use other properties pertaining to the mailbox (lines 202 to 203).

GarbageCollectOnlyAfterBackup (rw) Dictates whether deleted messages can only be permanently deleted after themailbox has been backed up (lines 201 and 205).

Hardlimit (rw) The mailboxes maximum size, in Kbytes, over which sending and receiving is restricted (line 206).

HomeMDB (ro) The URL of the store for the recipient (line 207)

OverQuotaLimit (rw) The maximum size, in Kbytes, over the StoreQuota property size upon whichsending mail is disabled (line 208).

OverrideStoreGarbageCollection (rw) Dictates whether the store should be prevented from permanently deletingdeleted messages (lines 209 and 210)

RecipientLimit (rw) Maximum number of people to which the recipient can send mail (per email) (line 211).

StoreQuota (rw) The maximum size, in Kbytes, allowed for the mailbox (line 212)

CreateMailBox Creates a mailbox at a specified URL (line 222)

DeleteMailBox Deletes a mailbox at a specified URL. (line 223)

MoveMailBox Moves a mailbox to a specified URL. (line 224)

Management Point 6 Retrieving the mailbox properties with CDOEXM from ADSI

At this stage of the script, we have the following information:

• The configuration of the user mailbox. (Quota, mailbox cleanup process, mailbox restrictions).

• The possibility to review and create list of users with delegated access to the mailbox..

• The possibility to create, move or delete mailbox from ADSI.User object. See points 8 and 9 on Figure 4 on page 19 to locate this operation in the Exchange 2000 logical view.

Page 39: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 39

20001008

Retrieving mailbox-enabled object properties with CDOEX The function EnumMailboxStore() presented in Sample 12 below is the same as the function EnumMailboxStore() presented in Sample 10 on page 35, with one exception: The Sample 12 version retrieves the mailbox-enabled object properties from a CDO.Person object; The Sample 10 retrieves the mailbox-enabled object properties from an ADSI.User object.

The purpose is to demonstrate how these two different COM technologies are tied together under Exchange 2000 and what kind of information one technology provides in comparison with the other.

This is the reason why in Sample 6 on page 26, the lines 14 and 15 including the function can be swapped with the lines 16 and 17 to switch between the CDOEX logic and the ADSI logic. In both cases, the CDOEXM.MailboxStore interface is used to access the mailbox configuration settings.

Sample 12 below (lines 30 to 38) starts in the same way as Sample 10 on page 35 (lines 30 to 38). The list of mailboxes is retrieved by an ADSI query. The difference lies in how the mailbox-enabled object information is retrieved from the Active Directory. In Sample 10, an ADSI.User object is instantiated at line 56 in the “For Each” loop. In Sample 12, a CDO.Person object is first created at line 52. Next, the IDataSource interface is opened to retrieve the user information (line 56).

Note that the information used to access user data is the same: Both script samples (line 31) use the ADsPath returned by the query result. Actually, behind the scene, the CDO.Person object is using ADSI. This is the reason why this operation is coupled to ADSI in Figure 4 on page 19 at step G.

In the same way as Sample 10 on page 35, the Sample 12 below retrieves the mailNickName and the displayName attribute. What is unique about this operation is the usage of the Fields collection (lines 59 and 60). The CDO.Person object does not expose the mailNickName and the displayName attributes.

Because CDOEX is linked to ADO in the Exchange 2000 architecture and ADO exposes a Fields collection (defined in the Web Store schema) containing miscellaneous properties related to the opened data source, it is possible from CDOEX to use this method to retrieve some LDAP properties contained in the Fields collection.

In a sense, we can say that ADO (with the help of the Web Store architecture and its OLE DB provider) extends the number of properties available from a CDOEX object. The main difference between the properties retrieved from the CDOEX object itself and an equivalent property from the Fields property is that the ADO Fields collection does not contain any business logic. This is why it is important to use the CDOEX properties to get or set values when possible. Only use the ADO Fields collection if the property is not available from the CDOEX object it self (as is the case for mailNickName and displayName). Sample 12 Retrieving the mailbox homed on a Mailbox Store and the associated mailbox-enabled object properties from CDOEX

1:' VB Script function to enumerate the mailboxes in a Mailbox Store from a CDO.Person '2:' object class. '3:' '4:' Version 1.00 - Alain Lissoir '5:' Compaq Computer Corporation - Professional Services - Belgium - '6:' '7:' Any comments or questions: EMail:[email protected] '8:9:Option Explicit10:11:' --------------------------------------------------------------------------------------12:Function EnumMailboxStore (urlMailboxStoreDB)..:..:26: ' ------------------------------------------------------------------------------27: WScript.Echo Space (intX + 1) & _

G

H

Page 40: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 40

20001008

28: "Retrieving Person/mailbox list via 'ADSI/ADO' LDAP Query."29:30: ' Query for the user's mailbox to move to.31: Set objResultList = ADSearch ("LDAP://" & strDefaultDomainNC, _32: "(homeMDB=" & urlMailboxStoreDB & ")", _33: "ADsPath", _34: "subTree", _35: False)36:37: ' ------------------------------------------------------------------------------38: objResult = objResultList.Items..:..:52: Set objPerson = CreateObject ("CDO.Person")53:54: For intIndice = 1 to (objResultList.Count - 1)55:56: objPerson.DataSource.Open objResult (intIndice)57:58: ' Getting two properties for display facilities.59: strAlias = objPerson.Fields("mailNickName")60: strDisplayName = objPerson.Fields("displayName")..:..:71: DisplayText "Company(CDOEX)", objPerson.Company72: DisplayText "Email(CDOEX)", objPerson.Email73: DisplayText "Email2(CDOEX)", objPerson.Email274: DisplayText "Email3(CDOEX)", objPerson.Email375: DisplayText "EmailAddresses(CDOEX)", objPerson.EmailAddresses76: DisplayText "FileAs(CDOEX)", objPerson.FileAs77: DisplayText "FileAsMapping(CDOEX)", objPerson.FileAsMapping78: DisplayText "FirstName(CDOEX)", objPerson.FirstName79: DisplayText "HomeCity(CDOEX)", objPerson.HomeCity80: DisplayText "HomeCountry(CDOEX)", objPerson.HomeCountry81: DisplayText "HomeFax(CDOEX)", objPerson.HomeFax82: DisplayText "HomePhone(CDOEX)", objPerson.HomePhone83: DisplayText "HomePostalAddress(CDOEX)", objPerson.HomePostalAddress84: DisplayText "HomePostalCode(CDOEX)", objPerson.HomePostalCode85: DisplayText "HomePostOfficeBox(CDOEX)", objPerson.HomePostOfficeBox86: DisplayText "HomeState(CDOEX)", objPerson.HomeState87: DisplayText "HomeStreet(CDOEX)", objPerson.HomeStreet88: DisplayText "Initials(CDOEX)", objPerson.Initials89: DisplayText "LastName(CDOEX)", objPerson.LastName90: DisplayText "MailingAddress(CDOEX)", objPerson.MailingAddress91: DisplayText "MailingAddressID(CDOEX)", objPerson.MailingAddressID92: DisplayText "MiddleName(CDOEX)", objPerson.MiddleName93: DisplayText "MobilePhone(CDOEX)", objPerson.MobilePhone94: DisplayText "NamePrefix(CDOEX)", objPerson.NamePrefix95: DisplayText "NameSuffix(CDOEX)", objPerson.NameSuffix96: DisplayText "Title(CDOEX)", objPerson.Title97: DisplayText "WorkCity(CDOEX)", objPerson.WorkCity98: DisplayText "WorkCountry(CDOEX)", objPerson.WorkCountry99: DisplayText "WorkFax(CDOEX)", objPerson.WorkFax100: DisplayText "WorkPager(CDOEX)", objPerson.WorkPager101: DisplayText "WorkPhone(CDOEX)", objPerson.WorkPhone102: DisplayText "WorkPostalAddress(CDOEX)", objPerson.WorkPostalAddress103: DisplayText "WorkPostalCode(CDOEX)", objPerson.WorkPostalCode104: DisplayText "WorkPostOfficeBox(CDOEX)", objPerson.WorkPostOfficeBox105: DisplayText "WorkState(CDOEX)", objPerson.WorkState106: DisplayText "WorkStreet(CDOEX)", objPerson.WorkStreet107:108: ' At this level of the object hierarchy,109: ' we can obtain a stream the Vcard of the CDO.Person110: ' objPerson.GetVCardStream111:112: If cEnumFieldsCollection Then _113: EnumFieldsCollection objPerson.Fields...:...:

Once the data source is opened (line 56), the script enumerates all the properties associated with the CDO.Person object (lines 71 to 106). For more information about the CDO.Person object, see the Exchange 2000 SDK.

Page 41: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 41

20001008

Lines 112 and 113 retrieve the ADO Fields collection associated with an Exchange 2000 server. See Sample 24 on page 62 for the EnumFieldsCollection() function.

Management Point 7 Retrieving mailbox-enabled object properties with CDOEX

At this stage of the script, we have the following information:

• The property list of the mailbox-enabled object. • The possibility to get access to the Vcard stream of the CDO.Person

object. See points G and H on Figure 4 on page 19 to locate this operation in the Exchange 2000 logical view.

Retrieving the mailbox properties with CDOEXM from CDOEX To enumerate the mailbox properties (Sample 13 below, lines 127 to 139), the script must first invoke the GetInterface method of the CDO.Person object. The GetInterface method is primarily intended as a generic interface navigation aid to scripting languages. The list of valid interface names to pass to GetInterface is dependent upon a specific implementation.

The IMailboxStore interface is aggregated by:

• CDO.Person

• ADSI.User

For instance, in Sample 12 on page 39 at line 56, the CDO.Person object is used as follows:

ObjPerson.DataSource.Open objResult (intIndice)

This is possible because the IDataSource interface is immediately accessible from the CDO.Person object. Actually, it is also possible to use the following code:

objDataSource = ObjPerson.GetInterface(“IDataSource”) objDataSource.Open objResult (intIndice)

The result will be exactly the same. Of course, for the IDataSource interface, the script does not use this method because IDataSource is directly available from the CDO.Person object. To access the mailbox settings (as made via ADSI in Sample 11 on page 37, lines 200 to 217) Sample 13 below must “connect” the CDO.Person to the IMailboxStore interface because the IMailboxStore interface is not directly accessible from the CDO.Person object. This why the following line is used (line 125):

objMailbox = ObjPerson.GetInterface(“IMailboxStore ”)

The steps from lines 127 to 144 in Sample 12 (CDOEX) are exactly the same as the lines 200 to 217 on Sample 10 (ADSI). Only the base object used is different. Sample 13 Retrieving the mailbox properties with CDOEXM from CDOEX

...:

...:125: Set objMailbox = objPerson.GetInterface ("IMailboxStore ")126:127: DisplayText "DaysBeforeGarbageCollection(CDOEXM)",128: objMailbox.DaysBeforeGarbageCollection129: DisplayText "EnableStoreDefaults(CDOEXM)", _130: objMailbox.EnableStoreDefaults131: DisplayText "GarbageCollectOnlyAfterBackup(CDOEXM)", _132: objMailbox.GarbageCollectOnlyAfterBackup133: DisplayText "Hardlimit(CDOEXM)", objMailbox.Hardlimit134: DisplayText "HomeMDB(CDOEXM)", objMailbox.HomeMDB135: DisplayText "OverQuotaLimit(CDOEXM)", objMailbox.OverQuotaLimit

I

J

Page 42: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 42

20001008

136: DisplayText "OverrideStoreGarbageCollection(CDOEXM)", _137: objMailbox.OverrideStoreGarbageCollection138: DisplayText "RecipientLimit(CDOEXM)", objMailbox.RecipientLimit139: DisplayText "StoreQuota(CDOEXM)", objMailbox.StoreQuota...:...:142: For Each strDelegate In objMailbox.Delegates143: DisplayText "Delegate(CDOEXM)", strDelegate144: Next...:147: ' At this level of the object hierarchy,148: ' we can create, move or delete a mailbox from the Mailbox Store.149: ' objMailbox.CreateMailBox150: ' objMailbox.DeleteMailBox151: ' objMailbox.MoveMailBox...:...:179:End Function

Management Point 8 Retrieving the mailbox properties with CDOEXM from CDOEX

At this stage of the script, we have the following information:

• The configuration of the mailbox-enabled Active Directory object. (Quota, mailbox cleanup process, mailbox restrictions).

• The ability to review and create a list of users with delegated access to this mailbox.

• The ability to create, move or delete a mailbox from the CDO.Person object. See points I, J on Figure 4 on page 19 to locate this operation in the Exchange 2000 logical view.

Retrieving the mail-enabled object properties with CDOEXM from ADSI or CDOEX To complete the picture, the list returned by the LDAP query contains the mailbox-enabled recipients because the script accesses the homeMDB attribute of the mailbox store (See Sample 10 and Sample 12 at lines 31 to 35). At this level of the object hierarchy, it is also possible to retrieve the mail-enabled recipient properties if the query returns a mail-enabled recipient list.

The purpose of the “EnumAllInXL.Wsf” script is to decompose the Exchange 2000 COM object hierarchy. Decomposing a mail-enabled object will stop the exploration at this level because a mail-enabled object does not have a mailbox.

To access the mail-enabled object’s properties, the script must use the interface IMailRecipient instead of IMailboxStore . Table 5 The CDOEXM interface for Mail-Enabled recipients management

Alias (rw) The email alias of the recipient.

ForwardingStyle (rw) Whether mail is also delivered to an alternative mail address.

ForwardTo (rw) The mailbox recipient where mail is forwarded.

HideFromAddressBook (rw) Whether the address is not displayed in the address book.

IncomingLimit (rw) The maximum size, in Kbytes, of a message sent to the recipient.

OutgoingLimit (rw) The maximum size, in Kbytes, of a message sent from the recipient.

ProxyAddresses (rw) A list of proxy addresses for the recipient.

RestrictedAddresses (rw) Defines the meaning of RestrictedAddressList.

RestrictedAddressList (rw) A list of addresses to accept or reject.

SMTPEmail (rw) The SMTP address used for the recipient.

TargetAddress (rw) The foreign mail system address to which the mail for this recipient should be sent.

8

G

H

7

Page 43: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 43

20001008

X400Email (rw) The X.400 address used for the recipient.

MailDisable Disable mail to a recipient.

MailEnable Enable mail to a recipient.

Here are two scripts creating a mail-enabled Active Directory user with the IMailRecipient interface. Sample 14 below creates a mail-enabled user from an ADSI object. Sample 15 on page 44 creates a mail-enabled user from a CDOEX object. Sample 14 Creating a mail-enabled object with CDOEXM from ADSI

1:' Script creating a user and enabling his mail address via the CDOEXM IMailRecipient '2:' interface associated to the ADSI user object class. '3:' '4:' Version 1.00 - Alain Lissoir '5:' Compaq Computer Corporation - Professional Services - Belgium - '6:' '7:' Any comments or questions: EMail:[email protected] '8:9:Option Explicit10:11:Const cEmailName = "arsene.lupin"12:Const cFirstName = "Arsène"13:Const cLastName = "LUPIN"14:Const cUserID = "LupinA"..:..:..:19:' By default this script expects to run on the local Exchange server.20:Set WNetwork = Wscript.CreateObject("Wscript.Network")21:strComputerName = WNetwork.ComputerName22:Wscript.DisconnectObject (WNetwork)23:Set WNetwork = Nothing..:..:28:' Get the default Windows 2000 Domain name29:Wscript.Echo "Binding to RootDSE to get default Domain Name."30:Set objRoot = GetObject("LDAP://RootDSE")31:strDefaultDomainNC = objRoot.Get("DefaultNamingContext")32:Set objRoot = Nothing..:..:37:Set objContainer = GetObject("LDAP://" & strComputerName & _38: "/" & "CN=users," & strDefaultDomainNC)39:40:Set objUser = objContainer.Create ("user", _41: "cn=" & UCase (cLastName) & _42: " " & cFirstName)43:objUser.Put "samAccountName", cUserID44:objUser.SetInfo45:46:objUser.Put "sn", cLastName47:objUser.Put "givenName", cFirstName48:objUser.Put "userPrincipalName", cEmailName49:objUser.Put "displayName", UCase (cLastName) & " " & cFirstName50:51:objUser.AccountDisabled = False52:objUser.SetInfo53:54:objUser.SetPassword "password"55:56:objUser.MailEnable "SMTP:" & cEmailName & "@MyDomain.Com"57:objUser.SetInfo..:..:..:

To access the IMailRecipient interface, Sample 15 on page 44, uses the same GetInterface method (line 38) as used in Sample 13 on page 41 (line 125). The logic and the reasons are exactly the same.

The IMailRecipient interface is aggregated by:

• CDO.Person

Page 44: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 44

20001008

• CDO.Folder

• ADSI.Contact

• ADSI.Group

• ADSI.User

The IMailRecipient interface will be used in Sample 22 on page 55 to mail-enable a Web Store folder. Sample 15 Creating a mail-enabled object with CDOEXM from CDOEX

1:' Script creating a user and enabling his mail address via the CDOEXM IMailRecipient '2:' interface associated to the CDO person object class. '3:' '4:' Version 1.00 - Alain Lissoir '5:' Compaq Computer Corporation - Professional Services - Belgium - '6:' '7:' Any comments or questions: EMail:[email protected] '8:9:Option Explicit10:11:Const cEmailName = "arsene.lupin"12:Const cFirstName = "Arsène"13:Const cLastName = "LUPIN"14:Const cUserID = "LupinA"..:..:19:' By default this script expects to run on the local Exchange server.20:Set WNetwork = Wscript.CreateObject("Wscript.Network")21:strComputerName = WNetwork.ComputerName22:Wscript.DisconnectObject (WNetwork)23:Set WNetwork = Nothing..:..:28:' Get the default Windows 2000 Domain name29:Wscript.Echo "Binding to RootDSE to get default Domain Name."30:Set objRoot = GetObject("LDAP://RootDSE")31:strDefaultDomainNC = objRoot.Get("DefaultNamingContext")32:Set objRoot = Nothing..:..:37:Set objPerson = CreateObject ("CDO.Person")38:Set objMailRecipient = objPerson.GetInterface ("IMailRecipient")39:40:objPerson.Fields("samAccountName") = cUserID41:objPerson.LastName = cLastName42:objPerson.FirstName = cFirstName43:objPerson.Fields("userPrincipalName") = cEmailName44:objPerson.Fields("displayName") = UCase (cLastName) & " " & cFirstName45:objPerson.Fields("userAccountControl") = 51246:objPerson.Fields("userPassword") = "password"47:objPerson.Fields.Update48:objPerson.DataSource.SaveTo "LDAP://" & strComputerName & "/" & _49: "cn=" & cEmailName & "," & _50: "cn=users," & strDefaultDomainNC51:52:objMailRecipient.MailEnable "SMTP:" & cEmailName & "@MyDomain.Com"53:54:objPerson.DataSource.Save..:..:

Page 45: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 45

20001008

Management Point 9 Retrieving the mail-enabled object properties with CDOEXM from ADSI or CDOEX

At this stage of the script, we have the following information:

• The configuration of the mail-enabled object. • The email address of the recipient. • The possibility to enable or disable mail-enabled recipient from the

CDO.Person object or the ADSI.User object. See points 8, 9 or I, J on Figure 4 on page 19 to locate this operation in the Exchange 2000 logical view.

So far, the script has retrieved the list of mailboxes in the Mailbox Store along with associated configuration for each. The next step is to look at the mailbox content. A mailbox contains some folders and inside the folders many data object types can be present (i.e. messages). But before decomposing the mailbox, we will first examine how the Public Stores in a Storage Group can be retrieved. The method used is almost the same as the method used to retrieve the Mailbox Stores in a Storage Group (See Sample 9 on page 32).

Why not examine the mailbox content first? Because accessing the folders in a mailbox or in a Public Folder uses the same technique. Because it is the same technique, the scripts share the same piece of code to do it and explanations for both accesses will be given at the same time. This is why we must first retrieve the Public Stores present in a Storage Group.

Getting information about Public Folders

Once the Russian doll has been opened, the discovery of the server (with the Storage Groups containing Mailbox stores and Public stores) allows the exploration of the second store type: The Public store containing the Public Folders.

Retrieving Exchange 2000 Public Store information with CDOEXM The Sample 8 on page 30 at line 257 calls the EnumPublicStoreDBs() function with the CDOEXM.StorageGroup object as a parameter. This function will retrieve the list of Public Stores present in this Storage Group.

The list of Public Stores is returned in a collection (See Sample 16 below on line 337). In the “For Each” loop, a Data source is opened (line 341) based on the distinguishedName retrieved from the collection. For each Public Store, the script will extract the values of the object’s properties (lines 348 to 362). Sample 16 Retrieving Public Store information with CDOEXM

330: Private Function EnumPublicStoreDBs (objStorageGroup)...:...:335: Set objPublicStoreDB = CreateObject("CDOEXM.PublicStoreDB")336:337: For Each urlPublicStoreDB In objStorageGroup.PublicStoreDBs338: DisplayText "urlPublicStoreDB(CDOEXM)", urlPublicStoreDB...:...:341: objPublicStoreDB.DataSource.Open (urlPublicStoreDB)...:...:348: DisplayText "Name(CDOEXM)", objPublicStoreDB.Name349: DisplayText "DaysBeforeGarbageCollection", _350: objPublicStoreDB.DaysBeforeGarbageCollection351: DisplayText "DaysBeforeItemExpiration", _352: objPublicStoreDB.DaysBeforeItemExpiration353: DisplayText "GarbageCollectOnlyAfterBackup", _354: objPublicStoreDB.GarbageCollectOnlyAfterBackup355: DisplayText "DBPath", objPublicStoreDB.DBPath356: DisplayText "SLVPath", objPublicStoreDB.SLVPath

M12

Page 46: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 46

20001008

357: DisplayText "FolderTree", objPublicStoreDB.FolderTree358: DisplayText "Status", objPublicStoreDB.Status359: DisplayText "Enabled", objPublicStoreDB.Enabled360: DisplayText "StoreQuota", objPublicStoreDB.StoreQuota361: DisplayText "HardLimit", objPublicStoreDB.HardLimit362: DisplayText "ItemSizeLimit", objPublicStoreDB.ItemSizeLimit363:364: ' At this level of the object hierarchy,365: ' we can Mount/Dismount the Public Store.366: ' objPublicStoreDB.Dismount367: ' objPublicStoreDB.Mount368:369: ' At this level of the object hierarchy,370: ' we can move the Public Store371: ' to an other location.372: ' objPublicStoreDB.MoveDataFiles373:374: If cEnumFieldsCollection Then _375: EnumFieldsCollection objPublicStoreDB.Fields376:377: EnumFolderTree objPublicStoreDB.FolderTree...:...:381: Next...:...:386: End Function

Note: Lines 366, 367 and 372 are commented out. Their presence is for information only. We do not want mount, dismount or move the Store data files when this script is executed.

Table 6 The CDOEXM object to manage the Exchange Public Store

Name (rw) The name of the object (line 348)

FolderTree (rw) The URL of the public folder tree that is associated with this database (lines357 and 377)

DBPath (ro) The path to the Exchange database file (line 355)

SLVPath (ro) The path to the Exchange streaming database file (line 356)

Status (ro) The current online status of the database (line 358)

Enabled (rw) Indicates whether this store should be mounted at start-up (line 359)

StoreQuota (rw) The quota limit at which folders will recieve warning messages (line 360)

HardLimit (rw) The quota limit at which messages will be rejected (line 361)

ItemSizeLimit (rw) The maximum size of a message, in KB (line 362)

DaysBeforeItemExpiration (rw) The age limit for all folders in this store, in days (lines 351 and 352)

DaysBeforeGarbageCollection (rw) The number of days to keep deleted items (lines 349 and 350)

GarbageCollectOnlyAfterBackup (rw) Indicates whether items should not be permanently deleted until the store hasbeen backed up (lines 353 and 354)

MoveDataFiles Changes the database file paths. DBPath and SLVPath parameters are file pathson the server. Flags parameter is ignored. For an existing object, the path canonly be changed if running on the local machine (line 372)

Mount Mounts this store for use. Timeout parameter is ignored (line 367)

Dismount Dismount this store. Timeout parameter is ignored (line 366)

GetInterface Returns the specified interface on the object

DataSource (ro) Returns the IDataSource interface on the object (line 341)

Fields (ro) Returns the Fields collection for the object (lines 374 and 375)

Lines 374 and 375 retrieve the ADO Fields collection associated to a Mailbox Store. See Sample 24 on page 62 for the EnumFieldsCollection() function.

Page 47: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 47

20001008

Management Point 10 Retrieving Exchange 2000 Public Store information with CDOEXM

At this stage of the script, we have the following information:

• An interface to retrieve the Public Folder Tree name of this Public Store with the help of the IFolderTree CDOEXM interface.

• The status of the Public Store (Mounted / Dismounted) and its default state at the Exchange startup.

• A set of information about the Store quotas. • A set of information about the Store cleanup process. • The ability to mount and dismount the Public Store and to move the Public Store

data files to another location. See points 12 and M on Figure 4 on page 19 to locate this operation in the Exchange 2000 logical view.

Retrieving the Public Folder Tree properties Sample 16 on page 45 at line 357 shows the URL of the Public Folder Tree associated with a Public Store. The same parameter is used at line 377 to call the function EnumFolderTree().

The Public Folder Tree information is retrieved by opening the Data source (Sample 17 below line 398) based on the distinguishedName retrieved from the Public Folder property (Sample 16 on page 45 at lines 357 or 377). For the retrieved Public Folder Tree, the script will extract its properties’ values (lines 405 to 418). Sample 17 Retrieving the Public Folder Tree properties

389: Private Function EnumFolderTree (urlFolderTree)...:...:394: Set objFolderTree = CreateObject("CDOEXM.FolderTree")395:396: DisplayText "FolderTree(CDOEXM)", urlFolderTree397:398: objFolderTree.DataSource.Open (urlFolderTree)...:...:405: DisplayText "Name(CDOEXM)", objFolderTree.Name...:...:409: For Each strReplica in objFolderTree.StoreDBs410: DisplayText "Replicas(CDOEXM)", strReplica411: Next...:...:415: DisplayText "TreeType(CDOEXM)", objFolderTree.TreeType416: DisplayText "RootFolderUrl(CDOEXM)", objFolderTree.RootFolderUrl417:418: If cEnumFieldsCollection Then EnumFieldsCollection objFolderTree.Fields419:420: EnumPublicStore objFolderTree.Name...:...:425: End Function

Table 7 The CDOEXM object to manage Exchange Folder Trees

Name (rw) The name of the object (line 405)

StoreDBs (ro) The list of URLs of public store databases that contain replicas of this public folder tree (lines 409to 411)

TreeType (ro) The public folder tree type (line 415) 0=General Purpose, 1=Mapi

RootFolderURL (ro) The URL that should be used to bind ADO to the root folder of this public folder tree (line 416)

GetInterface Returns the specified interface on the object

DataSource (ro) Returns the IDataSource interface on the object (line 398)

13 N

Page 48: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 48

20001008

Fields (ro) Returns the Fields collection for the object (line 418)

Line 418 retrieves the ADO Fieldscollection associated with a Public Folder Tree. See Sample 24 on page 62 for the EnumFieldsCollection() function.

Management Point 11 Retrieving the Public Folder Tree properties with CDOEXM

At this stage of the script, we have the following information:

• Public Folder Tree information for a Public Store. • The Tree type of the Root Folder Tree and other Tree properties. • The RootFolderURL to the Root Public Folder of the Folder Tree.

See points 13, N on Figure 4 on page 19 to locate this operation in the Exchange 2000 logical view.

Sample 17 on page 47 uses the Public Folder Tree name as a parameter (line 420) to explore the Public Folder Tree’s content. This is the point where the script will really enter into the Web Store.

Getting information about Folder tree in Mailboxes and Public Folders

Once the Russian doll has been opened up to the level of the Mailboxes and Public Folders, we can see that both contain some folders. Like a file system containing a directory (or a folder) hierarchy, Mailboxes or Public Folders contain folders. Let’s examine how to explore these folders.

Building the Web Store path to explore the content of a Folder in a Mailbox Sample 18 on page 49 is the continuation of Sample 11 on page 37 accessing the mailbox from an ADSI.User object.

Sample 19 on page 50 is the continuation of Sample 13 on page 41 accessing the mailbox from an CDO.Person object.

Whatever the origin of the object holding the mailbox configuration, both scripts (Sample 18 from ADSI and Sample 19 from CDOEX) are using the same method to access the mailbox content. Both scripts test if the currently logged-on user matches the alias of the examined mailbox. Because the Web Store security model does not by default allow access to the content of all mailboxes, the currently logged-on user only has the access to his mailbox. To have the script working, it is important that the Windows 2000 / Exchange 2000 installation uses a logon username identical to the mailbox alias. (See line 231 and/or line 160).

If this condition is met, the BrowseStoreFolder() function can be called. The parameter passed to this function is the FILE://./BackOfficeStorage pointer used to open the Web Store.

Note: It is very important to remember that all the scripts presented in this document must be running on the Exchange 2000 server. No remote access to the Web Store is possible via the Exchange 2000 OLE DB Provider.

10 K

Page 49: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 49

20001008

It is also possible to access the Web Store via the Exchange File System by browsing the contents of the file system folder tree (See Figure 5 below). Even if this method is practicable, only the access to each item's stream is accessible and no parsing of item content is made. To access item properties, an alternate mechanism must be used, such as the HTTP-DAV protocol, the Web Store OLE DB provider (ExOLEDB) with ADO 2.5, CDO for Exchange 2000 (CDOEX) or the Messaging API (MAPI).

Figure 5: The Web Store file system

The FILE://./:BackOfficeStorage pointer for a mailbox has the form:

File://./BackofficeStorage/MyDomainName.Com/MBX/MailboxAlias

The pointer is constructed at lines 236 (Sample 18) and 165 (Sample 19). The MailboxAlias is retrieved in:

• Sample 10 on page 35 at lines 60 and 61 for the ADSI procedure.

• Sample 12 on page 39 at lines 59 and 60 for the CDOEX procedure.

The MyDomainName.Com is the canonicalName LDAP property name retrieved in Sample 6 on page 26 at lines 89 and 90.

Next, the BrowseStoreFolder() function is called with the FILE://./BackOfficeStorage as a parameter. Sample 18 Building the Web Store pointer to explore the Folders content in a mailbox via ADSI

...:

...:220: ' At this level of the object hierarchy,221: ' we can create, move or delete a mailbox from the Mailbox Store.222: ' objUser.CreateMailBox223: ' objUser.DeleteMailBox224: ' objUser.MoveMailBox225:226: ' -------------------------------------------------------------------------

Page 50: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 50

20001008

227: ' We access the mailbox of the current logged user.228: ' So no security problems to run the script and accessing the mailbox.229: ' CONDITION: The mailbox alias and the username must be230: ' the same because we get the current username (account Name) from WSH.231: If strCurrentUserName = strAlias And cEnumMaiboxTree Then232:233: WScript.Echo Space (intX) & "Browsing mailbox '" & strDisplayName & "'."234:235: ' Construct the File://./BackofficeStorage/ pointer for MB236: BrowseStoreFolder "File://./BackofficeStorage/" & _237: strCanonicalNameDefaultDomain & "MBX/" & strAlias238:239: End If...:...:243: Next...:...:249:End Function

Sample 19 Building the Web Store pointer to explore the Folders content in a mailbox via CDOEX

...:

...:147: ' At this level of the object hierarchy,148: ' we can create, move or delete a mailbox from the Mailbox Store.149: ' objMailbox.CreateMailBox150: ' objMailbox.DeleteMailBox151: ' objMailbox.MoveMailBox152:153: Set objMailbox = Nothing154:155: ' -------------------------------------------------------------------------156: ' We access the mailbox of the current logged user.157: ' So no security problems to run the script and accessing the mailbox.158: ' CONDITION: The mailbox alias and the username must be159: ' the same because we get the current username (account Name) from WSH.160: If strCurrentUserName = strAlias And cEnumMaiboxTree Then161:162: WScript.Echo Space (intX) & "Browsing mailbox '" & strDisplayName & "'."163:164: ' Construct the File://./BackofficeStorage/ pointer for MB165: BrowseStoreFolder "File://./BackofficeStorage/" & _166: strCanonicalNameDefaultDomain & "MBX/" & strAlias167:168: End If...:...:172: Next...:...:179:End Function

Building the Web Store pointer to explore the Folders content in a Public Folder hierarchy Sample 20 on page 51 is using the same logic as the method used to construct the FILE://./BackOfficeStorage pointer for the mailbox. The only difference is the use of the Folder Tree name. See Sample 16 on page 45, line 377. This part of the code gets the Folder Tree membership from the examined Public Folder Store.

Note: The RootFolderURL property available from the CDOEXM.FolderTree object can be used to bind ADO to the root folder of the Public Store (See Table 7 on page 47). To use the same logic as the one used for the Mailbox, the script will not use the RootFolderURL and will build the FILE://.//BackOfficeStorage pointer in the same way as Sample 18 on page 49 and Sample 19 above.

14 O

Page 51: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 51

20001008

This Folder Tree name is a distinguishedName used as a data source in Sample 17 on page 47, line 398. In Sample 17, the name of the folder tree is used as a parameter to call the EnumPublicStore() function (line 420).

The form of the FILE://./BackOfficeStorage pointer for a Public Folder is: File://./BackofficeStorage/MyDomainName.Com/PublicFolderTreeName

This pointer is constructed at lines 435 and 436.

Note: It is important to run this script from an Exchange 2000 Server and in a test installation. It is not difficult to imagine the amount of data that can be collected from a Public Folder hierarchy if the script is run in a real production environment.

Next, the BrowseStoreFolder() function is called with the FILE://./BackOfficeStorage as a parameter. Sample 20 Building the Web Store pointer to explore the Folders content in a Public Folder hierarchy

428: Private Function EnumPublicStore (strFolderTreeName)429:430: If cEnumFolderTree Then431: intX = intX + 1432: WScript.Echo Space (intX) & "Browsing '" & strFolderTreeName & "'"433:434: ' Construct the File://./BackofficeStorage/ pointer for PF435: BrowseStoreFolder "File://./BackofficeStorage/" & _436: strCanonicalNameDefaultDomain & strFolderTreeName437: intX = intX - 1438: End If439:440: End Function

Exploring the Folders content The BrowseStoreFolder() function has the FILE://./BackOfficeStorage pointer as parameter. This parameter contained in the strURL variable will be used as an entry-point in the Web Store (See Sample 21 on page 53, line 18).

Note: Under Exchange 5.5, the access method to the Information Store was based on MAPI and made use of CDO 1.21. This access method is a client-server access method. This method is still supported under Exchange 2000 but as the samples of this document run locally on the server, Exchange 2000 provides an access method adapted to this circumstance.

In Sample 21 on page 53, the method used (lines 16 and 18) to open the Web Store is very simplified. But behind the scene many parameters are assumed for the ADO connection.

Actually, the piece of code: Method 1

Set objRecord = CreateObject("ADODB.Record")objRecord.Open strURL

could be coded in a more formal way as: Method 2

Set objConnection = CreateObject("ADODB.Connection")Set objRecord = CreateObject("ADODB.Record")

10 K

14 O

Page 52: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 52

20001008

objConnection.ConnectionString = strUrlobjConnection.Provider = "EXOLEDB.DATASOURCE"objConnection.OpenobjRecord.Open , objConnection

And to complete the opening methods, the next method can also be used: Method 3

Set objConnection = CreateObject("ADODB.Connection")Set objRecord = CreateObject("ADODB.Record")objConnection.Open "Provider=EXOLEDB.DATASOURCE; Data Source=" & strURL & ";"objRecord.Open , objConnection

All these methods are opening the Web Store in the same way.

Method 1 assumes some defaults. The strURL contains a FILE://./BackOfficeStorage pointer. Because the Exchange OLE DB Provider is registered in the system for this name space, there is no need to specify the Exchange 2000 OLE DB provider name. Behind the scene the objRecord is creating an objConnection object. This is why the script can be connected to the Web Store by opening an objrecord object.

Method 2 does not assume defaults and defines explicitly which OLE DB provider to use. (The name of the Exchange 2000 OLE DB provider is given). Method 3 is almost the same as the Method 2. Method 3 uses an ADO connection string but it uses exactly the same parameters. Both methods are good to avoid ambiguities. You are always sure that the script will use the Exchange OLE DB provider in any case because the Exchange 2000 OLE DB provider may accept different form of Web Store pointers.

In some cases, it is possible that the Web Store pointer is not a FILE://./BackOfficeStorage pointer. It is also possible to use a http://MachineName/Exchange/MailboxAlias pointer. The RootFolderURL property from the CDOEXM.FolderTree returns the same type of pointer. This property returns an http:// pointer to the Root of a Public Folders Tree. In such a case, Method 2 or Method 3 is mandatory. Using Method 1 will pose a problem because the default OLE DB provider used for this name space is the Internet Publishing OLE DB Provider.

Note: By default any pointer in form of an http:// pointer given to ADO without specifying explicitly the OLE DB provider to use will refer to the Internet Publishing OLE DB provider. This is the default provider registered for this name space.

Note: The OLE DB Provider for Internet Publishing, also known as the Internet Publishing Provider (IPP), allows developers to use OLE DB interfaces to access files and folders on HTTP servers supporting the FrontPage Web Extender Client (WEC) or Web Distributed Authoring and Versioning (WebDAV/HTTP-DAV) protocol extensions. The provider is currently installed with the full version of Internet Explorer 5.0 (which comes with Office 2000 or can be downloaded separately). It is installed by default with OLE DB 2.5 under Windows 2000. This extension uses IPP to provide the user with an Explorer-like access to files and folders published on WEC or DAV servers.

Note: IPP is built on top of HTTP-DAV, and there is no other option for its use. CDOEX is not supported on top of IPP.

When the OLE DB provider is not specified during the connection (Method 1), the name space of the OLE DB pointer is determinant. With an http:// pointer, the script must use Method 2 or Method 3 because both methods define explicitly the OLE DB provider to use.

Page 53: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 53

20001008

It is important to understand that even if the OLE DB pointer is an http:// pointer, there is no way to make a remote connection to the Exchange 2000 OLE DB provider. The Exchange 2000 OLE DB provider is not designed to work with remote connections. To make remote connections to the Web Store only HTTP-DAV or MAPI can be used. Sample 21 Exploring the Folders content

1:' VBScript function to enumerate folders content via ADO 2.5 on an Exchange server by '2:' using the FILE://./BackOfficeStorage pointer '3:' '4:' Version 1.00 - Alain Lissoir '5:' Compaq Computer Corporation - Professional Services - Belgium - '6:' '7:' Any comments or questions: EMail:[email protected] '8:9:Option Explicit10:11:' -----------------------------------------------------------------------------------12:Private Function BrowseStoreFolder (strURL)13:14:Dim objRecord15:16: Set objRecord = CreateObject("ADODB.Record")17:18: objRecord.Open strURL..:..:22: LoopInFolder objRecord23:24: objRecord.Close..:..:29:End Function30:31:' -----------------------------------------------------------------------------------32:Private Function LoopInFolder (objParentRecord)..:..:39: Set objRecordSet = objParentRecord.GetChildren40:41: While Not objRecordSet.EOF42:43: Set objChildRecord = CreateObject("ADODB.Record")44:45: objChildRecord.Open objRecordSet..:..:54: If cEnumFieldsCollection Then EnumFieldsCollection objChildRecord.Fields55:56: If objRecordSet ("DAV:iscollection") Then57: LoopInFolder objChildRecord58: Else59: If objChildRecord ("DAV:contentclass") = "urn:content-classes:message" Then60: If cEnumMessageContent Then EnumMessageContent objChildRecord("DAV:href")61: End If62: End If63:64: objChildRecord.Close..:..:69: objRecordSet.MoveNext70: Wend71:72: objRecordSet.Close..:..:77:End Function

Once the Web Store is opened (Line 18), the loop in the Folder hierarchy is started with the call to the LoopInFolder() function (line 22).

The LoopInFolder() function uses some ADO 2.5 enhancements to the navigation model. The line 39 uses the GetChildren method to get a RecordSet of the objects located below the current record.

Page 54: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 54

20001008

Note: Other ADO 2.5 useful enhancements are the CopyRecord and MoveRecord methods to enable prune and graft operations in the Web Store. Consult the ADO 2.5 SDK for more information on these methods and their related options.

The first LoopInFolder() call passes the FILE://./BackOfficeStorage pointer which is a root pointer to the Public Folder or to a mailbox. If the FILE://./BackOfficeStorage is a pointer to a Public Folder, the script gets the list of items and folders contained in the Public Folder. If it is a mailbox, the script gets the list of the folders contained in the mailbox (Inbox, Contacts, Calendar, …)

Next, for each item in the objRecordSet object, the script will loop until every item is examined (lines 41 to 70). Each item is opened (line 45) and its Fields collection enumerated (line 54). To determine if the examined item contains other items (such as a folder), one property from the Fields collection is tested: “DAV:iscollection”. This property returns “True” if the items contain other items. If it this the case, the script descends one level and iterates through every item found with the LoopInFolder() function.

If the item is not a collection, it is a data object (a leaf object). A data object can be a mail message, a calendar item, a contact item, a document, etc. The script will only decompose the message item because the purpose is to discover how a message is built and what the message object model offers to perform management tasks. This is the reason of the test at line 59. Of course, the script can be easily extended to examine a Calendar item or a Contact item.

Each discovered item has a content class so it means that this property will be in the Fieldscollection of every item discovered during the loop. This will allow you to review in the Excel sheet (line 54) the content type and any other property available from each item.

Once the item is explored, the script gets the next one (line 69) and the loop continues (line 70).

Based on the content class of a mail message, the Fields collection property “DAV:href” is passed as a parameter. This property contains a FILE://./BackOfficeStorage pointer to the message. See Sample 23 on page 56 to examine a mail message content.

Management Point 12 The Folder tree exploration

At this stage of the script, we have the following information:

• The content of a Folder and its children with the GetChildren method.

• The ability to move or copy a complete Folder with its content and its children with the MoveRecord and CopyRecord methods.

See points 10, 14 and K, O on Figure 4 on page 19 to locate this operation in the Exchange 2000 logical view.

Performing Simple Exchange Management tasks with Scripts

At this stage the Russian doll is almost exploded. Arriving at the end of the “encapsulation”, we reach the Items. An item can be a contact, a mail or anything else that can be contained by the Web Store. Even a folder can be seen as an item. By working with Web Store items, it is possible to perform some basic management tasks.

Page 55: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 55

20001008

Creating a folder and enabling its E-mail address Sample 21 on page 53 shows how to access a Web Store folder but from a management perspective, it can be interesting to create a folder in a Public Folder hierarchy and mail-enable this folder.

Doing so, the folder will be addressable by mail and, for instance, another script monitoring the miscellaneous Exchange 2000 server aspects (See “Exchange 2000 WMI Watcher” script in the second part of the document) can send a mail to an administrator and to this folder. As result, each alert will be logged and archived in the Public Folder.

With the IMailRecipient interface already used Sample 15 on page 44, it possible to enable an email address on a Folder in the Web Store. This is the purpose of Sample 22 below. Sample 22 Enabling E-mail on a Folder located in a Public Store

1:<!—- VB Script to make create a sub-Folder in the Public Folder tree. -->2:<!-- Once the folder created or opened, it e-mail enable this sub folder. -->3:<!-- -->4:<!-- Version 1.00 - Alain Lissoir -->5:<!-- Compaq Computer Corporation - Professional Services - Belgium - -->6:<!-- -->7:<!-- Any comments or questions: EMail:[email protected] -->8:9:<job>10:11: <object Id="objConnection" ProgID="ADODB.Connection" Reference=True />12: <object Id="objRecord" ProgID="ADODB.Record" Reference=True />13: <object Id="objFolder" ProgID="CDO.Folder" Reference=True />14:15: <script language="VBScript">16:17: Option Explicit18:19: Const cDomain = "VirtualCompany.Com"20: Const cFolderName = "MyMail-EnabledFolder"21:22: Dim strURLOpen23: Dim strURLItem24:25: Dim objMailRecipient26:27: strURLOpen = "File://./BackofficeStorage/" & _28: cDomain & "/Public Folders"29: strURLItem = "File://./BackofficeStorage/" & _30: cDomain & "/Public Folders/" & cFolderName31:32: Wscript.Echo strURLOpen33:34: objConnection.Open "Provider=EXOLEDB.DATASOURCE; Data Source=" & strURLOpen & ";"35:36: Wscript.Echo strURLItem37:38: objRecord.Open strURLItem, _39: objConnection, _40: adModeReadWrite, _41: adCreateCollection Or adOpenIfExists42:43: objFolder.DataSource.Open strURLItem44:45: Set objMailRecipient = objFolder.GetInterface ("IMailRecipient")46:47: objMailRecipient.MailEnable48: objFolder.DataSource.Save49:50: Set objMailRecipient = Nothing51:52: objRecord.Close53:54: Wscript.Echo "Completed."55:56: </script>57:</job>

15 P

16 Q

17 R

Page 56: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 56

20001008

This sample has three points of interest:

• It uses an object instantiation capability provided by WSH and not the traditional CreateObject() function from the VB run-time libraries (lines 11, 12 and 13). Note the “reference” parameter assigned to True. This allows retrieving the object type libraries definitions associated to each object. This is why the script can use the three constants used at lines 40 and 41 without the Const declaration statement.

• It uses ADO 2.5 to open a data source on the Parent Folder level. In the sample case, the Root Public Folder itself (line 34).

• The script opens a Record object with the connection established before (line 34) to create the desired folder (lines 38 to 41). Note the “adCreateCollection Or adOpenIfExists” statement to allow folder opening if it exists or a folder creation if it does not exist.

Once the folder is created (lines 38 to 41), the CDO.Folder object instantiated at line 13 opens a data source with the FILE://./BackOfficeStorage URL of the new folder (line 43). Next, the logic is the same as prior samples (See Sample 13 on page 41 or Sample 15 on page 44), the CDO.Folder object is aggregated to the IMailRecipient interface (line 45) to enable its email address.

Management Point 13 Enabling e-mail on a Folder

At this stage of the script, we have the following information:

• The ability to create a folder in the Store. • The ability to mail-enable or mail-disable a Folder from the

CDO.Folder object. See points 15, 16, 17 and P, Q, R on Figure 4 on page 19 to locate this operation in the Exchange 2000 logical view.

Examining message content The FILE://./BackOfficeStorage message pointer is contained in the strURL variable passed as a parameter to the function EnumMessageContent() (See Sample 23 below). This pointer can be used by CDO for Exchange 2000 as a pointer to the data source. The access to the message item is completed at line 27, just after the message object instantiation (line 26). Once the message object is connected to the data source, it is possible to review the message properties (lines 34 to 52).

Line 57 retrieves the ADO Fieldscollection associated with a CDO message object. See Sample 24 on page 62 for the EnumFieldsCollection() function. Sample 23 Examining mail message content

1:' VB Script function enumerating message content from a CDOEX object. '2:' '3:' Version 1.00 - Alain Lissoir '4:' Compaq Computer Corporation - Professional Services - Belgium - '5:' '6:' This function needs an inclusion or definition in the parent of the folloWing: '7:' '8:' Functions: '9:' '10:' EnumFieldsCollectionFunction.vbs '11:' '12:' Constants: '13:' '14:' cEnumFieldsCollection '15:' '16:' Any comments or questions: EMail:[email protected] '

11 L

18 S

Page 57: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 57

20001008

17:18:Option Explicit19:20:' ---------------------------------------------------------------------------------------21:Function EnumMessageContent (strURL)..:..:26: Set objMessage = CreateObject ("CDO.Message")27: objMessage.DataSource.Open strURL..:..:34: DisplayText "AutoGenerateTextBody(CDOEX)", objMessage.AutoGenerateTextBody35: DisplayText "BCC(CDOEX)", objMessage.BCC36: DisplayText "CC(CDOEX)", objMessage.CC37: DisplayText "DSNOptions(CDOEX)", objMessage.DSNOptions38: DisplayText "FollowUpTo(CDOEX)", objMessage.FollowUpTo39: DisplayText "From(CDOEX)", objMessage.From40: DisplayText "HTMLBody(CDOEX)", objMessage.HTMLBody41: DisplayText "Keywords(CDOEX)", objMessage.Keywords42: DisplayText "MDNRequested(CDOEX)", objMessage.MDNRequested43: DisplayText "MIMEFormatted(CDOEX)", objMessage.MIMEFormatted44: DisplayText "Newsgroups(CDOEX)", objMessage.Newsgroups45: DisplayText "Organization(CDOEX)", objMessage.Organization46: DisplayText "ReceivedTime(CDOEX)", objMessage.ReceivedTime47: DisplayText "ReplyTo(CDOEX)", objMessage.ReplyTo48: DisplayText "Sender(CDOEX)", objMessage.Sender49: DisplayText "SentOn(CDOEX)", objMessage.SentOn50: DisplayText "Subject(CDOEX)", objMessage.Subject51: DisplayText "TextBody(CDOEX)", objMessage.TextBody52: DisplayText "To(CDOEX)", objMessage.To..:..:57: If cEnumFieldsCollection Then EnumFieldsCollection objMessage.Fields..:..:62: EnumFieldsCollection objMessage.Configuration.Fields..:..:65: ' At this level of the object hierarchy, it is possible to send, reply,66: ' forward, addAttachment, etc ... to a message.67: ' objMessage.AddAttachment68: ' objMessage.AddRelatedBodyPart69: ' objMessage.BodyPart70: ' objMessage.CreateMHTMLBody71: ' objMessage.Forward72: ' objMessage.Post73: ' objMessage.PostReply74: ' objMessage.Reply75: ' objMessage.ReplyAll76: ' objMessage.Send..:..:83:End Function

Line 62 uses via the IConfiguration interface. From this interface, the script retrieves the associated Fields collection. This interface is associated with a message object and contains the communication parameters used for the message such as the SMTP Server name, the SMTP Server port, the Authentication type and more. For more information about the IConfiguration interface see http://msdn.microsoft.com/library/psdk/cdosys/_cdosys_iconfiguration_interface.htm.

At this level of the hierarchy, many other actions related to a message can be executed. The message object contains methods to allow a script to forward to, reply to, post and send a message (lines 67 to 76).

Page 58: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 58

20001008

Management Point 14 The message object

At this stage of the script, we have the following information:

• The configuration of a message in the Web Store. • The ability to reply to, forward and send messages.

See points 11, 18 or L, S on Figure 4 on page 19 to locate this operation in the Exchange 2000 logical view.

Going deeper into the Exchange 2000 CDOEX COM objects hierarchy

The script covers many aspects of the Exchange 2000 CDOEX COM objects hierarchy but not all of them are examined. For instance, the script does not explore the Calendaring Folder and associated objects, the Contacts folder and associated objects, the Journal, The Notes folder, etc. The script also stops at the Message object level. It is possible to go deeper by looking at the message body parts. If the Message is a MIME message (Sample 23 on page 56, line 43), it is possible to use the IBodyPart interface (line 69) to decompose it.

The purpose of the “EnumAllInXL.Wsf” is to help the understanding of the Exchange 2000 COM objects hierarchy presented in Figure 4 on page 19. Having a good view of this hierarchy will help anyone who wants to write scripts or applications to manage Exchange 2000. The script shows which COM technology to use to manage a specific component. The reader can complete the set of information retrieved by adding:

• A Select Case statement to Sample 21 on page 53, line 59 for other content type objects

• A IBodyPart interface exploration process starting from the message object in Sample 23 on page 56.

Page 59: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 59

20001008

Exploration Output result

Figure 6: Exchange 2000 ESM Window

When “EnumAllInXL.Wsf” is running and while it is loading the information in an Excel sheet, the script displays the different steps executed during the exploration. For instance in Figure 7 on page 60, at lines 6 and 7, the script shows that the Exchange 2000 server information is retrieved from WMI (line 6) and CDOEXM (line 7).

In this example, the script is run on a machine named DC01-CPQ. The Exchange 2000 configuration used for the sample output in Figure 7 is a configuration with:

• 4 Storage Groups

o First Storage Group (line 9 in red).

� Mailbox Store A (line 11 in green).

� Mailbox Store B (line 81 in green).

� Public Folder Store A (line 87 in blue).

• Hierarchy Name: 'Public Folders'

� Public Folder Store E (line 119).

• Hierarchy Name: 'Public Folders Tree (E)'

o Second Storage Group (line 125 in red).

� Mailbox Store C (line 127 in green).

� Public Folder Store C (line 133 in blue).

• Hierarchy Name: 'Public Folders Tree (C)'

o Third Storage Group (line 139) in red.

Page 60: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 60

20001008

� Mailbox Store D (line 141 in green).

� Public Folder Store D (line 147 in blue).

• Hierarchy Name: 'Public Folders Tree (D)'

o Fourth Storage Group (line 153 in red).

� Mailbox Store E (line 155 in green).

� Public Folder Store B (line 161 in blue).

• Hierarchy Name: 'Public Folders Tree (B)'

The server is in an Exchange 2000 organization with 2 Exchange 2000 Servers:

• DC01-CPQ (Line 6 and 7)

• DC02-CPQ (Line 126 and 127)

The mailbox of the currently logged-on user running the script is examined from line 19 to 53. Any message present in the mailbox has also its properties loaded in Excel (line 36 to 41 and line 48 to 53).

Figure 7: The "EnumE2KInXL" Sample output 1:Microsoft (R) Windows Script Host Version 5.1 for Windows2:Copyright (C) Microsoft Corporation 1996-1999. All rights reserved.3:4:Found Exchange Organization called 'First Organization'.5:6: Reading Exchange Server 'DC01-CPQ' information via 'WMI'.7: Reading Exchange server 'DC01-CPQ' information via 'CDOEXM.ExchangeServer'.8: ADO Field count=379: Reading Storage Group 'First Storage Group' information via 'CDOEXM.StorageGroup'.10: ADO Field count=3311: Reading Mailbox Store DB 'Mailbox Store A' information via 'CDOEXM.MailBoxStoreDB'.12: ADO Field count=3913: Retrieving Person/mailbox list via 'ADSI/ADO' LDAP Query.14: Retrieving Person information 'SystemMailbox{70F...}' via 'CDO.Person'15: ADO Field count=5116: Retrieving mailbox information 'SystemMailbox{70F...}' via 'IMailboxStore CDOEXM' interface.17: Retrieving Person information 'LISSOIR Alain' via 'CDO.Person'18: ADO Field count=5519: Retrieving mailbox information 'LISSOIR Alain' via 'IMailboxStore CDOEXM' interface.20: Browsing mailbox 'LISSOIR Alain'.21: Browsing 'File://./BackofficeStorage/VirtualCompany.com/MBX/Alain.Lissoir' via 'ADO'.22: urn:content-classes:taskfolder='Tasks'23: ADO Field count=7224: urn:content-classes:notefolder='Notes'25: ADO Field count=7226: urn:content-classes:journalfolder='Journal'27: ADO Field count=7228: urn:content-classes:mailfolder='Drafts'29: ADO Field count=15730: urn:content-classes:contactfolder='Contacts'31: ADO Field count=18832: urn:content-classes:calendarfolder='Calendar'33: ADO Field count=11634: urn:content-classes:folder='Sent Items'35: ADO Field count=7236: urn:content-classes:message='TEST.EML'37: ADO Field count=15638: Examining message content via 'CDOEX'.39: ADO Field count=6740: Examining message Configuration via 'CDOEX'.41: ADO Field count=1542: urn:content-classes:folder='Deleted Items'43: ADO Field count=7244: urn:content-classes:folder='Outbox'45: ADO Field count=7246: urn:content-classes:mailfolder='Inbox'47: ADO Field count=15748: urn:content-classes:message='TEST.EML'49: ADO Field count=157

Page 61: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 61

20001008

50: Examining message content via 'CDOEX'.51: ADO Field count=6752: Examining message Configuration via 'CDOEX'.53: ADO Field count=1554: Retrieving Person information 'BLAKE Francis' via 'CDO.Person'55: ADO Field count=7056: Retrieving mailbox information 'BLAKE Francis' via 'IMailboxStore CDOEXM' interface.57: Retrieving Person information 'BOND James' via 'CDO.Person'58: ADO Field count=7059: Retrieving mailbox information 'BOND James' via 'IMailboxStore CDOEXM' interface.60: Retrieving Person information 'COOPER Dan' via 'CDO.Person'61: ADO Field count=6962: Retrieving mailbox information 'COOPER Dan' via 'IMailboxStore CDOEXM' interface.63: Retrieving Person information 'GORDON Artimus' via 'CDO.Person'64: ADO Field count=7065: Retrieving mailbox information 'GORDON Artimus' via 'IMailboxStore CDOEXM' interface.66: Retrieving Person information 'MORTIMER Philip' via 'CDO.Person'67: ADO Field count=7068: Retrieving mailbox information 'MORTIMER Philip' via 'IMailboxStore CDOEXM' interface.69: Retrieving Person information 'STEED John' via 'CDO.Person'70: ADO Field count=7071: Retrieving mailbox information 'STEED John' via 'IMailboxStore CDOEXM' interface.72: Retrieving Person information 'TSUNO Yoko' via 'CDO.Person'73: ADO Field count=7074: Retrieving mailbox information 'TSUNO Yoko' via 'IMailboxStore CDOEXM' interface.75: Retrieving Person information 'VALHARDI Jean' via 'CDO.Person'76: ADO Field count=6977: Retrieving mailbox information 'VALHARDI Jean' via 'IMailboxStore CDOEXM' interface.78: Retrieving Person information 'WEST James' via 'CDO.Person'79: ADO Field count=7080: Retrieving mailbox information 'WEST James' via 'IMailboxStore CDOEXM' interface.81: Reading Mailbox Store DB 'Mailbox Store B' information via 'CDOEXM.MailBoxStoreDB'.82: ADO Field count=3983: Retrieving Person/mailbox list via 'ADSI/ADO' LDAP Query.84: Retrieving Person information 'SystemMailbox{6AA...}' via 'CDO.Person'85: ADO Field count=5186: Retrieving mailbox information 'SystemMailbox{6AA...}' via 'IMailboxStore CDOEXM' interface.87: Reading Public Store DB 'Public Folder Store A' information via 'CDOEXM.PublicStoreDB'.88: ADO Field count=4889: Retrieving FolderTree 'Public Folders' information via 'CDOEXM'.90: ADO Field count=2191: Browsing 'Public Folders' tree.92: Browsing 'File://./BackofficeStorage/VirtualCompany.com/Public Folders' via 'ADO'.93: urn:content-classes:folder='MyFolder'94: ADO Field count=7295: urn:content-classes:mailfolder='Services'96: ADO Field count=15797: urn:content-classes:mailfolder='Professional Services'98: ADO Field count=15799: urn:content-classes:message='Part 2 - The combination of WSH-ADSI under Windows 2000.EML'100: ADO Field count=157101: Examining message content via 'CDOEX'.102: ADO Field count=65103: Examining message Configuration via 'CDOEX'.104: ADO Field count=15105: urn:content-classes:message='Part 1 - Understanding WSH and ADSI in Windows 2000.EML'106: ADO Field count=157107: Examining message content via 'CDOEX'.108: ADO Field count=65109: Examining message Configuration via 'CDOEX'.110: ADO Field count=15111: urn:content-classes:mailfolder='Customer Services'112: ADO Field count=157113: urn:content-classes:mailfolder='Marketing'114: ADO Field count=157115: urn:content-classes:mailfolder='Corporate Templates'116: ADO Field count=157117: urn:content-classes:folder='Internet Newsgroups'118: ADO Field count=72119: Reading Public Store DB 'Public Folder Store E' information via 'CDOEXM.PublicStoreDB'.120: ADO Field count=44121: Retrieving FolderTree 'Public Folders Tree (E)' information via 'CDOEXM'.122: ADO Field count=19123: Browsing 'Public Folders Tree (E)' tree.124: Browsing 'File://./BackofficeStorage/VirtualCompany.com/Public Folders Tree (E)' via 'ADO'.125: Reading Storage Group 'Second Storage Group' information via 'CDOEXM.StorageGroup'.

Page 62: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 62

20001008

126: ADO Field count=32127: Reading Mailbox Store DB 'Mailbox Store C' information via 'CDOEXM.MailBoxStoreDB'.128: ADO Field count=39129: Retrieving Person/mailbox list via 'ADSI/ADO' LDAP Query.130: Retrieving Person information 'SystemMailbox{A99...}' via 'CDO.Person'131: ADO Field count=51132: Retrieving mailbox information 'SystemMailbox{A99...}' via 'IMailboxStore CDOEXM' interface.133: Reading Public Store DB 'Public Folder Store C' information via 'CDOEXM.PublicStoreDB'.134: ADO Field count=44135: Retrieving FolderTree 'Public Folders Tree (C)' information via 'CDOEXM'.136: ADO Field count=19137: Browsing 'Public Folders Tree (C)' tree.138: Browsing 'File://./BackofficeStorage/VirtualCompany.com/Public Folders Tree (C)' via 'ADO'.139: Reading Storage Group 'Third Storage Group' information via 'CDOEXM.StorageGroup'.140: ADO Field count=32141: Reading Mailbox Store DB 'Mailbox Store D' information via 'CDOEXM.MailBoxStoreDB'.142: ADO Field count=39143: Retrieving Person/mailbox list via 'ADSI/ADO' LDAP Query.144: Retrieving Person information 'SystemMailbox{CE2...}' via 'CDO.Person'145: ADO Field count=51146: Retrieving mailbox information 'SystemMailbox{CE2...}' via 'IMailboxStore CDOEXM' interface.147: Reading Public Store DB 'Public Folder Store D' information via 'CDOEXM.PublicStoreDB'.148: ADO Field count=44149: Retrieving FolderTree 'Public Folders Tree (D)' information via 'CDOEXM'.150: ADO Field count=19151: Browsing 'Public Folders Tree (D)' tree.152: Browsing 'File://./BackofficeStorage/VirtualCompany.com/Public Folders Tree (D)' via 'ADO'.153: Reading Storage Group 'Fourth Storage Group' information via 'CDOEXM.StorageGroup'.154: ADO Field count=32155: Reading Mailbox Store DB 'Mailbox Store E' information via 'CDOEXM.MailBoxStoreDB'.156: ADO Field count=39157: Retrieving Person/mailbox list via 'ADSI/ADO' LDAP Query.158: Retrieving Person information 'SystemMailbox{CBD...}' via 'CDO.Person'159: ADO Field count=51160: Retrieving mailbox information 'SystemMailbox{CBD...}' via 'IMailboxStore CDOEXM' interface.161: Reading Public Store DB 'Public Folder Store B' information via 'CDOEXM.PublicStoreDB'.162: ADO Field count=44163: Retrieving FolderTree 'Public Folders Tree (B)' information via 'CDOEXM'.164: ADO Field count=19165: Browsing 'Public Folders Tree (B)' tree.166: Browsing 'File://./BackofficeStorage/VirtualCompany.com/Public Folders Tree (B)' via 'ADO'.167: Reading Exchange Server 'DC02-CPQ' information via 'WMI'.168: Reading Exchange server 'DC02-CPQ' information via 'CDOEXM.ExchangeServer'.169: ADO Field count=37

Formatting the collected data

The EnumFieldCollection() function is only used to ease the data formatting of the information retrieved from Exchange 2000. This function simply enumerates a Fields collection passed as a parameter. The only restriction applied by this function is when a retrieved property is an array, instead of formatting all the elements of the array, the function assigns a string <array> to the value loaded in Excel. The purpose is simply to minimize the amount of data. Sample 24 Enumerating the Fields collection and formatting the collected data

1:' VB Script function enumerating the Fields collection from a CDO object. '2:' If the value is printable, the content is displayed other the variant '3:' value type is displayed '4:' '5:' This function uses a DisplayText function defined in the caller module. '6:' '7:' Version 1.00 - Alain Lissoir '8:' Compaq Computer Corporation - Professional Services - Belgium - '9:' '10:' Any comments or questions: EMail:[email protected] '11:12:Option Explicit13:14:' ------------------------------------------------------------------------------15:Function EnumFieldsCollection (objFields)..:..:

Page 63: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 63

20001008

25: For Each objField In objFields26:27: If IsArray (objFields (objField.Name)) Then..:33: DisplayField objField.Name, "<Array>"..:36: Else37: DisplayField objField.Name, objFields (objField.Name)38: End If39:40: Next..:44:End Function45:46:' ------------------------------------------------------------------------------47:Function DisplayField (strName, varValue)48:49:Dim strToDisplay50:51: Select Case VarType (varValue)52: Case vbInteger, _53: vbLong, _54: vbSingle, _55: vbDouble, _56: vbCurrency, _57: vbDate, _58: vbString, _59: vbBoolean60: strToDisplay = varValue61:62: ' We skip what is not printable on the screen.63: Case vbEmpty64: strToDisplay = "(vbEmpty)"65: Case vbNull66: strToDisplay = "(vbNull)"67: Case vbObject68: strToDisplay = "(vbObject)"69: Case vbError70: strToDisplay = "(vbError)"71: Case vbVariant72: strToDisplay = "(vbVariant)"73: Case vbDataObject74: strToDisplay = "(vbDataObject)"75: Case vbByte76: strToDisplay = "(vbByte)"77: Case vbArray78: strToDisplay = "(vbArray)"79:80: Case Else81: strToDisplay = "(VariantType:" & VarType (varValue) & ")"82:83: End Select84:85: DisplayText strName & "(ADO Field)", strToDisplay86:87:End Function

Page 64: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 64

20001008

Conclusion Exchange 2000 has a lot of new concepts and technologies oriented to the future. To learn the new Exchange 2000 features, the key is to learn the technologies based on industry standards such as LDAP and X.500, HTTP-DAV, XML, IMAP4, SMTP and X.400, etc. Learning about these standards goes a long way towards learning Windows 2000 and Exchange 2000 in general.

By adding COM abstraction layers based on these standards (for instance, CDO for Exchange 2000 or HTTP-DAV), Microsoft has moved its Exchange technology to Internet standards. The knowledge of the COM object model in environments like Windows 2000 and Exchange 2000 is key to developing new applications.

From an enterprise management point of view, the Windows Management Instrumentation (WMI) and CDO for Exchange Management (CDOEXM) are two key players in the enterprise management strategies.

Developing under Windows 2000 and Exchange 2000 changes the challenges from learning the programming language to learning the industry standards and the COM abstraction layers.

Page 65: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 65

20001008

APPENDIX

An overview of the Exchange 2000 WMI Providers The three WMI providers: ExchangeRoutingTableProvider, ExchangeQueueProvider and ExchangeClusterProvider provide an easy way for any application to access Exchange 2000 management information. Each of the three providers relates to a specific component set of Exchange 2000.

• The ExchangeRoutingTableProvider runs on top of the routing API.

• The ExchangeQueueProvider runs on top of the Queue API.

• The ExchangeClusterProvider runs on top of the Cluster API.

Each of these providers delivers information to ease the notification and the diagnostic of some problems that may occur in Exchange 2000.

Figure 8: Exchange 2000 WMI Providers

Exchange 2000 WMI Routing Table Provider

The Exchange Routing Table WMI provider is working on top of the Exchange Transport Core. The purpose of this provider is not to read the content of the routing table of Exchange 2000 to provide information about the existing routes available. Rather its purpose is as follows:

• To publish the status of the local Exchange 2000 server in the routing table based on the monitoring conditions configured with the ESM.

• To retrieve the status of other Exchange 2000 servers in the Organization from the routing table based on the monitoring conditions configured with the ESM.

• To publish the status of the Exchange 2000 local connectors in the routing table.

Page 66: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 66

20001008

• To retrieve the status of other Exchange 2000 connectors present the Organization from the routing table.

The routing table is used as a transport to publish the local status of the server and the local connectors states in the Organization. To perform this task, the WMI routing Table provider implements a dedicated way of access to and from the routing table only for the System Attendant. Every Exchange 2000 server in the Organization is publishing its state in the routing table in this way. This means that it is possible from one server to get the status of all the servers and connectors in the enterprise as they are seen from that server.

To distinguish the information retrieved between the server and the connectors, the WMI Routing Provider implements two WMI classes: ExchangeServerState and ExchangeConnectorState.

Each of these classes has a specific set of properties.

The ExchangeServerState class The states retrieved from this class are based on the monitoring conditions set with the ESM. Different information states are available from this class for the critical components of an Exchange 2000 server installation. The ESM allows an Administrator to configure a set of conditions determining a state for the monitored component (Figure 9 below). With the ESM, it is possible to define a monitoring condition with a corresponding state for:

• The Queues

• The disk space available on any disk in the system.

• The memory usage.

• The CPU usage for a “warning” and/or a “critical” threshold.

• Any Windows 2000 services relevant to Exchange 2000.

Figure 9: Exchange System Manager configuration settings for monitoring

Page 67: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 67

20001008

Figure 10: Exchange System Manager configuration settings for CPU monitoring

The ESM monitoring configuration UI is saved as a string in the Configuration Naming Context of the Active Directory. No direct programming of the WMI infrastructure is done from the ESM. The System Attendant is performing the WMI programming by reading the same string from Active Directory Configuration context.

Figure 11: The ESM Status view

When an Administrator looks at the monitoring status in the ESM, the ESM is interrogating the ExchangeRoutingTable provider via the WMIMGMT layer (See Figure 8 on page 65) and displays the ServerStateString property of the ExchangeServerState class and the IsUP property from the ConnectorState class. The ESM display is refreshed on a regular time interval basis or can be refreshed by the Administrator.

These statuses are visible in the ESM status view on Figure 11.

Page 68: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 68

20001008

Let’s examine the ExchangeServerState class properties and their meanings: Table 8 The ExchangeServerState WMI Class

Name The name of the Exchange 2000 server.

DN The distinguishedName of the Exchange 2000 server object in the Active Directory.

GUID The GUID of the Exchange 2000 server in the Active Directory.

Version The build number of the Exchange 2000 server software..

GroupDN The distinguishedName of the routing group containing Exchange 2000 server.

Unreachable If set to True, this property means that the Exchange server has a connectivity problem with the Master of its routing group.

ServerMaintenance If set to True, this property means that the monitoring settings have been disabled from the ESM

ServerStateString ‘Unknown’ , ‘Available' , 'Warning' or 'Critical' string applicable for the monitoring conditions configured in the ESM

ServerState Numeric values corresponding to ServerStateString. Unknown=0, Available=1, Warning=2, Critical=3.

QueuesStateString ‘Unknown’ , ‘Available' , 'Warning' or 'Critical' string applicable for the monitoring conditions configured in the ESM

QueuesState Numeric values corresponding to QueueStateString. Unknown=0, Available=1, Warning=2, Critical=3.

DisksStateString ‘Unknown’ , ‘Available' , 'Warning' or 'Critical' string applicable for the monitoring conditions configured in the ESM

DisksState Numeric values corresponding to DiskStateString. Unknown=0, Available=1, Warning=2, Critical=3.

MemoryStateString ‘Unknown’ , ‘Available' , 'Warning' or 'Critical' string applicable for the monitoring conditions configured in the ESM

MemoryState Numeric values corresponding to MemoryStateString. Unknown=0, Available=1, Warning=2, Critical=3.

CPUStateString ‘Unknown’ , ‘Available' , 'Warning' or 'Critical' string applicable for the monitoring conditions configured in the ESM

CPUState Numeric values corresponding to CPUStateString. Unknown=0, Available=1, Warning=2, Critical=3.

ClusterStateString ‘Unknown’ , ‘Available' , 'Warning' or 'Critical' string applicable for the monitoring conditions configured in the ESM

ClusterState Numeric values corresponding to ClusterStateString. Unknown=0, Available=1, Warning=2, Critical=3.

ServicesStateString ‘Unknown’ , ‘Available' , 'Warning' or 'Critical' string applicable for the monitoring conditions configured in the ESM

ServicesState Numeric values corresponding to ServicesStateString. Unknown=0, Available=1, Warning=2, Critical=3.

Note: The reason to have the string variable and the numeric variable for the server states is that the string variable is localized for the non-English versions of Exchange 2000.

The ExchangeConnectorState class The ExchangeConnectorState class is based on the same principle as the ExchangeServerState class. The class provides a monitoring capability of the connectors configured in an Exchange Organization. The state is published in the routing table. When this class is interrogated from the ESM or by a script, the class offers a list of the connectors available from the routing table with their corresponding status. Using this class, it is possible to know the current state of all the connectors in the Exchange 2000 Organization as seen from that server.

Page 69: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 69

20001008

Table 9 The ExchangeConnectorState WMI class

DN The distinguishedName of the Exchange connector object in Active Directory.

Name The name of the Exchange connector.

GUID The GUID of the Exchange connector object in Active Directory.

GroupDN The distinguishedName of the routing group containing the Exchange connector.

IsUP The state of the connector

Exchange 2000 WMI Queue Provider

The WMI Queue provider is based on the Queue API. It does not use any mechanism to publish or retrieve any information from the routing table with the help of the WMI Routing Table provider. The scope of this provider is local to the Exchange 2000 server. The provider implements two WMI classes:

• The ExchangeLink class to retrieve information about the Exchange links directly from the Queue API.

• The ExchangeQueue class to retrieve information about the Exchange queues directly from the Queue API.

For both classes, most of the properties are the one exposed by the Queue API.

From a scripting and management perspective, for both classes, the most interesting data is the IncreasingTime property (See Sample 3 on page 23 and Sample 4 on page 24). The Queue API does not provide this property directly. This is a property calculated by the WMI Queue provider.

Figure 12: The IncreasingTime property behavior from the ExchangeLink and ExchangeQueue classes

The IncreasingTime value represents the length of time while the number of messages in the Link/Queue has not decreased. The time is returned in milliseconds. To monitor this property, it is important to understand how is the calculation made. Two important factors influence how to monitor the value:

Page 70: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 70

20001008

• The sampling frequency (Tx interval on Figure 12 on page 69)

• The IncreasingTime value threshold to determine a critical situation

Each time a sample is taken, the IncreasingTime property is calculated and a new value is determined. The first polling interval (A on Figure 12) always returns an IncreasingTime value of zero because it is the first sample read. But when the second polling interval occurs (A’ on Figure 12), the IncreasingTime value will be equal to the T1 interval because the number of message has not decreased between A and A’.

When the next polling interval occurs (B on Figure 12), the IncreasingTime value will be equal to zero because the number of messages has decreased between A’ and B. It is important to note that the number of messages has decreased below the prior measured level. If the number of message level does not decrease below the prior level, the IncreasingTime value is equal to T1+T2. If the number of messages decreases to below the prior level, then the IncreasingTime value is set to zero.

For the same situation, if the polling interval is changed to measure at point A for the first sample and at point C for the second sample, the IncreasingTime value will not be equal to zero because the number of messages has not been detected as decreasing below the number of messages measured at point A. The IncreasingTime value will be equal to T1+T2+T3+T4.

Furthermore, if the polling is done between:

• A and B: IncreasingTime is equal to T1+T2.

• B and C: IncreasingTime is equal to T1+T2+T3+T4.

• C and D: IncreasingTime is equal to T1+T2+T3+T4+T5+T6.

• D and E: IncreasingTime is equal to zero.

Now if the polling is done in the following way:

• A and A’: IncreasingTime is equal to T1.

• A’ and B: IncreasingTime is equal to zero.

• B and B’: IncreasingTime is equal to T3.

• B’ and C: IncreasingTime is equal to T3+T4.

• C and C’: IncreasingTime is equal to T3+T4+T5.

• C’ and D: IncreasingTime is equal to T3+T4+T5+T6.

• D and D’: IncreasingTime is equal to zero.

• D’ and E: IncreasingTime is equal to T8.

• E and E’: IncreasingTime is equal to zero.

By changing the sampling frequency, we see that the IncreasingTime value can be very different. With the slowest sampling frequency, we miss the decreasing period between A and B. With the fastest polling frequency, this decreasing period is detected. Now, it is important to look at this behavior in a real time scale.

If we suppose that the Tx interval is equal to 1 minute, the alert threshold for the IncreasingTime value set on 30000ms (30s) and the polling interval sets every Tx (every 1 minute), you will get a notification at point A’. This will be useless because the queue has decreased between A’ and B. It is clear that you don’t want to be notified for such situation. In a production environment the number of messages can increase suddenly for 1 minute (or more) but the number of message can decrease rapidly in the next minutes. In such case, you get an alert for a non-critical situation.

Page 71: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 71

20001008

Now, if we suppose that the Tx interval is equal to 1 hour, the alert threshold for the IncreasingTime value set on 14400000ms (4h) and the polling interval sets every Tx (every 1 hour), you will only get a notification at point D. This is a better situation because you are notified for a non-decreasing situation after 4 hours. On the other hand it is a little bit too long to be notified because this situation may hide a real problem.

The key is to find a compromise between the polling intervals to detect quickly any non-decreasing situations without getting an alert for increasing situations that are temporary.

A best practice is to choose, for instance, to poll every of 10s and an IncreasingTime threshold value of 1800000ms (30min). In this situation, the flow represented on Figure 12 will never generate an alert. Only real non-decreasing situations longer than a half-hour will be detected with a precision of 10s. Table 10 The ExchangeLink WMI class

LinkName Name of the link

ProtocolName Name of the protocol used by the link (i.e. SMTP)

VirtualServerName Name of the Protocol Virtual Server Name

VirtualMachine Name of the server hosting the link

Version Version of the link

NumberOfMessages Number of messages in queue in the link

NextScheduledConnection Date/Time of the next connection attempt

OldestMessage Date/Time of the oldest message in the queue

SizeOfQueue Size of the queue in bytes

LinkDN distinguishedName of the link

ExtendedStateInfo Information message

Value below is calculated by the WMI provider (Class ExchangeLink) IncreasingTime Time during which the number of messages in queue has not decreased

StateFlags Flags determining the link behavior Values below are coming from the StateFlags property and are provided by the WMI provider (Class ExchangeLink)

StateActive True when the link has an active connection transferring mail

StateReady True when the link is ready for a connection, but there are no connections

StateRetry True when the link is waiting for the retry interval to elapse

StateScheduled True when the link is waiting for the next scheduled time

StateRemote True when the link is to be activated by remote server. A connection will not be made unless requested by a remote server (like TURN/ETRN)

StateFrozen True when the link is frozen by administrative action

TypeRemoteDelivery Messages on link are being delivered remotely. This is the default type of link (i.e. between 2 Routing Groups)

TypeLocalDelivery True when the link delivers message locally. (i.e. to a local Mailbox store)

TypePendingRouting True when it is an internal queue where messages are stored while the systemdetermines how to route them. Messages on this link have not been routed to their next hop

TypePendingCategorization True when messages are stored while they are pending address lookup and DLexpansion

TypeCurrentlyUnreachable

True when this is a holding queue where messages are stored when all current routes are down or messages on this link do not have an available route to their finaldestination. This is due to transient network or server errors. These messages will beretried when a route becomes available

TypeDeferredDelivery True when this is the deferred delivery queue (using Outlook, a property to defer amessage for later delivery can be set)

TypeInternal Generic catch all for internal queues.

SupportedLinkActions Represent the various operations that can be performed on a link via the Queue API. Values below are coming from the SupportedLinkActions property and are provided by the WMI provider (Class ExchangeLink)

ActionKick True if a “Force a connection” can be made for this link via the Queue API. This will even work for connections pending retry or a scheduled connection

Page 72: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 72

20001008

ActionFreeze True if “Prevent outbound connections from” can be made for the link via the QueueAPI.

ActionThaw True if “Undo a previous admin freeze action” can be made for the link via the Queue API.

Table 11 The ExchangeQueue WMI class

ProtocolName Name of the protocol used by the queue (i.e. SMTP)

VirtualServerName Name of the Protocol Virtual Server Name

QueueName Name of the Queue

VirtualMachine Name of the system hosting the queue

Version Version of the queue

NumberOfMessages Number of message in queue

SizeOfQueue Size of the queue in bytes

Value below calculated by the WMI provider (Class ExchangeQueue)

IncreasingTime Time during which the number of messages in queue has not decreased

MsgEnumFlagsSupported Represent the various enumerations that can be performed on a queue via the QueueAPI.

Values below are coming from the MsgEnumFlagsSupported property CanEnumFirstNMessages True if queue can enumerate “N first messages” via the Queue API.

CanEnumSender True if queue can enumerate “sender via” the Queue API.

CanEnumRecipient True if queue can enumerate “recipient via” the Queue API.

CanEnumLargerThan True if queue can enumerate “messages larger” than via the Queue API.

CanEnumFrozen True if queue can enumerate “frozen messages” via the Queue API.

CanEnumNLargestMessages True if queue can enumerate “N largest messages” via the Queue API.

CanEnumNOldestMessages True if queue can enumerate “N oldest messages” via the Queue API.

CanEnumFailed True if queue can enumerate “messages with a failed delivery attempts” via the QueueAPI.

CanEnumAll True if queue can enumerate “all the messages” via the Queue API.

CanEnumInvertSense True if queue can enumerate “messages based on an inverted filter” via the Queue API.

Exchange 2000 WMI Cluster Provider

The Cluster WMI provider implements only one class directly based on the cluster service. The State property contains the state of the Cluster group. Table 12 The ExchangeClusterResource WMI class

VirtualMachine The name of the Cluster group

Name The name of the member in the cluster group

Type

Windows Clustering defines several types of resources and provides resource DLLs to manage these types. The following default resource types are included with all server clusters: DHCP Service Distributed Transaction Coordinator File Share Generic Application Generic Service IP Address Message Queuing Network Name Physical Disk Print Spooler WINS Service

State The state of the Cluster group

Page 73: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 73

20001008

ADSI Functions helper

Note: The reader may refer to the Compaq Active Answer web site for other publications about ADSI (from the same author):

http://www.compaq.com/ActiveAnswers

“Part 1 - Understanding Microsoft WSH and ADSI in Windows 2000”

“Part 2 - The powerful combination of WSH and ADSI under Windows 2000”

Getting the Exchange Organization Name

The Exchange Organization name is located in the Active Directory Configuration Naming Context. Only one Exchange 2000 Organization per Windows 2000 Forest is supported. A simple ADSI script can retrieve the Exchange Organization name by looking in the container dedicated to Exchange 2000. This is the purpose of Sample 25 below. The script makes a loop (lines 33 to 41) and returns the cn (line 38) of the first msExchOrganizationContainer object class found. Of course, if a Forest was able to support many Exchange Organizations, this method is not valid. Today under Windows 2000 and Exchange 2000, only one Organization is supported.

This function is used in Sample 6 on page 26 and in “Moving mailboxes from ADSI.User and CDO.Person objects based on a LDAP query” sample included in the second part of this document. Sample 25 Retrieving the Exchange Organization name

1:' VB Script to verify the presence of Exchange 2000 and to return the organization name '2:' '3:' Version 1.00 - Alain Lissoir '4:' Compaq Computer Corporation - Professional Services - Belgium - '5:' '6:' Any comments or questions: EMail:[email protected] '7:8:Option Explicit9:10:' --------------------------------------------------------------------------------------11:Function GetExchangeOrg ()..:..:18: On Error Resume Next19:20: Set ObjRoot = GetObject("LDAP://RootDSE")21: strConfigNC = ObjRoot.Get("configurationNamingContext")22: WScript.DisconnectObject ObjRoot23: Set ObjRoot = Nothing24:25: Set objExchangeContainer = GetObject ("LDAP://CN=Microsoft Exchange,CN=Services," &26: strConfigNC)27: If Err.Number Then28: ' Exchange container in services not present, Exchange 2000 is not installed29: GetExchangeOrg = ""30: Exit Function31: End If32:33: For Each objExchangeOrg In objExchangeContainer34: If (objExchangeOrg.Class = "msExchOrganizationContainer") Then35: Wscript.Echo "Found Exchange Organization called '" & _36: objExchangeOrg.Get ("cn") & "'."37: Wscript.Echo38: GetExchangeOrg = objExchangeOrg.Get ("cn")39: Exit Function40: End If41: Next

Page 74: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 74

20001008

42:43: GetExchangeOrg = ""44:45:End Function

Querying the Active Directory with ADSI and ADO

Querying the Active Directory from the scripting world means using ADO (See Figure 2 on page 17). As explained on page 16, ADO relies on ADSI by the presence of an Active Directory OLE DB provider. This OLE DB provider allows search operations against the Active Directory. ADO is used to establish the connection to this provider and transmit the query command to execute. If a change to the data retrieved from the search must be done after the query, ADSI must be used, not ADO. The Active Directory OLE DB provider is a read-only provider.

The purpose of the document is not to focus on ADSI with ADO. The function is given for reference purposes. This function is used in Sample 10 on page 35, in Sample 12 on page 39 and in “Moving mailboxes from ADSI.User and CDO.Person objects based on a LDAP query” sample included in the second part of this document.. Sample 26 Searching in the Active Directory

1:' VB Script making search operations in AD through ADSI OLE DB interface via ADO '2:' '3:' ADSearchFunction1.vbs '4:' This function handles the multi-values properties and return each elements one '5:' by one. '6:' '7:' '8:' Version 1.00 - Alain Lissoir '9:' Compaq Computer Corporation - Professional Services - Belgium - '10:' '11:' Any comments or questions: EMail:[email protected] '12:13:Option Explicit14:15:' -------------------------------------------------------------------------------------16:Function ADSearch _17: (strNamingContextSearch, strFilterSearch, strAttribsToReturnSearch, _18: strDepthSearch, boolEcho)..:..:34: Set objDictionary = CreateObject ("Scripting.Dictionary")35:36: Set objADOConnnection = CreateObject("ADODB.Connection")37: objADOConnnection.Provider = "ADsDSOObject"38: objADOConnnection.Open "Active Directory Provider"39:40: Set objCommand = CreateObject("ADODB.Command")41: Set objCommand.ActiveConnection = objADOConnnection42:43: If Ucase (Mid (strNamingContextSearch, 1, 7)) = "LDAP://" Or _44: Ucase (Mid (strNamingContextSearch, 1, 5)) = "GC://" Then45:46: Set objNamingContext = GetObject(strNamingContextSearch)47: Else48: Set objRoot = GetObject("LDAP://RootDSE")49: strNamingContext = objRoot.Get(strNamingContextSearch)50: Set objRoot = Nothing..:..:56: Set objNamingContext = GetObject("LDAP://" & strNamingContext)57: End If58:59: strADsPathSearch = "<" & objNamingContext.ADsPath & ">"60:61: objCommand.CommandText = strADsPathSearch & ";" & _62: strFilterSearch & ";" & _63: strAttribsToReturnSearch & ";" & _64: strDepthSearch..:..:

Page 75: Part 1: Introduction to the use of Exchange 2000 with ...users.skynet.be/alain.lissoir/hp/Part 1... · Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical

Part 1: Introduction to the use of Exchange 2000 with Windows Script Host Technical Guide 75

20001008

67: If boolEcho Then WScript.Echo "Searching ..." & vbCRLF68: Set objRecordSet = objCommand.Execute69:70: objDictionary.Add "RecordCount", objRecordSet.RecordCount71:72: While Not objRecordSet.EOF73: For intIndice = 0 To objRecordSet.Fields.Count - 1..:..:91: ' Check if returned value is a multi-value92: If IsArray (objRecordSet.Fields(intIndice).Value) Then93: intElements = 094: For Each varElements in objRecordSet.Fields(intIndice).Value95: objDictionary.Add objRecordSet.Fields(intIndice).Name & ":" & _96: objRecordSet.AbsolutePosition & "/" & _97: intIndice & ":" & intElements, _98: varElements99: intElements = intElements + 1100: Next101: Else102: objDictionary.Add objRecordSet.Fields(intIndice).Name & ":" & _103: objRecordSet.AbsolutePosition & "/" & intIndice, _104: objRecordSet.Fields(intIndice).Value105: End If106: Next...:...:110: objRecordSet.MoveNext111: Wend...:...:115: Set ADSearch = objDictionary116:117: Set objNamingContext = Nothing...:...:128:End Function