PowerShell %


In a previous post, I demonstrated the Where-Object cmdlet (whose alias is ?).

Another important cmdlet is ForEach-Object.  In fact, it is so important that it also has a simple alias: %

Say for example that you want to calculate the length in kilobytes of every file in the current directory. It’s this simple: Get-ChildItem -File | % {$_.Length / 1KB}

So what’s going on here?

The left side of the pipe (see my previous blog) is enumerating all children (e.g. files) in the current directory. I use the -File switch to limit the results to files. On the right side of the pipe, we use ForEach-Object to loop through each file and calculate the file length, in KB. We wrap the calculation in brackets { and } because this is an expression we need PowerShell to evaluate. Note that because it is such a common unit of file system measurement, PowerShell also understands the notation KB.

Advanced Aside: As I’ve said before, there are many ways to do the same thing in PowerShell. For instance, you could also have done this: Get-ChildItem -File | Select-Object {$_.Length / 1KB}. In this case, the Select-Object mechanism also offers the ability to pretty this up. Try this for instance: Get-ChildItem -File | Select-Object Name, @{Name="Kbytes";Expression={$_.Length / 1Kb}} | ft -AutoSize. But for a quick way to enumerate values of a collection on your PowerShell host, what could be simpler then % ?

Here’s another example:

Let’s say you wanted to enumerate a list of all odd numbers from 1 to 10,000…. This PowerShell host syntax looks a bit convoluted, but you would just type 1..10000 | % { if ($_ % 2 -eq 0) {return} write-host $_ }. To make this easier to read, just imagine the syntax were broken out on multiple lines, like this:

NOTE: this code will not run due to the position of the line breaks:

1..10000 | %         # for each number from 1 through 10,000
{
   if ($_ % 2 -eq 0)    # does current object mod 2 have a remainder of zero
   {
      return               # if its even then do a noop
   }
   ## else
   Write-Host$_         # output current object (i.e. the odd numbers)
}
Advanced Aside: It is possible to divide up code over multiple lines on the PowerShell host, as long as your code follows certain rules regarding the placement of curly braces and such.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s