Extending PowerShell for SharePoint with Custom Commandlets

May 5 2010 2 comments

In my previous entry on SharePoint and PowerShell I promised I’d show you how to implement custom commandlets for Master Page manipulation. SharePoint 2010 ships with a wide array of commandlets, but none of them seem applicable here. This should also serve as a nice generic example on how to implement simple commandlets.

In order to work with this example, you will need to install the PowerShell reference assemblies that ship with the Windows SDK (pick the one that is most appropriate for your OS). Create a new class library project, add a reference to System.Management.Automation and we’re ready to go:

    [Cmdlet(VerbsCommon.Set, "MasterPage")]
    public class SetMasterPageCommandlet : Cmdlet
    {

    }

PowerShell has a naming pattern where the commandlets are of the form verb-noun. The verb part is chosen from a set of common verbs (Get, Set, Write, Read etc.), and the noun can be anything you like. The snippet above defines a commandlet called Set-MasterPage.

Obviously we’ll need to accept a bunch of parameters, so let’s define them next:

    [Parameter(Position = 0, Mandatory = true)]
    [ValidateNotNullOrEmpty]
    public string SiteUrl
    {
        get; set;
    }

    [Parameter()]
    public string MasterUrl
    {
        get; set;
    }

    [Parameter()]
    public string CustomMasterUrl
    {
        get; set;
    }

The Parameter attribute tells PowerShell that the property will receive an argument from the command line. We’re saying that SiteUrl is a mandatory parameter, the first positional parameter and it must not be null or an empty string. As for MasterUrl and CustomMasterUrl, I want to make it possible to set one, the other or both, so I can’t make either of them mandatory.

That’s all from the ceremony department, let’s get to the meat of the matter. Add a reference to Microsoft.SharePoint.dll and finish the commandlet with the following method:

    protected override void BeginProcessing()
    {
        base.BeginProcessing();

        if (string.IsNullOrEmpty(MasterUrl)
            && string.IsNullOrEmpty(CustomMasterUrl))
            throw new InvalidOperationException(
                "You must specify a master page, a custom master page or both");

        using(var site = new SPSite(SiteUrl))
        using(var web = site.RootWeb)
        {
            if(!string.IsNullOrEmpty(MasterUrl))
                web.MasterUrl = MasterUrl;

            if(!string.IsNullOrEmpty(CustomMasterUrl))
                web.CustomMasterUrl = CustomMasterUrl;

            web.Update();
        }
    }

PowerShell commandlets have four interesting lifecycle methods: BeginProcessing, EndProcessing, StopProcessing and ProcessRecord. The ones we want to use depend on the sort of commandlet we’re writing. In this case, the commandlet is purely a set operation that doesn’t need to return anything or process piped input. Additionally, setting the master page is a quick operation, so we won’t support aborting the operation halfway through. That means implementing BeginProcessing is enough.

Oh, and you’ll probably want to try the command out, too. Build the project, fire up PowerShell, load the assembly and give your commandlet a try:

    Import-Module "C:\Path\To\Your.Module.dll"
    Set-MasterPage http://localhost/ `
        -CustomMasterUrl MyCustomMasterPage.master

That’s all there is to it. Have fun!

Popularity: 1% [?]

2 comments to “Extending PowerShell for SharePoint with Custom Commandlets”

  1. [...] This post was mentioned on Twitter by SharePoint Dev Wiki. SharePoint Dev Wiki said: #SharePoint #Link Extending PowerShell for SharePoint with Custom Commandlets | SharePoint Blues http://ow.ly/17h42Z [...]

  2. [...] Extending PowerShell for SharePoint with Custom Commandlets (SharePoint Blues)In my previous entry on SharePoint and PowerShell I promised I’d show you how to implement custom commandlets for Master Page manipulation. SharePoint 2010 ships with a wide array of commandlets, but none of them seem applicable here. This should also serve as a nice generic example on how to implement simple commandlets. [...]

Leave a Reply