Top 3 Products & Services


Dated: Nov. 20, 2011

Related Categories

Windows 2000
Windows NT
Windows XP
Windows Vista
Windows 7

By Payton Byrd

Who needs another shell? Unlike the Unix world, Windows hasbeen pretty consistent with the shell environment. First there was MS-DOS (COMMAND.COM) and later Windows NT (CMD.EXE). You can actually still get to COMMAND.COM if you really, really want to. But for all intents and purposes, these have been the only two shells Windows users have ever known.

Microsoft wants to change that. When .Net was announced in 2000, Microsoft promised everything would one day be .Net. Unfortunately, Microsoft stuck the .Net name on things that were not .Net at all, such as Passport.Net which had no managed code in it at all.

Things Are Changing in Redmond

Microsoft is exploring what can be done in managed code by going so far as building an operating system out of a special implementation of the CLR called Singularity. This operating system may be the first ancestor of a whole new way to think about computing. Until then, we have to think near-term and practical. One of the reasons that there's a ton of shells available for Unix is that people have constantly said "what if we add this, too" and then go off and fork an existing shell and add "that, too." Microsoft has instead updated COMMAND.COM and CMD.EXE only when a new version of DOS or Windows was released, maintaining near 100% backwards compatibility along the way, which is a far cry from the mish-mash of commands between the various Unix shells. At Microsoft, there was no reason to create yet another shell for just minor changes. But now, now there are good reasons to build a new shell.

PowerShellToday, Microsoft has decided that if the kernel of the OS is not ready to be in managed code, the UI is a great place to introduce managed code the OS. To start, Microsoft released Windows Presentation Foundation, which is a managed infrastructure for displaying vector graphics-based user interfaces. At the same time, the server team decided to do a .Net based shell, but this would not be like any other shell out there. No, this shell is different, very differnt.

Every system admin has written tons of scripts or batch files to make the operating system bend to their will. Those building scripts can be quite complex, and usually those scripts involve building secondary scripts which perform smaller, more atomic portions of a system. One thing that seems to invariably happen is that as time passes, the scripting styles evolve and the scripts become very disjointend in their usage. The reason for this is that scripts are fundamentally just a bunch of words with little semantic meaning. No two people think alike and no two script writers make scripts alike. It's all just words. To help make those words make sense, tools such as grep and awk and perl were created to parse scripts, build new scripts, and report on the output of scripts. Just like the shells themselves, the tools began to fragment to honor sacred cows. Unfortunately, not everyone shares the same sacred cows.

Windows PowerShell is Different

I know, I'm repeating myself and I still haven't really said why it's different. It's different because text processing is not the reason Windows PowerShell exists. Existing tools do that just fine. Windows PowerShell is implemented in managed code running in the CLR. That means that it's object oriented. That means that to manipulate things in Windows, it has to fully participate in the application domain model. It also means that using the built in tools of the CLR that those objects can be interrogated, security can be applied to the objects... it's just like any other program running in the CLR. When you type a command in Windows PowerShell, you are invoking a specific, small-scale object that has a very specific purpose. Yes, you can invoke command line applications, too. You can also invoke GUI applications. But your old DOS batch files won't run anymore. Why? Windows PowerShell is not about text processing, it's about object handling.

For example, to pass the output of one command to another, you use a pipe. This is how it is in COMMAND.COM, CMD.EXE, BASH, SH, etc. You also use the pipe to pass the results of a command in Windows PowerShell to another command. The difference is that the pipe is actually pushing an object to the next command. Don't get me wrong, that object can be a string. But it can also be a DataSet. But it can also be a Dictionary. But it can also be a... well, you get the point.

So Why Does Objects Matter in the Shell Environment?

In traditional text-based shells, you have to parse strings to use the piped output of a command or program. String parsing is not an exact science, and globalization and style issues can quickly derail the processing of non-trivial data. Use the wrong delimiter in output and a delimited list becomes a single record. Objects allow to encapsulate data into meaningful units that can be processed consistently. If you've read this blog for any amount of time, you know I like things that work consistently, and I especially like tools that allow me to do things in a consistent manner.

Don't worry, you can still do mad text parsing in Windows PowerShell; after all, you have full access to the entire .Net Framework with all of it's kick-butt string tools. But once you move beyond that way of thinking you may never want to go back. For example, Windows PowerShell is to shells what Ant (and it's variants, such as NAnt) are to make. Ant and NAnt are actually conceptually similar to Windows PowerShell, but with Windows PowerShell you get a completely interactive environment from which to interact with every object the operating system contains (within the security rights of the user, of course).

Here's an example of how piping an object allows you to do neat things. Windows PowerShell has over 100 cmdlets built in. These cmdlets are all named following a convention: verb-noun. Each cmdlet must do something, like Get a Child Item; which is named Get-ChildItem. If you are in a directory (which is the current object) and you get it's child items, you are actually doing the same thing as the old "dir" command in COMMAND.COM or CMD.EXE. A major difference, though, is that the output of "dir" in the old shells was just a pre-formatted string. In Windows PowerShell, "dir" is an alias to the Get-ChildItem cmdlet, and it's output is a matrix of data.

PS C:\PSTest> dir

  Directory: Microsoft.PowerShell.Core\FileSystem::C:\PSTest

Mode        LastWriteTime   Length Name
----        -------------   ------ ----
d----    12/28/2006 12:20 AM      SubDir1
d----    12/28/2006 12:20 AM      SubDir2
-a---    12/28/2006 12:21 AM     18 Text1.txt
-a---    12/28/2006 12:21 AM     36 XML1.xml

OK, so it's a directory listing. Big whoop. Not so fast, this is a big deal.

PS C:\PSTest> dir | format-list

  Directory: Microsoft.PowerShell.Core\FileSystem::C:\PSTest

Name      : SubDir1
CreationTime  : 12/28/2006 12:20:47 AM
LastWriteTime : 12/28/2006 12:20:47 AM
LastAccessTime : 12/28/2006 12:20:47 AM

Name      : SubDir2
CreationTime  : 12/28/2006 12:20:49 AM
LastWriteTime : 12/28/2006 12:20:49 AM
LastAccessTime : 12/28/2006 12:20:49 AM

Name      : Text1.txt
Length     : 18
CreationTime  : 12/28/2006 12:21:00 AM
LastWriteTime : 12/28/2006 12:21:07 AM
LastAccessTime : 12/28/2006 12:21:07 AM
VersionInfo  :

Name      : XML1.xml
Length     : 36
CreationTime  : 12/28/2006 12:21:52 AM
LastWriteTime : 12/28/2006 12:21:52 AM
LastAccessTime : 12/28/2006 12:21:52 AM
VersionInfo  :

Here we see the result of piping the matrix of data from the Get-ChildItem cmdlet (aliased as "dir") and sending it to another cmdlet called Format-List. The output in the list is much more detailed than the default output. This would not be possible with a text-based shell as all the data must be sent into the pipe for the data to be displayed. If we were to pipe the results of the first "dir" command in a text-based shell, we could refactor it to a list, but we wouldn't be able to show any data elements that aren't in the original output, nor could we make the common data elements show more detail. What's happening here is that the Format-List cmdlet is actually building the text output from the actual object heirarchy of the Get-ChildItem cmdlet and shaping it the way it wants to.

Wrapup, For Today

This is probably bordering on information overload for today. I'll wrap this up by teasing you with what's coming up in a future post. I'll look at how Windows PowerShell exposes data stores such as the registry as a path that can be worked with in exactly the same ways as a directory. This will help tie together the concept that everthing is an object, and polymorphism is the coolest thing since sliced sub-classes of wheat that implement the IBaked and IMixed interfaces. That's geek humor. I thought it was funny. In a later post we'll write our first cmdlet, the obligatory "Hello, world!" Finally, we'll look at the Windows PowerShell scripting language and why an existing language just wouldn't do.

PS. There's a really cool feature that will cause Commodore Amiga fans to scream "It's about $%!&ing time!"

Now that you've gotten free know-how on this topic, try to grow your skills even faster with online video training. Then finally, put these skills to the test and make a name for yourself by offering these skills to others by becoming a freelancer. There are literally 2000+ new projects that are posted every single freakin' day, no lie!

Previous Article

Next Article