PowerShell – An introduction, Part I

Over the past months I’ve been holding a couple of workshops on PowerShell. It’s quite an interesting topic, but not something I originally thought would be suitable for this blog and its web-development theme. Still, having given this a bit more thought I decided that there are so many useful features and cmdlets that could be of great value when hosting a web site or two that I should reconsider.

This first post will be a brief introduction for those who’ve never touched PowerShell before. Later posts will probably be more hands-on and less theoretical. I’ll gladly receive any thoughts or comments you may have.

Installing

PowerShell can be downloaded from the Microsoft web site. Simply point your browser to https://www.microsoft.com/powershell and you’ll be set in no time. Apart from the executables you’ll find a lot of useful links, like the one to the PowerShell team blog and the IIS 7.0 PowerShell Provider.

Basic syntax

Okay, having installed PowerShell we’re now ready to try some basic commands.

Echoing text

Any object not used in an assignment or operation will be echoed to the screen. This means that if we simply type a string like this:

PS C:\>“Hello World”
Hello World

It will be displayed on the screen. (Without the quotes.) The same goes for numbers, so by typing an equation you’ll be given the result:

PS C:\>1 + 1
2

If you type in an array PowerShell will echo it one line at a time:

PS C:\>“foo”, “bar”, “bletch”, “fum”
foo
bar
bletch
fum

Basically you could say that any object will, unless told otherwise, be displayed on screen using its default formatting. The default formatting is defined by the object itself.

Calling executables

Running an executable is more or less as easy as in the regular command shell. At least if the .exe is in the PATH. For any executable not in the PATH you'll need to write the full path of the .exe for it to successfully execute. This may seem like a hassle, but this behavior is by design and was implemented in order to prevent you from accidentally executing an .exe.

Cmdlets

Cmdlets (pronounced "command-lets") are PowerShell-specific commands. They follow a strict naming standard of verb-noun, (for example "get-date" or "set-location").

Get-Help

This a command that you'll use quite a lot. Get-Help <cmdlet> will display some generic information about the cmdlet in question. Using various switches such as "-detailed", "-examples" or "-full" you can then get more detailed information on the cmdlet in question. For example:

Get-Help Get-Date -examples

This will show you the generic information on get-date as well as some sample code.

Set-Location

Set-Location is the PowerShell equivalent to the old MS-DOS command "CD". Some examples are:

Set-Location ..
Set-Location C:\Windows\
Set-Location D:

 

Aliases

Actually you can write CD in PowerShell too. By default PowerShell will set up an alias for you that points to the Set-Location cmdlet. This means that CD is just another name for Set-Location. If you want you can create your own aliases using the New-Alias cmdlet:

New-Alias gh Get-Help

This creates an alias named gh that points at Get-Help. If you type Get-Help gh PowerShell will be smart enough to show you the documentation for the Get-Help cmdlet.

Object orientation

One of the cool things about PowerShell is that it is object oriented. This means that all the cmdlets return objects, which can, in turn, be passed on to another cmdlet. To illustrate this, let’s look at the DIR-command.

Using DIR

You can use DIR in PowerShell, but it is actually an alias for the get-childitem cmdlet. How can you tell? Use the get-command cmdlet:

PS C:\> get-command dir
 
CommandType     Name                                                Definition
-----------     ----                                                ----------
Alias           dir                                                 Get-ChildItem

Since DIR in PowerShell is not the same thing as DIR in MS-DOS that means you can’t use all the switches you might be used to, for example DIR /w will not work.

So, what happens when you type DIR and press enter?

Well, first of all the get-childitem cmdlet is run. It looks in your present working directory, creates a collection of all the items there, and returns it. You can think of this collection as a big Excel Spreadsheet if you like.

Once the collection is returned to PowerShell it will be displayed on screen. This is because the default behavior for PowerShell when it comes to any object is to display it on screen. We saw this earlier with strings, integers and arrays.

The collection will be displayed using a default presentation. This does not mean you will see all the information the object contains. If I run Get-ChildItem (DIR) on a folder I’ll get the standard information. Like so:

PS C:\Test> dir
 
    Directory: Microsoft.PowerShell.Core\FileSystem::C:\Test
 
Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        2008-05-28     11:25      45568 Document.doc
-a---        2008-05-26     10:00    8993629 Satisfaction.mp3
-a---        2008-05-28     11:25       1599 Text.txt

Even though I get only text on screen the actual object returned is much more complex. I can demonstrate this by piping the object into another cmdlet.

Piping

A simple MS-DOS piping example would be type file.txt | more. Actually you can use more in PowerShell as well, but let’s look at another, more interesting cmdlet that we could pipe the object into; Format-List.

Format-List

By default the output of Get-ChildItem is formatted in a table, but let’s say we want it as a list instead? No problem. Simply use the following syntax:

PS C:\Test> dir | format-list
 
    Directory: Microsoft.PowerShell.Core\FileSystem::C:\Test
 
Name           : Document.doc
Length         : 45568
CreationTime   : 2008-05-28 11:22:53
LastWriteTime  : 2008-05-28 11:25:26
LastAccessTime : 2008-05-28 11:25:26
VersionInfo    :
 
Name           : Satisfaction.mp3
Length         : 8993629
CreationTime   : 2008-05-28 11:24:33
LastWriteTime  : 2008-05-26 10:00:46
LastAccessTime : 2008-05-28 11:24:33
VersionInfo    :
 
Name           : Text.txt
Length         : 1599
CreationTime   : 2008-05-28 11:22:53
LastWriteTime  : 2008-05-28 11:25:35
LastAccessTime : 2008-05-28 11:22:53
VersionInfo    :

We still have the default information, only presented in a different manner. Still, there is a lot more information we could get, by using the –property switch. By simply using the following syntax: dir | format-list –property * we get all the properties of each and every item in the directory. The output is quite extensive:

PS C:\Test> dir | format-list -property *
 
PSPath            : Microsoft.PowerShell.Core\FileSystem::C:\Test\Document.doc
PSParentPath      : Microsoft.PowerShell.Core\FileSystem::C:\Test
PSChildName       : Document.doc
PSDrive           : C
PSProvider        : Microsoft.PowerShell.Core\FileSystem
PSIsContainer     : False
Mode              : -a---
Name              : Document.doc
Length            : 45568
DirectoryName     : C:\Test
Directory         : C:\Test
IsReadOnly        : False
Exists            : True
FullName          : C:\Test\Document.doc
Extension         : .doc
CreationTime      : 2008-05-28 11:22:53
CreationTimeUtc   : 2008-05-28 09:22:53
LastAccessTime    : 2008-05-28 11:25:26
LastAccessTimeUtc : 2008-05-28 09:25:26
LastWriteTime     : 2008-05-28 11:25:26
LastWriteTimeUtc  : 2008-05-28 09:25:26
Attributes        : Archive
 
PSPath            : Microsoft.PowerShell.Core\FileSystem::C:\Test\Satisfaction.mp3
PSParentPath      : Microsoft.PowerShell.Core\FileSystem::C:\Test
PSChildName       : Satisfaction.mp3
PSDrive           : C
PSProvider        : Microsoft.PowerShell.Core\FileSystem
PSIsContainer     : False
Mode              : -a---
Name              : Satisfaction.mp3
Length            : 8993629
DirectoryName     : C:\Test
Directory         : C:\Test
IsReadOnly        : False
Exists            : True
FullName          : C:\Test\Satisfaction.mp3
Extension         : .mp3
CreationTime      : 2008-05-28 11:24:33
CreationTimeUtc   : 2008-05-28 09:24:33
LastAccessTime    : 2008-05-28 11:24:33
LastAccessTimeUtc : 2008-05-28 09:24:33
LastWriteTime     : 2008-05-26 10:00:46
LastWriteTimeUtc  : 2008-05-26 08:00:46
Attributes        : Archive
 
PSPath            : Microsoft.PowerShell.Core\FileSystem::C:\Test\Text.txt
PSParentPath      : Microsoft.PowerShell.Core\FileSystem::C:\Test
PSChildName       : Text.txt
PSDrive           : C
PSProvider        : Microsoft.PowerShell.Core\FileSystem
PSIsContainer     : False
Mode              : -a---
Name              : Text.txt
Length            : 1599
DirectoryName     : C:\Test
Directory         : C:\Test
IsReadOnly        : False
Exists            : True
FullName          : C:\Test\Text.txt
Extension         : .txt
CreationTime      : 2008-05-28 11:22:53
CreationTimeUtc   : 2008-05-28 09:22:53
LastAccessTime    : 2008-05-28 11:22:53
LastAccessTimeUtc : 2008-05-28 09:22:53
LastWriteTime     : 2008-05-28 11:25:35
LastWriteTimeUtc  : 2008-05-28 09:25:35
Attributes        : Archive

As long as something is returned it is possible to daisy-chain additional cmdlets onto the previous one. We could, for example, add | more to the command above to divide it into smaller chunks. We could use the Out-File cmdlet to save the result to a textfile, etc.

Summary

What have we covered so far?

  • PowerShell is object-oriented
  • By default any object will be displayed on screen, so if you want to know what 2+2 equals, simply type 2+2.
  • You can call standard .exe applications, etc from PowerShell, but they either need to be in the PATH, or you need to write the full path to them.
  • PowerShell-specific applications are called cmdlets (“Command-lets”)
  • Most MS-DOS commands work, but they’re usually aliases to their PowerShell equivalent, so you might not be able to use all the switches you’re used to.
  • You can use the | to daisy-chain cmdlets together, such as dir | format-list | more

We still haven’t covered things like functions, variables, creating .NET objects, etc. I also plan to write a few samples showing how to use the cool cmdlets to get information from computers on the network, looking for specific files, exporting to Excel, printing, etc. As always I’d be happy to receive feedback and suggestions on things to cover.

/ Johan