PowerShell Part 1 – Getting Started

As part of ‘DEV306: Taming SOA Deployments using Windows Server AppFabric’ I showed a couple of PowerShell scripts that can be used to deploy a simple WCF service. The demo was pretty quick due to 60 minute session length and the fact that reading PowerShell is not the most exciting presentation. Over the next couple of blogs I’m going to walk through the scripts which are available from http://public.me.com/stefsewell. This first post is just to whet the appetite and introduce some PowerShell basics and concepts.

To dig into PowerShell I’ve been using the MEAP edition of Windows PowerShell in Action, 2nd Edition by Bruce Payette and I definitely recommend it.

The Basics

To run PowerShell commands you can use either the PowerShell console or the PowerShell ISE (integrated scripting environment). The ISE has some neat features such as breakpoints and allows you to easily build up scripts rather than issuing single commands.

Note: On a 64-bit system there is a 32-bit and 64-bit version of the PowerShell console and ISE. Confusingly the 64-bit version runs out of the C:\Windows\System32 directory while the 32-bit version runs out of c:\Windows\SysWOW64. You want to be using the 64-bit version, we’ve seen some strange behavior and errors when trying to use the 32-bit version on a 64-bit OS.

Getting Help…

The first script 1-PowerShell basics is just an introduction to some of the PowerShell goodness. The first useful thing is knowing how to get help and as with all PowerShell commands this takes the form of a verb-noun pairing:

> Get-Help

This gets you into the first page of the help system and from here you’ll want to drill down into specific commands:

> Get-Help invoke-command

You’ll get a description of the command, including the supported parameters. One of the very useful standard parameters for get-help is the -examples:

> Get-Help Invoke-Command -examples

This returns you a number of usage examples. Not only is help provided for specific commands but there is also help on a number of more general topics:

> Get-Help about_remoting

This will give you a good overview of the PowerShell remoting features.

Wildcards are supported so to see all the ‘about’ topics:

> Get-Help about*

Using Aliases…

Next up is navigating around using a familiar set of commands. The standard PowerShell commands can take a little getting used to, especially after years of either UNIX or DOS. To make you feel at home, there is the concept of an alias. An alias is simply another name for a command, for example Get-ChildItem will be more familiar as ls or dir to most people. To see the list of mapped aliases:

> Get-Alias

You can use cd to change directory which is an alias for Set-Location.

Variables…

PowerShell supports variables and uses a $ prefix:

> $foo = “TechEd”

To display the contents of $foo:

> Write-Host “The value of foo is $foo”
The value of foo is TechEd

The “” delimited string is evaluated prior to printing. If you use a single quote ‘ then a literal string is created:

> Write-Host ‘The value of foo is $foo’
The value of foo is $foo

Conditionals…

To check to see if a variable is not null:

if(-not $foo) { # do something } else { # do something else }

Slightly odd syntax but you check for -not of the variable, ! can be used as shorthand for -not. The comment character in PowerShell is #.

Loops…

Within a script, foreach and while loops are supported:

Foreach ($file in Get-ChildItem C:\) {
 
    $file.name
}

$count = 0;

While($count -lt 10) {
    $count++
    "$count"
}

To get access to environment variables you use $env:, for example:

> Write-Host $env:ComputerName

Using Pipes…

Both DOS and UNIX support piping the output from one command into another, allowing complex chains of commands to be linked together. PowerShell also supports this:

> get-service | where-object {$_.Status -eq "Stopped"}

This returns all of the installed Windows services with a status of stopped. The $_ is an iterator variable allowing you to enumerate over all of the results returned from the get-service command. The equality operator is -eq, in the same style as -not.

Additional Modules…

Before going much further, we need to relax the default security setting slightly. Out of the box a script execution policy of Restricted is set. This prevents the loading of configuration and the running of scripts. I find that changing this to RemoteSigned works well, this allows local scripts to run and signed scripts (by a trusted publisher) if the are downloaded from the internet.

> Set-ExecutionPolicy RemoteSigned

A number of Microsoft technologies have an accompanying PowerShell module that contains commands allowing automation. For example IIS comes with WebAdministration and Windows Server AppFabric brings along ApplicationServer. To use these modules you first need to be running in an elevated PowerShell console (run as Administrator) then import the module:

> Import-Module WebAdministration
> Import-Module ApplicationServer

To see the commands available in a module:

> Get-Command -module WebAdministration
> Get-Command -module ApplicationServer

There are commands allowing you to manage web applications, virtual directories, application pools, the AppFabric monitoring and workflow stores, and much more. We’ll see examples of these in the WCF service installation script in the next post.

A great feature of PowerShell is the concept of the provider, this allows a hierarchical structure to be navigated as if it was a physical drive. Consider how we navigate and administer the file system: cd (set-location), dir (get-childitem), mkdir (new-item) etc. These same commands can be used to navigate any hierarchy that has a provider such as:

cert: the certificate store
wsman: WinRM settings
HKLM: registry HKEY_LOCAL_MACHINE
IIS: Internet Information Server

This allows you to do the following:

> dir IIS:\Sites\Default Web Site\
> dir HKLM:\SOFTWARE\Microsoft\MSDTC

To change to the IIS ‘drive’:

> IIS:

Your PowerShell prompt will now show you an IIS path rather than a file system path. You navigate around using the standard commands. Note that WSMAN: doesn’t work, you need to cd WSMAN: explicitly.

.NET Integration

PowerShell is tightly integrated with .NET allowing objects to be constructed and consumed directly. For example:

> Write-Host ([System.DateTime]::Now)

The () indicates the expression is to be evaluated, the [] indicates a .NET type. The :: denotes a method call.

> [Reflection.Assembly]::LoadWithPartialName("System.Messaging")
> [System.Messaging.MessageQueue]::Create(".\Private$\MyNewQueue")

This second example shows how to create a private message queue in MSMQ. The System.Messaging assembly is loaded via the Reflection API.

This is really only just scratching the surface, however it gives us enough to be able to read through the installation script and understand what is going on. That’s for the next post…

PS: The canonical Hello, World! in PowerShell is simply:

> ‘Hello, World!’

Not tremendously useful but we’ve now ticked that box.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: