For the past few days I've been messing around with Windows PowerShell. PowerShell is the next-generation command-line environment for Windows and associated server products (for example, Exchange 2007 will use it as a command-line and scripting interface). It's way beyond anything you've used in a command-line in the past, because instead of passing text from command to command (via a pipeline) you're passing fully-fledged .NET objects.

Let me give you an example!

Let's say you want to know some statistics about lines of code in your source tree. The first thing you need to get is a list of C# files on your drive. No problem:

get-childitem \ -recurse -include *.cs

What are we doing here? Well, first we're using the get-childitem to recursively list every file on our hard drive with an extension of ".cs". The output of get-childitem is not a simple string of text - it's an array of System.IO.FileInfo classes.

So now we need information about the contents of each of those files. How many lines are in each file? Let's pipe our output through to another command:

dir \ -recurse -include *.cs | get-content

The get-content command returns the contents of a file as an array of strings, one for each line. We want to get the length of that array (the number of lines in the file), so let's use that get-content call in a slightly different way:

dir \ -recurse -include *.cs | select-object @{Name="Lines"; Expression={(get-content $_).Length}}

The select-object command selects certain properties from the given object (in this case the FileInfo objects in the array returned by "get-childitem"). We're returning a calculated property called "Lines" which is the number of lines in the file (based on the length of the array returned by get-content).

So now our command is returning an array of Int32 values - the number of lines in every C# file on our hard drive. Last thing we want to do is get some statistics about those numbers:

dir \ -recurse -include *.cs | select-object @{Name="Lines"; Expression={(get-content $_).Length}} | measure-object Lines -av -sum -max -min

And we're done! The measure-object command gives us all the statistics we need. Here's an example of the output from the above string of commands:

Count : 63 Average : 221.587301587302 Sum : 13960 Maximum : 8425 Minimum : 20 Property : Lines

Pretty cool, huh? One line of commands to get a bunch of handy statistics about your lines-of-code.

This is a really simple breakdown of what's possible in PowerShell. Check out the team blog for a more in-depth look at the amazing things this thing is capable of!