Windows Server How-To

How To Combine PowerShell Cmdlets

Brien breaks down multiple ways to combine actions in PowerShell.

Going forward, PowerShell will be Microsoft's preferred mechanism for managing Windows Server and other Microsoft server products. PowerShell is a command line interface in which administrative actions are performed by using cmdlets (pronounced commandlettes). Cmdlets are made up of verb-noun pairs that are separated by a hyphen. For example, if you wanted to see a list of all of the virtual machines that are running on a Hyper-V server you could use the Get-VM cmdlet. Get is the verb and VM is the noun in this case.

Although PowerShell cmdlets can be quite powerful, they do have their limitations. Often times, performing an administrative task will require multiple cmdlets to be used together. There are several different ways to accomplish this.

One method is to manually run multiple commands in sequence. To show you what I mean, imagine that you wanted to see how much memory your Hyper-V virtual machines were configured to use. You can use the Get-VMMemory cmdlet to view virtual machine memory configurations, but this cmdlet requires you to know the name of the virtual machine. If you didn't already know the virtual machine name, you could use the Get-VM cmdlet to retrieve a list of virtual machines and then use the Get-VMMmemory cmdlet to retrieve the memory configuration. For example, in Figure 1, the Get-VM cmdlet revealed a virtual machine named Mirage. I then appended the name Mirage to the Get-VMMemory cmdlet to retrieve the memory configuration for Mirage.

[Click on image for larger view.] Figure 1. You can run cmdlets manually.

Another technique that you can use is known as piping. Piping involves separating two cmdlets with the pipe symbol (which looks like a vertical line). When you use the pipe symbol, you are telling PowerShell to take the first cmdlet's output and use it as an input parameter for the second cmdlet.

To show you how this works, let's go back to the Get-VMMemory cmdlet. If I wanted to see the memory configuration for all of the virtual machines running on a server, I could use this command:

Get-VM | Get-VMMemory

In the command above, the Get-VM command retrieves a list of the virtual machines running on the server. Normally, the Get-VM cmdlet would display the virtual machine list on screen. However, the pipe symbol tells PowerShell to use the virtual machine list as an input parameter to the next cmdlet (Get-VMMemory) rather than displaying it. You can see this command and its output in Figure 2.


[Click on image for larger view.] Figure 2. You can pipe cmdlets together as a way of using one cmdlet's output as an input parameter for the next cmdlet.

Another way that you can combine multiple PowerShell cmdlets is through a script block. Script blocks are enclosed in braces {} and are normally used for executing command sequences in response to a condition. For example, a script block might look something like this:

If ($condition)

In this case, the Get-VM cmdlet exists within the script block. You could enclose as many cmdlets as you want between the braces, and those cmdlets would be executed together whenever the specified condition is met.

Although not as common as piping, script blocks can also be used within a command. Often times PowerShell cmdlets require the use of optional parameters. For example, suppose that you wanted to use PowerShell to create a Windows Storage Pool. You could do so by using the New-StoragePool cmdlet. However, the cmdlet would not be able to create a storage pool all by itself. You would have to supply the cmdlet with additional information in the form of parameters such as a friendly name, the name of the storage subsystem, and the physical disks to include in the storage pool.

Parameters consist of a dash, the parameter name, and a value. For example, if you wanted to create a storage pool with a friendly name of My Storage Pool, the cmdlet and the corresponding parameter might look like this:

New-StoragePool –FriendlyName "My Storage Pool"

In this case, FriendlyName is the parameter and "My Storage Pool" is the parameter value.

Although I have expressed a literal value in this case, sometimes you may wish to retrieve a value from somewhere else. This is where script blocks come in. A script block can be used to embed a cmdlet within a parameter.

To show you how this works, let's take a look at the –PhysicalDisks parameter for the New-StoragePool cmdlet. Normally you would use the –PhysicalDisks parameter to specify a physical disk. However, it is possible to use a script block containing the Get-PhysicalDisks cmdlet rather than supplying a literal value. The parameter might look something like this:

–PhysicalDisks {Get-PhysicalDisk}

It is worth noting that not every PowerShell cmdlet supports the use of script blocks, but they do work with some cmdlets (such as the New-StoragePool cmdlet).

As you can see, there are several ways to combine multiple PowerShell cmdlets together. Doing so is often necessary for achieving the desired end result.

About the Author

Brien Posey is a 22-time Microsoft MVP with decades of IT experience. As a freelance writer, Posey has written thousands of articles and contributed to several dozen books on a wide variety of IT topics. Prior to going freelance, Posey was a CIO for a national chain of hospitals and health care facilities. He has also served as a network administrator for some of the country's largest insurance companies and for the Department of Defense at Fort Knox. In addition to his continued work in IT, Posey has spent the last several years actively training as a commercial scientist-astronaut candidate in preparation to fly on a mission to study polar mesospheric clouds from space. You can follow his spaceflight training on his Web site.


comments powered by Disqus

Subscribe on YouTube