Windows PowerShell, known prior to its official release as the Monad Shell (MSH), is an advanced replacement for the good ol' Command
Prompt. Although it uses many familiar DOS commands (sort of), it
introduces some Unix-like functionality to the Windows platform while
borrowing some of the Windows-aware features found in WSH scripts, like
printing, security, and process control.Windows
PowerShell 1.0 was released more or less concurrently with Windows
Vista, but it's not included in the default Vista installation. You can
download PowerShell for free from http://www.microsoft.com/powershell/, but Microsoft has hinted that it'll be included with future versions of Windows.
At first glance, PowerShell (Figure 1) looks like an ordinary Command Prompt window, with the main distinguishing feature being the text PS preceding the prompt. As you may have guessed, you type a command at the prompt and press Enter
to excecute the command. But the commands you can type—and how they
interact with each other—are what really set PowerShell apart.
1. CmdLets and Aliases
PowerShell's built-in commands are called CmdLets for reasons that aren't entirely clear, and the CmdLets all have long, rather inconvenient names like Copy-Item, ConvertFrom-SecureString, and Invoke-Expression. The good news is that most of the commands have short versions, called aliases, that just happen to coincide with familiar DOS and Unix command names. For instance, instead of typing Copy-Item, you can type copy (as in DOS) or cp
(à la Unix) to copy files from one place to another; if nothing else,
this dualism is an important advantage over the conventional Command
Prompt.
Table 1 shows a list of common, basic PowerShell commands, and their DOS and Unix counterparts.
Table 1. Common DOS and Unix commands and their PowerShell equivalents
DOS
|
Unix
|
PowerShell
|
Description
|
---|
cd
|
cd
|
Set-Location
|
Change the working directory (folder)
|
cls
|
clear
|
Clear-Host
|
Clear the screen
|
copy
|
cp
|
Copy-Item
|
Copy a file or object from one place to another
|
del, rd
|
rm, rmdir
|
Remove-Item
|
Delete a file, directory (folder), or object
|
dir
|
ls
|
Get-ChildItem
|
Display the contents of the current directory or object
|
help
|
man
|
Get-Help
|
Display a list of commands or details about the specified command
|
md
|
mkdir
|
New-Item
|
Create a directory (folder) or object
|
move
|
mv
|
Move-Item
|
Move a file, directory (folder), or object to a new location
|
ren
|
mv
|
Rename-Item
|
Change the name of a file or object
|
type
|
cat
|
Get-Content
|
Display the contents of a file or object
|
What's more enticing is that you can make your own aliases. For example, if you find yourself frequently using the Get-Culture command (which retrieves the language in use by Windows), you could shorten it like this:
Set-Alias -Namelang -ValueGet-Culture
so that you could thereafter type only lang to display the current language. The Set-Alias command also lets you change (overwrite) any of the built-in aliases.
The Set-Alias
command only creates aliases for bare commands; you can't bury your
favorite command-line parameters in an alias. To replace a complex,
multipart command with a single word you can type at the prompt, use
PowerShell variables, discussed later. |
|
Of
course, once you close the current PowerShell window, your custom alias
will be forgotten. So, to save your custom aliases from session to
session, add your Set-Alias commands to your PowerShell profile file. Of course, you probably don't have a profile yet, so type:
New-Item -type file -force $profile
to create one. Then type:
notepad $profile
to open the newly created profile for editing.
PowerShell has about 130 commands, most of which are documented in the UserGuide.rtf file included with the package. There's also a simple online help system, via the help
command, that displays a list of available commands (in a
not-so-helpful format), or if invoked with the name of a command,
displays the syntax and explanation of the command. To see all the
available information about a command, include the -full parameter, like this:
help Get-Item -full
While using the online
help, you'll soon discover the needlessly complex SYNTAX section, which
lists all the parameters supported by a single command. For instance,
the syntax line for the Copy-Item command (copy to you and me) consumes four lines, and is about as easy to read as the computer output in the Matrix movies. But rest assured, it's more or less the same as its DOS counterpart; in other words, this command:
copy c:\stuff\myfile.txt d:\misc
still works as you'd expect.
2. Pipelines
So,
if PowerShell looks like the Command Prompt, and most of the commands
you know and love work the same, then what's the point?
Without
drowning you in technical jargon, what sets PowerShell Cmdlets apart
from their Command Prompt counterparts is that they work better with piping,
a means of redirecting the output of one command so that it's used as
the input for another. For example, this two-part command:
get-process m* | stop-process
works because the get-process Cmdlet sends (through the pipe) its output (a list of running processes that start with the letter m) as a structured object. In turn, the stop-process
Cmdlet receives this object and uses it as a list of processes to stop.
In lesser Command Prompts, this information is passed between commands
(piped) as plain text, which means you need to use a variety of tools
(like grep in Unix) to format the
output so the receiving command can process it. (Imagine what this would
all sound like if I had left in the jargon.)
Unfortunately,
this particular aspect of PowerShell is a little more hype than dope.
For one, the example command above (taken from Microsoft's own
documentation) is pointless, since the following simpler command works
just as well:
stop-process m*
Of course, the downside of this object-oriented model is that the various data is all typed,
and can't be easily converted from one type to another. That is, you
can't easily pipe output to a command that hasn't been specifically
designed to receive it. In good ol' Unix and DOS, you can pipe anything
to anything. For instance, this PowerShell command:
help | help
which I expected would send a list of Cmdlets generated by help
back to
help, which in turn would spit
out a detailed explanation of each Cmdlet, did not work at all. Perhaps
this is a silly example, but it sure would've made my job easier.
What
does work well is the passing of filenames from one Cmdlet to another.
Here's a sophisticated series of commands that illustrates this:
Get-ChildItem 'H:\MediaCenterPC\My Music' -rec | where { -not $_.
PSIsContainer -and $_.Extension -match "wma|mp3" } | Measure-Object -
property length -sum -min -max -ave
This amalgam of three Cmdlets does the following:
Retrieves a list of filenames in the H:\MediaCenterPC\My Music folder and all its subfolders (thanks to the -rec option), and passes the list to...
the where (Where-Object) Cmdlet, which filters out any files that don't have the .wma or .mp3 filename extensions, and then passes the modified list to...
the Measure-Object Cmdlet, which outputs detailed information about the music files in the list.
And you could keep going like this, including a command that take the output from Measure-Object
to process, store, or display it in some fashion. The syntax may look a
little messy to the uninitiated, but it would be much more difficult to
do this sort of thing in WSH and nearly impossible in a batch file.