Applies to: Exchange Server 2010 SP2, Exchange Server 2010 SP3

Topic Last Modified: 2009-02-23

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.

See the following sections for information and examples of using pipelining in the Shell:

Using Pipelining to Perform Multiple Actions

Using Pipelining to Process Data from another Cmdlet

Using Pipelining to Pipe Data between Dissimilar Nouns

Using Pipelining to Report Errors

The use of pipelining to string together the actions of two or more cmdlets gives the Shell the power of composition, which 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.

For example, the following command uses pipelining to move all the mailboxes on Server1 to the Executives database on Server2 by using the Move-Mailbox cmdlet, based on output that is piped from the Get-Mailbox cmdlet:

Get-Mailbox -Server Server1 | Move-Mailbox -TargetDatabase Executives

You can also use pipelining to process data that is output by a cmdlet. For example, for a list of all processes where the HandleCount property of the process is larger than 400, you can run the following command:

Get-Process | Where { $_.HandleCount -gt 400 } | Format-List

In this example, the Get-Process cmdlet passes objects to the Where-Object cmdlet. The Where-Object cmdlet picks out the objects that have a property called HandleCount with a value larger than 400.

Where is an alias for the Where-Object cmdlet. For more information, see Aliases.

In this example, the HandleCount property is preceded by the $_ variable. This variable is created automatically by the Shell to store the current pipeline object. The Where-Object cmdlet then sends these objects to the Format-List cmdlet to be displayed.

The use of structured objects, instead of text, is one of the most exciting capabilities of the Shell. The use of structured objects forms the basis of a powerful compositional model of administration. For more information about structured objects, see Structured Data.

Piping data between dissimilar nouns is useful in cases where you want to use the data from one cmdlet with another cmdlet, but the preceding cmdlet in the pipeline doesn't output an object that the next cmdlet can use to identify the object to act upon. This situation typically happens if you're trying to pipe an object from a cmdlet with a noun that's different than the cmdlet that's expecting the object. For more information about cmdlets, see Cmdlets.

To pass data between cmdlets that haven't been optimized to pass objects directly between each other, you need to pass the object through the ForEach cmdlet. When you use the ForEach cmdlet, you can access the object directly using the $_ special variable and associate its properties with the parameters on the second cmdlet.

In the following example, the Get-Mailbox cmdlet and the New-InboxRule cmdlet aren't optimized to send objects directly between each other. For the New-InboxRule cmdlet to take action on objects provided by the Get-Mailbox cmdlet, we need to manually associate the correct property on the mailbox object to the correct parameter on the New-InboxRule cmdlet. To do this, we use the following command:

Get-Mailbox | ForEach { New-InboxRule -Name "Mark as Read" -Mailbox $_.Name -From john@contoso.com -MarkAsRead $True}

In this example, we know that the New-InboxRule cmdlet requires that you specify the mailbox on which to create the new inbox rule. We also know that the Get-Mailbox cmdlet outputs an object that contains the name of each mailbox being returned. By using the ForEach cmdlet, which contains the command to be run on each object it receives, we gain access to the $_ special variable, which contains the current object in the pipeline. We can access the Name property of the current mailbox object using the syntax $_.Name. We provide $_.Name as an argument on the Mailbox parameter of the New-InboxRule cmdlet which provides the cmdlet with the information it needs to create the new inbox rule.

ForEach is an alias for the ForEach-Object cmdlet. For more information, see Aliases.

To report errors, you can use the error pipeline. The error pipeline lets you report errors while a command runs. You don't have to wait until the command has finished running or to put the error information in the standard result pipeline. The Write-Error cmdlet writes its arguments to the error pipeline.

For more information about pipelining, run the following command in the Shell:

Get-Help About_Pipeline