Whistler: Build More Flexible Console Snap-ins with the MMC 2.0 Object Model

Vivek Jhaveri
This article assumes you�re familiar with MMC, COM, VBScript, and XML
Level of Difficulty     1   2   3 
SUMMARY Microsoft Management Console (MMC) 2.0 provides a host of exciting new features for MMC users and snap-in developers. The new MMC 2.0 automation object model allows much of the user interface of MMC 2.0 to be accessed through script, and exposes events so that many tasks can now easily be automated. The new view extension model uses HTML to enable extensions to seamlessly integrate new user interfaces with those of existing snap-ins. MMC 2.0 also includes a specific view extension snap-in, the Extended View snap-in, which provides an interface similar to Web folders. Drag and drop support has been expanded, and console files now use the XML file format. Enhancements to console taskpads make it easier to accomplish tasks.

M icrosoft® Management Console (MMC) is the user interface and the point of integration for administration applications in Windows® 2000 and beyond. This article explores some of the enhancements and new features offered in MMC 2.0, and illustrates applications of each.
      Note that this is a preview of MMC 2.0, so some areas may change by the time the product is released. MMC 2.0 will be released as part of "Whistler," the codename for the successor to Windows 2000.

Introducing the Automation Object Model

      The most significant addition in MMC 2.0 is the automation object model. One goal of the object model was to allow much of the user interface of MMC to be accessible via script. This feature allows users and administrators to perform repetitive tasks using any automation-compatible programming language such as VBScript, JScript®, Visual Basic®, or even C++. Many of the objects supported by the object model should be familiar to anyone who has written macros for Microsoft Excel or Word.
      Many objects also have a one-to-one correspondence with the MMC user interface. For example, a Document object represents the console file. The Document object in turn has a Views collection which represents the set of currently opened views. The object model also exposes a rich set of events so that script can be made aware of actions that take place, such as a toolbar button click or the execution of a context menu item. Figure 1 shows the relationships of objects in the object model. (Please note that for clarity, a few miscellaneous objects are not shown.)
      Using the new object model, you can write a very simple script to start MMC, add a couple of snap-ins, configure the views in the console, and save the results to a new console file. The following script starts MMC, adds the Local Users and Groups snap-in, and saves the console to c:\console1.msc.

  ' Filename: Example1.vbs - add a snap-in and save the console file
  

Set mmc = wscript.CreateObject("MMC20.Application")
Set doc = mmc.Document

' Add the Local Users and Groups snap-in
doc.SnapIns.Add "Local Users and Groups"

doc.SaveAs("C:\console1.msc")
doc.Close(true)

 

      Another example illustrating the new programmability of MMC 2.0 is a script that can launch an existing console file, navigate down the scope pane (tree), select an item, and execute a command available on the item's menu. If you have ever wanted to display an MMC property sheet or wizard from another application, you can now easily do so by adding code that uses the MMC object model while keeping MMC itself invisible using the Application.Hide method.
      The script in Figure 2 starts the console created by the script shown in the previous code. Then it displays the property sheet for the first user displayed by the Local Users and Groups snap-in.
      Although the automation object model can be accessed from script code running outside MMC, in general the model is inaccessible to a snap-in. This is consistent with the MMC philosophy that snap-ins be self-contained and not rely on other snap-ins to be present in the console. Allowing a snap-in to have access to the object model would automatically give it access to all the other snap-ins in the console file and could introduce undesirable dependencies across snap-ins. However, there is one exception to this rule: a snap-in with HTML in its result pane can access the automation object model using the external keyword. The external keyword is the general mechanism that Microsoft Internet Explorer (which MMC hosts) provides to enable communication between HTML and the host application, in this case MMC. This mechanism is used by view-extension snap-ins, a topic I'll explore later.

Extending the Automation Object Model

      The basic MMC automation object model allows context menu items to be executed and property sheets and wizards to be displayed. However, it would be nice to be able to write scripts to make the sort of changes that are usually made using the property sheets and wizards. For example, now that you've brought up the property sheet using the script in Figure 2, you can add code to the script to change the Full Name field. The quick and dirty way to do this is to use something like Visual Basic or the VBScript SendKeys method to actually play out (simulate) the corresponding keystrokes inside the property sheet.
      There is a better way, but it requires the snap-in to extend the automation object model and provide additional scriptable commands that can be used to configure its objects. This is actually easier than it sounds. All snap-ins that add scope and result items already implement the QueryDataObject method on the IComponent and IComponentData interfaces. QueryDataObject returns a data object for a node or set of nodes. In a similar manner, MMC 2.0 defines two new interfaces, IComponent2 and IComponentData2, both of which expose methods called QueryDispatch. QueryDispatch returns an instance of IDispatch for the specified node or set of nodes.

Figure 3 Administrator Properties
Figure 3 Administrator Properties

      The IDispatch interface is at the heart of all automation. The commands exposed through the IDispatch interfaces returned by QueryDispatch are exposed in the object model via the View.SnapinScopeObject and View.SnapinSelection- Object methods. If the Administrator item in Figure 3 were to support an IDispatch interface that exposed a method called SetFullName(BSTR Name), your script could invoke the method like so:

  View.SnapinSelectionObject.SetFullName 'Vivek Jhaveri'
  

 

      What does this mean for the users of your snap-in? Once the functionality of your snap-in is made scriptable via MMC, administrators will be able to create a library of scripts for frequently used tasks. They will be able to schedule these scripts and run them without having to physically be present at the console. In short, you can add tremendous value to all the work that you have already put into your snap-in by making the most frequently performed operations directly accessible through the object model in MMC 2.0.
      There are three advantages to extending the MMC object model in order to write your own independent automation server. First, all your code stays in one place. Second, the amount of work a snap-in needs to do to extend the MMC object model is just a fraction of what would be required to create an independent object model. Finally, administrators who already know how to access your snap-in's functionality through the user interface will be able to quickly understand how to access the functionality through the object model.

Introducing View Extensions

      MMC 2.0 introduces a new snap-in extension mechanism, view extensions, which can augment the view of existing snap-ins or add completely new views. View extensions use HTML to provide a user interface, so the interface can include script to take advantage of the objects and events exposed by the MMC object model.
      To provide a richer user experience, MMC 2.0 includes a specific view extension snap-in, the Extended View snap-in, which provides an interface similar to Web folders. (I'll cover this more thoroughly in the section on the Extended View snap-in later in this article.) A snap-in can support the extended view by exposing a couple of new clipboard formats or by implementing the new INodeProperties interface. Figure 4 and Figure 5 illustrate the extended view using the Services snap-in and the Group Policy snap-in, both of which support the extended view in the upcoming version of Windows (codenamed Whistler). The screen areas called out in Figure 4 will be described in the next section.
      View extension snap-ins, like all extension snap-ins, register to extend one or more node types. When MMC displays the result pane for a node, it loads all view extensions for the node's type, along with all console taskpads for the node, into a tab selector.

Capabilities of View Extensions

      The purpose of view extensions is to enable the creation of UI elements that add value to an original result view for a snap-in. The feature is not intended to add entirely new management functionality; that is probably best served by namespace extensions or entirely new primary snap-ins. View extensions can make full use of the MMC 2.0 object model, DHTML, and script.
      When the tab corresponding to a view extension is selected, the HTML added by the view extension is loaded into the result pane, as you can see in Figure 4 and Figure 5. The HTML has complete control over the result pane. In Figure 4, the HTML used by the Extended View snap-in embeds the original result list view into the result pane along with additional information. You can embed the original result list view of the snap-in being extended by creating a region within the HTML and attaching the new mmcview behavior to it. This is a Dynamic HTML behavior supplied by MMC that positions the result view over the element to which it is attached. To illustrate, the following HTML fragment divides the result view vertically into two halves, and positions the snap-in's result view over the left half.

  <TABLE height='100%' WIDTH='100%'>
  
<TR>
<TD width='50%' STYLE="behavior:url(#default#mmcview)"></TD>
<TD></TD>
</TR>
</TABLE>

 

To learn more about behaviors, see the documentation for Internet Explorer 5.0.
      Since the DHTML displayed by the view extension is not connected to the back or forward buttons, view extensions should not display a UI that changes state in a way that would make it difficult to recreate the same view when the same scope node is revisited.
      Applications for view extensions readily come to mind. It's easy to envision a third-party view extension snap-in that extends server nodes in the Exchange 2000 System Administrator and provides a rich topological view of the server in the enterprise. View extensions could be created for a snap-in to make the snap-in more modular. Or, your snap-ins can use view extensions to simplify the user experience by displaying the most relevant tasks and information. And the list goes on.

Interfaces Implemented by View Extensions

      For snap-in developers, the following section is especially relevant. View extension snap-ins implement a single interface, IExtendView, which has a single method:

  interface IExtendView : IUnknown
  
{
HRESULT GetViews (
[in] LPDATAOBJECT pDataObject,
[in] LPVIEWEXTENSIONCALLBACK pViewExtensionCallback);
};

 

      The view extension callback interface pointer passed in is used to add views. MMC implements the callback, which has the following definition:

  interface IViewExtensionCallback : IUnknown
  
{
[helpstring("Adds a view to the result pane")]
HRESULT AddView([in] PMMC_EXT_VIEW_DATA pExtViewData);
};

 

      The MMC_EXT_VIEW_DATA structure has the following definition:

  typedef struct _MMC_EXT_VIEW_DATA
  
{
GUID viewID; // GUID used to describe the view.
// Used to restore a view.
LPCOLESTR pszURL; // URL describing extension page
LPCOLESTR pszViewTitle; // title of the view extension
LPCOLESTR pszTooltipText; // tooltip for the tab
BOOL bReplacesDefaultView; // TRUE == no "Standard" tab
} MMC_EXT_VIEW_DATA, *PMMC_EXT_VIEW_DATA;

 

      The view extension snap-in specifies the URL to the HTML used in the result pane; this usually points to an HTML resource in the snap-in's DLL. The snap-in also supplies a title for the view extension, a tooltip for the view, and specifies whether the Standard tab should be displayed by MMC. The Standard view refers to the original list view displayed by the snap-in that's being extended. If your view extension embeds the original result view of the primary snap-in (as you saw in Figure 4 and Figure 5), there is usually no need to display the Standard tab.

The Extended View Snap-in

      As I've already mentioned, a view extension is a type of snap-in that extends the view of any snap-in that it is registered to extend. To showcase the view extension model, MMC 2.0 will ship with a built-in view extension snap-in called the Extended View. The Extended View snap-in is a specific view extension snap-in, providing a user interface that is very similar to the Web View in Windows Explorer.
      The Extended View extension can be registered to extend any existing node type simply by registering its CLSID as a view extension of the node type. The CLSID of the Extended View extension is {B708457E-DB61-4c55-A92F-0D4B5E9B1224}. Once registered, the extended view will appear in the result pane of any scope node of a type for which it is registered.
      As you saw in Figure 4 and Figure 5, the result pane is divided vertically into two parts in the Extended View snap-in. The right section contains the primary snap-in's original result list view. The HTML added by the Extended View snap-in uses the mmcview behavior to embed the result list of the snap-in that's being extended into the right section of the result pane.
      The Extended View snap-in automatically displays a header bitmap and the header title giving the name of the currently selected scope node. Script in the HTML obtains the name of the currently selected scope node via the object model and displays it in the Header Title area. Immediately below the Header Title, you can see the name of the currently selected result item and a description of it.
      The Extended View snap-in can provide content for the Description area and the HTML Details area. The HTML Details area is populated with the CCF_HTML_DETAILS property of the selected node (shortly I'll explain how these properties are obtained). This HTML can include links and other active content, such as a thumbnail image.
      For example, to display a Properties link, the primary snap-in can supply the following string for this clipboard format:

  "Display <A HREF = 
  
javascript:external.ExecuteSelectionMenuItem('_PROPERTIES')>
Properties</A>"

 

The previous code will cause the text "Display Properties" to be displayed. When the Properties link is clicked, the Properties menu item on the currently selected list item is executed. The string "_PROPERTIES" is the language-independent name for the Properties menu item. Language-independent menu names are also new in MMC 2.0, but they are beyond the scope of this article.
      The Description area is populated with the CCF_DESCRIPTION property of the selected result item. This value is required to be a plain text string. The CCF_DESCRIPTION and CCF_HTML_DETAILS properties are obtained using the Node.Property property on the Node object of the currently selected result item. This value is returned as a string, which is provided by the snap-in in one of two ways. First, the snap-in's data object can support having the same name as the property via a clipboard format. Alternatively, a snap-in can return these values by implementing the new INodeProperties interface (to be described in the upcoming MMC 2.0 SDK).
      The script also registers itself as an event sink for several object model events, including selection changes and the execution of a context menu item or toolbar item. When one of these events is fired, the script updates the HTML. In this way, the name of the result list item and the description area always stay in sync with the currently selected item.

Drag and Drop Enhancements

      MMC has always supported a basic set of drag and drop features that snap-in developers could use. In MMC 2.0 this set has been expanded to allow drag and drop onto list items, between instances of MMC, or between MMC and other applications. You can also drag and drop items using the right-click mouse button. When you do, a context menu appears when the item is dropped, allowing you to select Move or Copy. This is consistent with other Windows-based applications. MMC allows anything that can be dragged to be dropped onto a list item; it is up to the snap-in to decide what to do with it or to disallow the drop operation.

Changes to Console Files

      MMC 2.0 allows several snap-ins to be added to a single console to create a custom tool. Earlier versions of MMC used a proprietary file format for tools created using MMC (with the .msc file name extension). This did not allow the contents to be easily inspected or modified directly. In contrast, MMC 2.0 uses an XML console file format, although console files created using earlier versions of MMC will continue to work. Because XML is text-based, these console files can be added to a source control system, allowing you to maintain full-revision history.
      Prior to MMC 2.0, snap-in developers had to manually localize versions of their console files into different languages. An MMC 2.0 console file, by contrast, is easy to localize because all strings that require localization are in a single table within the file. You can easily create a custom parser to allow your console files to be localized using the localization tool of your choice.
      Figure 6 shows the contents of a sample XML console file. Parts of the console file that contain binary data, such as the console file icon, have been omitted for clarity.
      An additional enhancement in MMC 2.0 is in the area of user mode console files. As you are probably aware, console files can be saved in author mode or in one of three user modes (full access, limited access/multiple windows, and limited access/single window). Author mode console files allow complete freedom in changing the list of snap-ins, the available views, and so on. By contrast, user mode console files do not permit the list of snap-ins to be changed, and they also present a simplified UI. All shipping console files should be in one of the user modes.
      Earlier versions of MMC saved changes made by the user of a console to the original console file. These included changes to the size and position of views, the selected scope items, list view column sizes and positions, and so on. However, because it is possible for multiple users to use the same console file, only the changes made by the last user of the console would actually be remembered and restored.
      MMC 2.0 solves these problems by automatically saving all changes to a user mode console to the user's profile, instead of to the original console file. Thus, each user's settings are saved independently. Furthermore, because the console file is never changed, it can be used in read-only mode. This puts the finishing touches on the metaphor of the console file as the tool. When you launch a console file, the complete custom tool appears. When it is closed, it disappears, after fully saving its state so that it can be restored later.

Console Taskpad Enhancements

      Console taskpads, which debuted in MMC 1.2 in Windows 2000, are a little-known but powerful feature of MMC. They allow you to place the most frequently performed tasks at your fingertips and to simplify the user interface of your snap-in. You can create a series of tasks, each with an icon and a description, which are displayed together. In MMC 1.2, task icons could be chosen from a fixed set of icons that MMC offered. MMC 2.0 allows you to create your own icons for tasks.
      The tasks you can create can perform three types of operations. First, a task can execute a context menu item on any item within the console. Next, a task can execute a shell command. A powerful parameter substitution mechanism allows data from within MMC to be passed to the shell command as command-line arguments. For example, you could create a task to launch a script to ping the computer specified by the currently selected item. Finally, a task can navigate to another location in the console.

Figure 7 Console Taskpad for Computer Management
Figure 7 Console Taskpad for Computer Management

      Figure 7 shows a console taskpad created for the Computer Management snap-in. The Create a New User and Create a New Group tasks execute the corresponding menu items in the Local Users and Groups snap-in. The other three tasks move the scope tree selection to the appropriate snap-in. Figure 8 shows a console taskpad created for the Services node. Notice how similar the interfaces in Figure 4 and Figure 8 look. This is deliberate; in MMC 2.0, console taskpads, the Extended View, and taskpads provided by snap-ins have been reformatted to have a uniform user interface.

Conclusion

      The new features in MMC 2.0 create a richer user experience. With the addition of scripting support, MMC becomes a more powerful tool that enables programmatic access to much of its functionality. Many new features in MMC 2.0 have not been discussed in this article; these will be documented in upcoming versions of the MMC 2.0 SDK, which will be included with the Whistler release of the Windows Platform SDK.

Vivek Jhaveri is the development lead for MMC at Microsoft. He was a developer in the Exchange group and worked on the Exchange 2000 system administration snap-ins. He can be reached at vivekj@microsoft.com.

From the March 2001 issue of MSDN Magazine