Windows scripting has long been the butt of jokes from UNIX system administrators. This has been the case for several reasons; chief among them is that Windows has been lacking many of the key features that make scripting truly useful. However, Microsoft is now not only catching up to but actually surpassing other OSs' scripting capabilities with its new Windows PowerShell scripting environment. Formerly code-named Monad, PowerShell delivers several scripting capabilities that Windows has never had and greatly improves some existing features. Even though PowerShell is still a release candidate, it's useful to know how PowerShell is filling in the capability gaps and how it works.
Filling In the Gaps
Microsoft designed PowerShell to provide a more powerful scripting and command environment than was previously available in Windows. The design team members had a number of goals in mind. In summary, they wanted to make the Windows scripting environment more powerful and easier to use than the scripting tools in any other OS. They also wanted to build an environment that would be usable for systems administration tasks and application development—and one that would integrate with the Microsoft .NET Framework. Meeting these goals meant that Microsoft had to address some capabilities that have been missing from Windows scripting tools. To fill these capability gaps, Microsoft incorporated into PowerShell the best aspects of a wide variety of commandline environments:
- Composition. Composition lets you create complex commands by stringing together lots of little commands, each of which typically does only one task. UNIX shells deliver this capability in spades. Most UNIX administrators use composition every day, even if they don't know that's what it's called. The original designers of the UNIX shell environment had an explicit goal of making the shell use lots of small, single-purpose commands that administrators could combine in various ways. This stood in sharp contrast to other environments available at the time, which tended to use large, complex command structures.
- Pipelining. Pipelining lets you take the output of one command and pass it as input to the next command in a composition. The command interpreter in current Windows OSs does this in a very limited manner. For example, if you run the command
dir | more
the output of the Dir command will be piped to the More command. However, most Windows commands don't support pipelining (or the close cousins, output and input redirection).
- Object orientation. PowerShell commands output objects, not blocks of text. Objects have properties (items you can view and change) and methods ( executable actions). For example, you can use the get-mailbox command to get a list of mailbox objects, which you can then manipulate in a variety of ways. Get-mailbox doesn't return a list of names of mailboxes; it returns objects that represent the mailboxes themselves. As you'll see in the "PowerShell in Action" section, having commands that return sets of objects gives you a huge degree of power.
- Safety. Most of the PowerShell commands that create or change objects support two flags: confirm and whatif. When you set the confirm flag, you'll be asked whether you really want to perform the specified action. When you set the whatif flag, you'll be shown what happens without actually changing anything. These flags are invaluable because they give you a way to test changes before they actually take place.
- Consistent structure and consistent naming. Almost all of the PowerShell commands use a consistent verb-object structure and follow consistent naming patterns. To boot, there aren't that many verbs. Because of the consistencies and the small number of verbs, it's easy to figure out how to construct a command if you know the object you want to work with.
- Robust online help. PowerShell provides robust online help for objects, commands, and the shell environment itself.
PowerShell 101
PowerShell is made up of lots of objects called cmdlets (pronounced command-lets). Cmdlets are analogous to DLLs in that they're executable objects that can't run on their own. For that reason, cmdlets are run from within the PowerShell command interpreter. PowerShell Release Candidate 1 (RC1) includes more than 120 cmdlets.
Cmdlets can have parameters, which can be named or positional (i.e., PowerShell interprets them according to their location on the command line). For example, when you use the get-mailbox cmdlet, the first parameter always specifies what mailboxes you want to get. You can include other parameters in this cmdlet by specifying their names.
There are several built-in cmdlets that you'll use often enough to warrant a mention here:
- The format family of cmdlets (i.e., format-table and format-list) take a stream of objects and format them appropriately. You can choose what properties are displayed. So, for example, when displaying a list of mailboxes, you can choose to see only the mailbox name and total size by running a command such as
get-mailboxstatistics |
format-table name, size
(Although this command appears on several lines here, you would enter it on one line in PowerShell. The same holds true for the other multiline commands in this article.)
- The where cmdlet lets you select objects to be used. For example, if you run the command
get-eventlog application | where
{$_.ID eq "-1018"}
PowerShell searches the application event log and retrieves all events whose event ID is 1018. Interestingly, the where cmdlet is one of the few PowerShell cmdlets that don't follow the verb-object syntax I mentioned earlier.
- As its name suggests, the group cmdlet groups objects according to a property you specify. Let's say you want a list of all the mailboxes in your organization along with their sizes, grouped according to which mailbox database they were in. This command would do the trick:
get-mailboxstatistics |
group MailboxDatabase |
format-table count,name
When you look at other people's Power-Shell scripts, you might see funny-looking abbreviations for some cmdlets, such as fl for format-list. PowerShell has extensive support for aliases. There are built-in aliases for many common commands. Plus, you can define your own aliases in your shell profile, which is a special file that PowerShell uses to apply per-user defaults and settings.