Wednesday, 30 January 2013

Check a Powershell Script for syntax errors

I recently had the unfortunate experience of sending off Powershell scripts to a client, only for them to come back because they did not run. A missing double quote was the culprit, but there must be a way to nip the problem in the bud.

The solution came from this great post:

param($path, [switch]$verbose)
if ($verbose) {
    $VerbosePreference = ‘Continue’
}
trap { Write-Warning $_; $false; continue }
& `
{
    $contents = get-content $path
    $contents = [string]::Join([Environment]::NewLine, $contents)
    [void]$ExecutionContext.InvokeCommand.NewScriptBlock($contents)
    Write-Verbose "Parsed without errors"
    $true
}

A simple script to check scripts (who watches the watchmen?).  It taks the path of the script to be checked and returns a simple boolean result of the validity of the syntax. True genius. I have definitely added this as a step in my deployment process.

Tuesday, 29 January 2013

Create Nintex Constants in Powershell

My current project has the requirement of a 'dll free' installation. That means that all the good code that was written in C# to create Nintex Constants  (I used http://jaclynsaito.wordpress.com/2011/09/13/creating-nintex-workflow-constants-programmatically/ as a reference) is not allowed on any servers. Bummer.

So, how was the problem solved? The solution: Powershells impressive 'Add-Type'.

The syntax I used is something like this:

Add-Type -TypeDefinition $source -Language CSharpVersion3 -ReferencedAssemblies $references -passThru  -ErrorAction SilentlyContinue

(the official blurb is here)

The code is quite straightforward, but the real kicker is the ReferenceAssemblies. By default, Add-Type only gives a limited number of references (System.dll and System.Management.Automation.dll.) So, if I want to add a reference to Nintex.Workflow.dll (which is helpful when trying to add Nintex constants), I will need to provide the full path the dll as part of the referenced assemblies parameter. This becomes even more interesting when multiple references are required.

The code I used to solve this problem is as follows:
I created a function to search the GAC for a specific filename (such as Nintex.Workflow.dll).  The code looks something like this:

function GACFinder([string] $name = $(throw "Value cannot be null: name"))
{
return (Get-ChildItem -Path C:\windows\assembly -Filter $name -Recurse | Select-Object -first 1).FullName;
}

I call the code as follows:
$references = (
(GACFinder("Nintex.Workflow.dll")),
(GACFinder("System.Xml.dll"))
)

The code does a recursive search of the GAC and returns the first instance it finds for the requested dll. For example, I get
C:\windows\assembly\GAC_MSIL\Nintex.Workflow\1.0.0.0__913f6bae0ca5ae12\Nintex.W
orkflow.dll as the reference for Nintex.Workflow.dll.

So, the result of the $references is an array of the references that I need for my code to run. Problem solved. I can now create my 'NintexHelper' C# class and reference it in my Powershell code.

NOTE: If you have multiple versions of a dll in the GAC (perhaps with multiple strong name keys), then this code may cause a problem if the first item it selects is not the one you wanted. It will work in most cases, but I have been burnt before and you have been warned.

Tuesday, 22 January 2013

Introduction

Starting Out


I have had the priviledge (and pain) of working on a SharePoint 2010 development project for the last 12 months. During that time, I have experienced the good, the bad and the weird that is SP 2010 development.

I thought a blog would be good forum to share some of findings and solutions some of the interesting issues I have encounterd on my (limited) journey. Hopefully, some if it may actually be helpful. Most likely, I will be writing it for myself and the two people I pay to visit the site.

It should be interesting .....