Monday, July 6, 2009

Windows PowerShell for developers part 1

So as some of you might know I am a nerd at heart. This factors into my constant need to learn everything I can about exciting new technologies and finding a way to integrate them into my daily development life.

One of those new technologies is Microsoft PowerShell. For those of you who haven't heard of it please remove yourselves from under your respective rocks and join us in the 21st Century! If after removing yourself from under said rock you still don't know what PowerShell is then just google it! I will, however, give you one good link as a place to get started.

Now that we're all up to speed that PowerShell exists and what it is let's dive into a quick primer so you can follow along with today's lesson....

We will be utilizing a profile to store our variables and functions for future use instead of creating individual scripts. Perhaps in a future post we can discuss the use of scripts in conjunction with your profile.

Does anyone in class not have a profile? Anyone? Bueller... Bueller...
Does everyone know how to check to see if they have a profile? Well if not it is very easy to find out and very easy to create one. So, everyone follow along.

(If you are this far into the post I will assume that you know how to open PowerShell)

Do I have a profile?
To check to see if you have a profile simply open PowerShell and type:

Test-Path $profile

If this statement returns True then you have a profile. Otherwise you're out of luck and will have to create one.

How do I create a profile?
Simply type

New-Item
-Path $profile -ItemType file -Force

And abrakadabra you have created a profile! Congratulations. Now we can get to the exciting stuff!

As I mentioned above I like to find ways to integrate new technology (like PowerShell) into my daily development life. There are a few ways that I have found that have made a few mundane tasks a little easier thanks to PowerShell and the profile. However, before we can dive into that you must edit your profile.

How do I edit my profile?
To edit your profile type the following:

notepad $profile

This will open your profile in Notepad. Personally I prefer to use Notepad++ but that is entirely up to you.

It's worth stating that your profile will be loaded every time you open a PowerShell console. This means that instead of writing a few statements every time you need to accomplish a task you can write it once and reuse it. For a developer this should be nothing new. If it is new then you may want to think about picking up a development book or finding a new line of work ;-)

I know I know.... Quit your yappin' and get down to some PowerShell!

The first few tasks that I use PowerShell to accomplish are related to Source Control (I use SVN). Namely Updating and Committing. To do this we have a few things to do.

  1. Create a variable to store the directory of our project
  2. Create a function to update our project from the repository
  3. Create a function to commit our changes
Creating variables
Creating variables is very easy. We will create a variable in our profile called "$projectDir" and give it a value of "C:\Projects\MyProject"

$projectDir = "C:\Projects\MyProject"

Now wasn't that easy? Your profile should now look like this:


Now that we have our variable let's create our first function (as most people who read this post will be developers I won't go into what a function is.

Creating our first function
In point number two of our Source Control tasks we need to create a function to handle updating our project from our SVN repository.

Let's first create the function definition

function Update-Project { }

As you can see it looks somewhat like a JavaScript function except there are now parentheses. Parans are only required if the function requires parameters.

There are several things that I like to do for every function that I create. The first is to put a comment either on the first line of the body or directly above the definition stating the intention of the function. To create a comment simply prepend a # to any string:

# Updates the current project from the SVN repository
function Update-Project { }

Your profile should now look like this:

Now down to the meat of the function. If you have SVN then you may be familiar with the command svn up "C:\Projects\MyProject". If so, you will recognize this:

function Update-Project
{
svn up $projectDir
}

Adding some eye candy
As you can see, this is a great first function due to its simplicity and usability. One additional piece of eye candy that I like to throw into my functions is a statement to the console stating what is happening. We do this with the statement Write-Host like this:

Write-Host "Updating project $projectDir" -ForegroundColor Yellow

Your profile should now look like this:

Notice the -ForegroundColor parameter.
This is used to just make things look a little nicer.


Reloading your profile
Now save your profile and either close and re-open PowerShell or type ". $profile". Note that there is a period (.) and space ( ) before the dollar sign ($). This will reload your profile without having to close PowerShell. Some of you may get an error when reloading your profile stating something about PowerShell being unable to execute scripts. This is due to your ExecutionPolicy. If you are one of those people read this.
If we look at this in PowerShell we can see the following:

You can see that we got our nice yellow text and the command was executed. Disregard the 'skipped' statement (C:\Projects\MyProject doesn't actually exist on my machine ;-))

Creating a function with parameters
Now that we have our first function out of the way let's go ahead and create our second function for committing changes to our SVN repository. This function will be very similar to our Update function so I will just type it out:

# Commits changes to the current project
funtion Commit-Project ([string] $message)
{
Write-Host "Commiting $projectDir to SVN" -ForegroundColor Yellow
svn ci $projectDir -m $message
}

As you can see we do have one minor difference for this function. That is the inclusion of a parameter.

[string] $message

The "[string]" denotes that it is of type string and "$message" is the local-scope variable used store it's value.

Your profile should finally look like this:


Conclusion
All-in-all these two functions are very simple but can save you a lot of typing over the course of a few months of development if you like to use the command line. I hope you are able to take this knowledge and come up with more and better ways to utilize the power of PowerShell in your every day development.

In a future post I'll look at making our functions even more generic for those of you who work on more than one project at a time as well as how to use MSBuild with PowerShell.