{ Code: Impossible } | this = HowI.Roll();

TAG | powershell

I mentioned previously that I am working on a dev environment setup script for a long-term project at work. The goal of this script is to get a developer’s machine ready to work on the project, installing dependencies, creating dev/test databases, etc.

Since our project will be using CouchDB my script should create/update a few databases when it is run (this part is coming soon!). But before that can happen the script needs to check for the presence of an active CouchDB instance.

Since CouchDB has a completely HTTP-based API we can test for its existence by opening up our favorite browser and visiting http://localhost:5984. This gives us:

{"couchdb":"Welcome","version":"1.0.0"}

So my script is going to need to do an HTTP GET on the url above and compare it to the JSON response that CouchDB should send back. Now normally, I might want this check to be less strict, maybe only checking that {"couchdb":"Welcome" was returned, but in this case I want the specific version number as well so this check will be fine going forward.

If I don’t get the response I expect I’ll want the script to fail out immediately; No sense in continuing with the environment setup if one of the key components is missing!


$futonurl = "http://localhost:5984"
$resp_couchdb = [string](new-object System.Net.WebClient).DownloadString($futonurl)

if( $resp_couchdb.Trim() -eq "{""couchdb"":""Welcome"",""version"":""1.0.0""}" ) {
    Write-Output "CouchDB 1.0 Found!"
    # here we can continue setting up our test/dev document stores
} else {
    throw("CouchDB v1.0 must be installed and running to continue...")
}

Althought this script is pretty simple, it shows that PowerShell is not just MS-Batch 2.0. PowerShell lets me leverage .Net to do heavy lifting from the command-line that I wouldn’t be able to do without creating a few console applications.

· ·

I just finished my first ever powershell script and I’m pretty proud of it – even though I did borrow a good portion of it.

We’re starting a pretty long-term project at work – it’s scheduled for a final deliverable date set in July of 2011 – and with our small(er) dev team I’m pretty certain more hands than my own will be working on this over the course of the entire project.

This new project is going to have a few external dependencies (Moq, StructureMap, possibly MvcTurbine) and I wanted a quicker and friendlier way for a new developer coming into the project to get up-to-speed environment wise. I originally started with a batch file. I know, I know. It’s my comfort zone. Too many years of not having something like powershell at my finger-tips.

After about 10 minutes of fighting with batch language limitations I decided to move on and try my hand at using powershell to help automate the developer environment setup.

So I borrowed some code from Adam Weigerts blog to bypass the need for the gacutil (and the .Net Framework SDK, a whopping 100mb download!). Once I had this, I just had to come up with the code to recurse over all the .dll files that are stored in sub-folders within a “Source Dependencies” folder.

From concept to finish I think this took me about an hour to come up with, I’m no programming super soldier so anyone who is doing windows development should be able to throw together a powershell script to automate their common, repetitive and annoying tasks.

The code is included below, I’ll be adding to it as the project goes on, pushing in some other environment setup features (dev db creation/sync would be the next feature for this). Now that I’ve taken a swing at PowerShell I’m really happy with it and I really am sorry it took so long for me to use it.

If you’re still automating things with Batch files, you’re missing out. Big.


BEGIN {
    Clear-Host
    $ErrorActionPreference = "Stop"

    if ( $null -eq ([AppDomain]::CurrentDomain.GetAssemblies() |? { $_.FullName -eq "System.EnterpriseServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" }) ) {
        [System.Reflection.Assembly]::Load("System.EnterpriseServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") | Out-Null
    }

    $publish = New-Object System.EnterpriseServices.Internal.Publish
}

PROCESS {
    $files=get-childitem ".\Source Dependencies" *.dll -rec|where-object {!($_.psiscontainer)}
    foreach( $file in $files ) {
        $assembly = $file.fullname
        if ( -not (Test-Path $assembly -type Leaf) ) {
            throw "The assembly '$assembly' does not exist."
        }

        if ( [System.Reflection.Assembly]::LoadFile( $assembly ).GetName().GetPublicKey().Length -eq 0 ) {
          throw "The assembly '$assembly' must be strongly signed."
        }

        Write-Output "Installing: $assembly"

        $publish.GacInstall( $assembly )
    }
}

·

Theme Design by devolux.nh2.me