About Pipes
In the last lesson we have laid a foundation for variables and arrays, and today we’ll learn how to search & filter them according to custom conditions. In order to do that and much more, we need to use Pipes. The Pipe character | is used after a command, and the data from the command left of the pipe gets presented to the succeeding command. If you remember the old MS-DOS days, you used to list contents of a directory containing many items with:
dir | more
and so you pressed Enter every time you wanted to see the next screen of content. You passed the output of dir command to more that makes reading large amount of text more pleasant.
Simple Example
Now in PowerCLI, let’s say you want to list all VMs on a single ESXi host and put them to a variable. Considering you are already connected to your vCenter via Connect-VIServer, you would then do:
$allmyVMs = Get-VMHost esxihost1.fqdn.net | Get-VM
Let’s take piping even further – the invaluable Where clause, which can be replaced by a quick mnemonic, a question mark sign ? . If not explicitly stated, the variables that are output from the pipe are stored in the global variable $_ . Any condition that follows must be stored in curly brackets {}.
Filtering, Logical Operators
So if we’d like to further filter the VMs that contain test in their name, we’d use
$testVMs = $allmyVMs | ? {$_.Name -like "*test*"}
When you review your variable, you will see that all VMs containing the name test ale filled in it. You can also filter by more properties than just name, let’s say you only want the VMs that are online, so you exclude the valid powerstate property (you can get the properties list via piping the VM’s variable $allmyVMs | gm).
You will accomplish this by using Logical Operators -and (and) , -eq (equals). There are many more:
- logical: -or, -not (!)
- comparison-oriented (return $true or $false): -like, -notlike (both sides of the expression have to be the same, supports wildcards) -contains, -notcontains (for finding an exactly matching string), -ne (not equal), -match, -notmatch (returns true if it finds just a fraction in the compared expression)
- math-oriented: -ge (greater or equal), -gt (greater than), -le (less or equal), -lt (less than),
$testVMsOnline = $allmyVMs | ? {$_.Name -like "*test*" -and $_.powerstate -eq "PoweredOn"}
Piping to a command
And for our last example, let’s say you actually want to find powered off VMs and then power them on. You will be passing the stored array into a command like this:
Get-VM | ? {$_.powerstate -eq "PoweredOff"} | Start-VM
Piping isn’t really that complicated once you get to know the drill. It is just passing the outputs “along the pipeline” to the commands you would like to. Just experiment with it (be sure to be in a lab environment though) and you will soon become a pipe master 🙂 See you around!