torstai 17. toukokuuta 2012

Windows PowerShell

The Windows PowerShell
One advantage that Linux (and other Unix-like systems) has always had over Windows is the powerful command line interface. Linux systems provide the user with dozens of little programs that can be combined, or piped, together to do more complex things. For example, the ls ("list") command lists the files in the current directory. The wc ("word count") command counts the number of lines, words and/or bytes in the given input. Pipe these together, and you can get the number of files in the current directory: "ls | wc -l".

With the Windows Command Prompt these kind of operations have traditionally been way more difficult. Of course, I guess most people never use the Command Prompt, but those who do miss these powerful features from Unix-like systems. Nowadays, however, we have the Windows PowerShell.

The Windows PowerShell has been around for a few years already and I've been vaguely aware of its existence, but never really looked into it until now. It seems to be readily available on all Windows 7 installations, and most likely on Windows Vista as well. You can find it from the Start Menu.


When you start the PowerShell, you might want to see what commands are available. You can use the Get-Command command or its alias gcm for that. You'll see many lines of text that end with "...", i.e. they are truncated. Use Get-Command | Format-List  or the short form gcm | fl to see everything, or gcm Some-Specific-Command | fl to get info on some specific command only. And since the PowerShell commands aren't that short, you might only want to see the list of short commands, or aliases, available Get-Alias. The PowerShell commands are case-insensitive, so that would be the same as get-alias. And by the way, the default alias for get-alias is gal.

When you are accustomed to Unix shells the weird part in PowerShell is that it is object oriented. The pipes actually pass around typed objects rather than character streams. So when you "print out a list of files", you are actually rendering a collection object consisting of file objects. I won't go into this in detail but it is good to know this.

Replacements for Unix commands

So, what commands replace the most used Unix commands? Here are some of the most important ones in the format of Unix-command: Windows-command (alias):
grep: Select-String
cat: Get-Content (cat)
ls: Get-ChildItem (ls)
mv: Move-Item (mv)
cp: Copy-Item (cp)
wc: Measure-Object -line -word -character (measure)
cd: Set-Location (cd)
tail -n 15 : cat | select -last 15
tail -f cat -path -wait


OK, so the PowerShell can do pretty much anything a Linux shell could, and often with the same command. However, there aren't ready made aliases for all the commands. Luckily, you can define more of these aliases by yourself. Let's create that grep alias: Set-Alias grep Select-String. There! However, there's still a problem: if you now exit the PowerShell, your brand new alias is deleted. Luckily, you can save these into your profile file. First, type $profile to see the location of your profile file. Chances are it doesn't exist so you need to create it. After you have done that you can add your set-alias commands into it. You can then easily edit the file by typing notepad $profile.

However, when PowerShell starts the next time it will give you a warning that "the execution of scripts is disabled on this system". The command get-help about_signing explains in detail what you can do about this, but the easiest way is to restart PowerShell with the administrator rights and to enter the command set-executionpolicy remotesigned. You can now close the admin shell and open it up again with your normal rights and presto, your aliases are available to you right from the start!


Unluckily, aliases can only be created for plain commands, not for commands with parameters or pipes. However, these cases can be dealt with by creating functions. Let's create a function called tail. Open your profile file and add these lines to it:
function tail($1, $2) {
    cat $2 | select -last $1
Then, in your PowerShell, reload your profile script: . $profile (notice the dot). Now, when you want to see the last 15 lines in the given file, you can just enter this command: tail 15 [filename]. Voilà!

Further resources

I read quite a few web pages when learning the basics of PowerShell and you will probably find them useful as well. First, Microsoft, of course, has an Owner's manual as well as a large collection of useful PowerShell tips. Second, Stack Overflow has thousands of questions about PowerShell answered. Third, a Windows PowerShell blog has a more detailed list of those Unix equivalents in PowerShell. Finally, as usual, Google is your friend!

Ei kommentteja:

Lähetä kommentti