Exchange Server 2007

Take Command with the Exchange Management Shell

David Strome


At a Glance:

  • How the Exchange Management Shell works
  • How to use cmdlets
  • Cmdlets vs. commands

If you administer an Exchange environment, I’m sure by now you’ve heard that the upcoming Exchange Server 2007 includes a new command-line interface called the Exchange Management Shell. Built on Microsoft Windows PowerShell technology, the Exchange

Management Shell is a powerful management interface you can use to manage every aspect of Exchange Server 2007 from the command line. From there you can interact directly with the Exchange Management Shell, write scripts for automation, or integrate your applications with the underlying engine. Figure 1 shows the shell in action.

Figure 1 The Exchange Management Shell

Figure 1** The Exchange Management Shell **(Click the image for a larger view)

The Exchange Management Console doesn't just use the Exchange Management Shell to perform operations; the wizards show you what commands they're performing. Copy the commands the wizards create and paste them directly onto the command-line or into a script. After you've modified the parameters to your liking, test your scripts or commands by using the WhatIf parameter, which lets you see the results before you make any changes to your environment.

The Exchange Management Shell gives you a robust and flexible scripting platform to integrate with your current scripting solutions, and it lets you communicate natively with data sources like COM and Windows Management Instrumentation (WMI). Based on the .NET Framework, the Exchange Management Shell uses cmdlets—the smallest unit of funcionality in the Exchange Management Shell—to accept and return structured data instead of plain text. We'll look at cmdlets in more detail shortly.

Windows PowerShell Snap-In

The first step in understanding the Exchange Management Shell is to look at how it relates to Windows PowerShell™, a brand new, powerful, flexible command-line interface that's based on the .NET Framework. It combines the best features of several other shells, and adds many new features as well. Windows PowerShell is designed to be a host for other applications, much the same way that Microsoft Management Console (MMC) acts as a host for the various snap-ins that are provided with applications. The Exchange Management Shell is the first Windows PowerShell snap-in to be released.

Snap-ins are collections of cmdlets used to administer an application or major component. If you don't load them first, you can't use them. Luckily, it's extremely easy to start the Exchange Management Shell snap-in. But, before I get to that, I should explain some key concepts that you'll need to understand as you read this article and use the Exchange Management Shell.

Cmdlets Cmdlets resemble built-in commands in other shells, for example, the dir command found in cmd.exe. Like these familiar commands, cmdlets can be called directly from the command line in the Exchange Management Shell and run under the context of the shell, not as a separate process. Unlike commands in other shells, cmdlets have descriptive verb-noun names. The verb describes the action the cmdlet takes, and the noun describes the component or feature that is acted upon.

You don't have to guess what a cmdlet does. When you see the Move-Mailbox cmdlet, you know exactly what it's used for.

For a look at how cmdlets differ from ordinary commands, see the sidebar "Cmdlets vs. Commands", which is taken from the .NET Framework 3.0 section of the Windows® SDK and can be found at

Identity and Positional Parameter The Identity parameter can be used with most Exchange-related cmdlets. It gives you access to the unique identifiers that refer to a particular object in Exchange Server 2007 so you can perform actions on a specific Exchange object using the unique value that makes the most sense to you.

The Identity parameter is a collection of values from other parameters. These values are guaranteed to be unique across that set of objects. You can specify the values of these other parameters, such as Name and DistinguishedName, or they can be system-generated, such as a GUID. The additional parameters that are used, if any, and how they are populated, depend on the object you refer to.

The Identity parameter is also considered a positional parameter—a parameter that lets you specify its value without specifying its name. A parameter is positional if the Parameter Position attribute is an integer. This integer indicates the position on the command line where the cmdlet can find the parameter's value. Because Identity is a positional parameter that resides in position 0, which is the first position, any value entered in this position without a parameter name is considered to be an Identity parameter value. This reduces the number of keystrokes when you type commands. For example

Get-Mailbox –Identity "Kim Akers" 

performs the same action as:

Get-Mailbox "Kim Akers"

Pipelining Pipelining in the Exchange Management Shell is the act of one cmdlet using the output of another cmdlet when it performs an operation. Pipelining is accomplished by using the pipe "|" symbol. All verbs in the same noun-cmdlet set can use piped information from another command. Some noun-cmdlet sets also let you pass data through the pipeline to another noun cmdlet set.

The use of pipelining to string together the actions of two or more cmdlets lets you take smaller components and convert them into something more powerful. For example, you can use one cmdlet to gather data, pass that data to a second cmdlet to filter the data to a subset, and then pass that data to a third cmdlet to act on the subset only.

Starting the Exchange Management Shell

The simplest way to load the shell is to click Start, click Programs, then Microsoft Exchange Server 2007, and then click Exchange Management Shell.

The second way you can load the Exchange Management Shell snap-in is to do it manually from a Windows PowerShell session. Click Start, then Programs, and then Windows PowerShell. After it has started, run the following command to load the Exchange Management Shell:

Add-PSSnapin Microsoft.Exchange.Management.PowerShell.Admin

There are some differences between loading the Exchange Management Shell snap-in using the Programs menu entry and starting it manually using the Add-PSSnapin cmdlet. When you use the Programs menu entry, it not only loads the Exchange Management Shell snap-in, but it also runs a Windows PowerShell script to set up a customized Exchange administration environment. If you want to set up a similar administrative environment after loading the Exchange Management Shell manually, change to your Exchange installation's bin directory—for example, C:\Program Files\Microsoft\Exchange Server\Bin. Then, run the following command:


Take a look at the Exchange.ps1 script to see how to customize the Windows PowerShell environment to suit your needs. When you load the Exchange Management Shell, you'll see something similar to Figure 2.

Figure 2 Exchange Management Shell Welcome Banner

Figure 2** Exchange Management Shell Welcome Banner **(Click the image for a larger view)

Where Do I Start?

Because the shell has such an extensive array of cmdlets, the Get-Help cmdlet and Exchange Server 2007 Help file will be invaluable resources. The Operations section in the Exchange Server 2007 Help file provides you with dozens of how-to procedures for performing most administrative tasks.

Typing Get-Help by itself displays general help information about getting help. To get help on a specific cmdlet, type Get-Help followed by the cmdlet you want information on. You can control what information is presented by using the Detailed, Full, and Example parameters. Just add them to the end of the command. For instance, Get-Help cmdlet name –Full returns all of the help sections available for a cmdlet.

If you want to retrieve information about a specific parameter or parameters on a cmdlet, you can use the Parameters parameter with Get-Help. Thus, if you want to view all of the parameters and their descriptions on the Set-Mailbox cmdlet that contain the word "quota," use the command:

Get-Help Set-Mailbox –Parameter *quota*

You may want to view a list of cmdlets that manage a specific server role or component feature or that affect objects across a certain scope of functionality. The Get-Help cmdlet lets you do this with three parameters: Role, Component, and Functionality. When you use the Get-Help cmdlet with these parameters, you must enclose the values that you specify with these parameters in wildcard characters, "*". The following are examples of how to call Get-Help with each parameter:

Get-Help -Role *Mailbox*
Get-Help -Component *Recipient*
Get-Help -Functionality *Server*

For more information, the "Getting Help" topic in the Exchange Server 2007 Help file lists all of the role, component, and functionality values that can be used.

Formatting Command Output

By default, when output is displayed to the screen, the Exchange Management Shell displays only a subset of the available properties for each object. However, you can easily gain access to all properties by piping the output of a command to the following three formatting cmdlets: Format-List, Format-Table and Format-Wide. You'll probably use Format-List and Format-Table regularly so I'll talk about those specifically.

The Format-List cmdlet takes input from the pipeline and outputs a vertical columned list of all the specified properties of each object. You can specify which properties you want to display by using the Property parameter (although the Property parameter is a positional parameter, meaning you only need to specify the values and not the parameter name). If the Format-List cmdlet is called without any parameters specified, all properties are output. This cmdlet wraps lines instead of truncating them. One of the best uses for Format-List is to override the default output of a cmdlet so that you can retrieve additional or more focused information. For example,

Get-DistributionGroup | Format-List Name, *OnlyFrom, 
PrimarySmtpAddress, *Size*

Figure 3 shows the output of this command.

Figure 3 Format-List Example Output

Figure 3** Format-List Example Output **(Click the image for a larger view)

The Format-Table cmdlet lets you display items in a table format with label headers and columns of property data. By default, many cmdlets, such as Get-Mailbox and Get-JournalRule, use the table format for output. Parameters for the Format-Table cmdlet include the Properties and GroupBy parameters. These work exactly as they do with the Format-List cmdlet. To have long lines of property information display completely instead of truncating at the end of a line, use the Wrap parameter, like so:

Get-Mailbox –Database Research | Format-Table Name, 
ProhibitSendQuota, Database –Wrap 

See Figure 4 to view the output.

Figure 4 Format-Table Example Output

Figure 4** Format-Table Example Output **(Click the image for a larger view)

If you include a wildcard character, you can match multiple properties without having to type each property name individually. For example, this returns all properties that begin with E-mail.

Get-Mailbox | Format-List Email* 

Time to Practice

Now that you have some basic commands under your belt, why not run through the following examples. They'll illustrate the power and flexibility of the Exchange Management Shell and let you get your hands dirty.

The command you'll try first creates 10 users, named User1 through User10:

1..10 | ForEach { Net User "User$_" MyPassword=01 /ADD 
/Domain; Enable-Mailbox "User$_" -Database "Mailbox 
Database" }

Let's dissect the parts. The command 1.0 outputs the integers 1 through 10 and passes them through the pipeline to the ForEach cmdlet. The ForEach cmdlet acts on each object as it's received and runs the commands within the { } brackets for each object. The Net User command creates a new domain user, and the Enable-Mailbox cmdlet creates a new mailbox in the "Mailbox Database" on the local server. The semicolon separates the two commands so they can be placed on the same command line. The $_ variable is a special variable that contains the value of the current object in the pipeline. With this example, the $_ variable contains the integer that is currently in the pipeline.

This next example will allow you to view the mailboxes that reside on the server MBX and return the Name, mailbox database, and quota properties of each mailbox.

Get-Mailbox –Server MBX | Format-Table 

The Get-Mailbox cmdlet returns each mailbox specified with the Server parameter, and then pipes the output of each mailbox object to the Format-Table cmdlet. By default, the Format-Table cmdlet displays all of the properties returned by a cmdlet unless you specify which properties to display. Here only the Name and Database properties, as well as all properties that contain the string "quota" are requested. Figure 5 shows how this output might look.

Figure 5 Get-Mailbox Command Output

Figure 5** Get-Mailbox Command Output **(Click the image for a larger view)

In this example you'll set the send quota limit to 600MB for all mail-enabled users across the organization who have "Manager" in their title.

Get-User –Filter { Title –Like "*Manager*"} 
–RecipientTypeDetails UserMailbox | Set-Mailbox 
–ProhibitSendQuota 600MB

Run by itself, the Get-User cmdlet returns all user objects in Active Directory, including non-mailbox-enabled users. In order to retrieve a set of user objects that can be used by the Set-Mailbox cmdlet, you need to instruct the Get-User cmdlet to return only the Active Directory user objects that are mail-enabled users. The RecipientTypeDetails parameter lets you specify the Active Directory recipient type, in this case, UserMailbox. Next, you need to retrieve a set of mail-enabled users that are managers. In this example, the Title property of each Active Directory user object is populated. You can use this value to determine which users are managers using the Filter parameter, which instructs the server to return only the Active Directory objects that match your criteria. This is called server-side filtering. Once you have a set of objects, it gets passed on to the Set-Mailbox cmdlet, which then sets the ProhibitSendQuota property for each mailbox to 600MB.

Next we'll test the outcome of a command to remove all mailboxes that are members of a distribution group. Here's the command:

Get-DistributionGroupMember "Fourth Year Students" |
 Where { $_.RecipientType –Eq "UserMailbox" } | Remove-
 Mailbox -WhatIf

The first cmdlet retrieves the recipient objects that are members of the Fourth Year Students distribution group. Then, only the recipient objects that match the RecipientType of "UserMailbox" are passed on to the Remove-Mailbox cmdlet. Instead of removing the mailboxes, the Remove-Mailbox cmdlet will display the action it would have performed and the objects on which it would have taken the action. The Get-DistributionGroupMember cmdlet retrieves a list of all recipient objects that are members of the "Fourth Year Students" distribution group. However, because the Remove-Mailbox cmdlet can only work with mail-enabled users, you need to filter out all recipient types except "UserMailbox". Unlike some other cmdlets, the Get-DistributionGroupMember cmdlet does not have the Filter cmdlet, which means it can't perform server-side filtering. For cmdlets that can't perform server-side filtering (because they don't see any performance benefit), you can use the Where cmdlet to perform client-side filtering, which retrieves all objects and performs the filtering on the local client machine. The Where cmdlet only allows objects through that match the criteria you specify. The objects that have a RecipientType of "UserMailbox" are sent to the Remove-Mailbox cmdlet. This cmdlet removes the Active Directory user object and marks the mailbox for removal. When the WhatIf parameter is used, the Remove-Mailbox cmdlet displays text similar to the following:

What if: Removing the Mailbox "
/user10" will remove the Windows user object and mark 
the mailbox in the database for removal.

If you're satisfied that the command will perform the actions you want, run the command again without WhatIf. For certain cmdlets, such as those with the Remove verb, the shell will automatically ask for confirmation before any changes are made. You have the option to step through each change, instruct the shell to not prompt for confirmation again, or cancel further processing. For cmdlets that don't implement confirmation automatically, you can force confirmation using the Confirm parameter.


Now that you've had a taste of cmdlet power, you're ready to experiment on your own and see just how helpful both the Exchange Management Shell and the Microsoft Windows PowerShell will be in your future systems management tasks. If you want to read more about both topics, take a look at the following resources. For the Management Shell see the Exchange Server 2007 Help file at, the Windows Powershell scripting center at, and the Exchange team blog at

David Strome has been a technical writer with the Exchange User Education group at Microsoft for just over one year. Prior to joining Microsoft in Redmond, WA, David spent about 10 years designing, implementing, and administering Exchange Server installations at various companies in British Columbia, Canada. He can be reached at

© 2008 Microsoft Corporation and CMP Media, LLC. All rights reserved; reproduction in part or in whole without permission is prohibited.