Export (0) Print
Expand All
12 out of 26 rated this helpful - Rate this topic

Using Exchange Management Shell Commands With Managed Code

Topic Last Modified: 2007-03-02

By Ray Dixon, Programming Writer

Would you like to add Exchange management capabilities to your Microsoft .NET Framework–based applications? This article explains the basics of using the Exchange Management Shell from managed code, and provides the building blocks from which you can add features that manage computers running Microsoft Exchange Server 2007.

Before you get started, you need the Windows PowerShell SDK, which is in the latest Windows Platform SDK. The Windows PowerShell SDK contains, among other things, the assembly that you must reference in order to access the Windows PowerShell or the Exchange Management Shell. For more information, see Windows PowerShell SDK.

Add a reference to the System.Management.Automation.dll assembly. By default, this assembly is installed in C:\Program Files\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0\. After referencing the assembly, add the following directive statements to your code:

using System.Management.Automation;
using System.Management.Automation.Host;
using System.Management.Automation.Runspaces;

Adding the following directive statements will make it easier to work with the collections returns from the commands:

using System.Collections.Generic;
using System.Collections.ObjectModel;

To use the Microsoft Windows PowerShell or the Exchange Management Shell from managed code, you must first create and open a runspace. The following code creates a new instance of a runspace and then opens it.

Runspace myRunspace = RunspaceFactory.CreateRunspace();
myRunspace.Open();

This code only provides access to the cmdlets that come with the default Windows PowerShell installation. To use the cmdlets that come with the Exchange Management Shell, you must specify this by using an instance of the RunspaceConfiguration class. The following code opens a runspace that has access to the Exchange Management Shell.

RunspaceConfiguration rsConfig = RunspaceConfiguration.Create();
PSSnapInException snapInException = null;
PSSnapInInfo info = rsConfig.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.Admin", out snapInException);
Runspace myRunSpace = RunspaceFactory.CreateRunspace(rsConfig);
myRunSpace.Open(rsConfig);

This code specifies that you want to use Windows PowerShell in the context of the Exchange Management Shell. This gives you access to the Exchange-specific cmdlets in addition to the Windows PowerShell cmdlets.

You can invoke a cmdlet from managed code in more than one way. This article explains how to use the Pipeline class to invoke a cmdlet.

First, create a new instance of the Pipeline class by using the runspace that you created. The following example shows how to create a new instance of the Pipeline class.

RunspaceConfiguration rsConfig = RunspaceConfiguration.Create();
PSSnapInException snapInException = null;
PSSnapInInfo info = rsConfig.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.Admin", out snapInException);
Runspace myRunSpace = RunspaceFactory.CreateRunspace(rsConfig);
myRunSpace.Open(rsConfig);
Pipeline pipeLine = myRunSpace.CreatePipeline();

Next, create an instance of the Command class by using the name of the cmdlet that you want to run. The following code creates an instance of the Command class that will run the Get-Command cmdlet.

Command myCommand = new Command("Get-Command");

Next, add the command to the Commands collection of the pipeline.

pipeLine.Commands.Add(myCommand);

Now, call the Pipeline.Invoke method to run the command.

Collection<PSObject> commandResults = pipeLine.Invoke();

This code invokes the cmdlet(s) in the Commands collection of the pipeline and returns a collection of objects that are derived from the PSObject class. The following code puts together all of the previous code examples.

RunspaceConfiguration rsConfig = RunspaceConfiguration.Create();
PSSnapInException snapInException = null;
PSSnapInInfo info = rsConfig.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.Admin", out snapInException);
Runspace myRunSpace = RunspaceFactory.CreateRunspace(rsConfig);
myRunSpace.Open();
Pipeline pipeLine = myRunSpace.CreatePipeline();
Command myCommand = new Command("Get-Command");
pipeLine.Commands.Add(myCommand);
Collection<PSObject> commandResults = pipeLine.Invoke();

You can do lots of things with what the Pipeline.Invoke method returns. In this example, the collection of PSObject derived classes are available cmdlets. The first thing you can do is determine how many objects the method returned. In this case, you are invoking the pipeline in the context of the Exchange Management Shell and will get a collection that contains over 500 commands. You can get the value of the commandResults.Count property to find the exact number of commands returned. If you did not specify a runspace and used the default runspace, the collection would be much smaller because it would only contain the commands that come with Windows PowerShell. The following code shows how to invoke the same command in the default runspace.

Runspace myRunSpace = RunspaceFactory.CreateRunspace();
myRunSpace.Open();
Pipeline pipeLine = myRunSpace.CreatePipeline();
Command myCommand = new Command("Get-Command");
pipeLine.Commands.Add(myCommand);
Collection<PSObject> commandResults = pipeLine.Invoke();

In this example, the value of the Count property of the commandResults collection is much smaller than the same value in the example that specifies the RunspaceConfiguration that is specific to the Exchange Management Shell.

The PSObject class has a Properties property that contains the collection of properties on the object. The following code shows how you can iterate through the commandResults collection and get the name of each cmdlet.

foreach (PSObject cmdlet in commandResults)
{
string cmdletName = cmdlet.Properties["Name"].Value.toString();
System.Diagnostics.Debug.Print(cmdletName);
}

Note that in an actual application, it would be more useful to print the names to a user interface. This example prints to the trace output simply to show how you can access the properties of the objects.

Suppose you want to get a list of commands, but you want to restrict that list by using a parameter with the Get-Command cmdlet. You can do that by specifying one or more parameters and adding them to the command. The following code shows how to add a parameter so that the command restricts the list of commands that are returned to those that have "Get" as the verb.

CommandParameter verbParam = new CommandParameter("Verb","Get");
myCommand.Parameters.Add(verbParam);

You can add as many valid parameters as you like to your command. For example, suppose you want to return a list of only the Exchange Management Shell commands with the verb "Get". You can use the parameter defined in the previous example and add another parameter to the command.

CommandParameter psSnapInParam = new CommandParameter("PSSnapIn","Microsoft.Exchange.Management.PowerShell.Admin");
myCommand.Parameters.Add(psSnapInParam);

If you put together the two code blocks, the command will execute using both parameters and return the Exchange Management Shell "Get" cmdlets.

The pipeline is a powerful feature that is used on the command line as well as in scripts. You can also use the pipeline in your applications. To pipe the output of one command to the input of another, you simply add both commands to the pipeline. The following code gets the list of commands and then pipes that list to the Get-Member cmdlet. The result is a collection that contains every member of each command.

Runspace myRunSpace = RunspaceFactory.CreateRunspace();
myRunSpace.Open();
Pipeline pipeLine = myRunSpace.CreatePipeline();
Command getCommand = new Command("Get-Command");
pipeLine.Commands.Add(getCommand);
Command getMember = new Command("Get-Member");
pipeLine.Commands.Add(getMember);
Collection<PSObject> commandResults = pipeLine.Invoke();

You can add many commands to the pipeline. They will execute in the order in which you added them, as they would from the command line, and the output of one command will be passed as the input to the next command.

From here, you can extend the concepts to build robust, integrated applications that provide your users with an interface of your choosing. Now, get creative and go code!

Did you find this helpful?
(1500 characters remaining)
Thank you for your feedback
Show:
© 2014 Microsoft. All rights reserved.