Sorting the SharePoint Quick Launch Menu in PowerShell

I recently had to work with a SharePoint site which had accumulated an enormous number of links in its left-hand, (or ‘quick launch’ in SharePoint parlance), menu. Unfortunately, I wasn’t able to activate the ‘SharePoint Publishing Infrastructure’ feature for the site in question, meaning I couldn’t use the automatic sorting functionality. Instead, all I had available in the interface was the clunky list of items with a pull-down menu to specify the position they should appear in.

reorder-quick-launch

Unsorted quick launch and rudimentary sorting interface.

A quick search showed up lots of examples of how to add and remove individual links or how to export /  import via an XML file, but sorting seems not to come up. (Maybe everyone else is better at managing what ends up in their navigation elements?). Regardless, armed with my trusty PowerShell ISE I reckoned I could whip something up to fulfil my requirement.

My plan was simple:

  1. Get the specified site’s quick launch.
  2. Create a sorted copy of the links in the quick launch.
  3. Clear the current quick launch.
  4. Copy back in my sorted list of links.
  5. Treat myself to a nice cup of tea and a biscuit.

Here’s the quick and dirty solution I came up with:

That fixed my immediate problem but when I get five minutes I’ll come back and make a function out of it. I’d like to be able to specify the site and the specific section I want sorted, perhaps with the ability to sort the top-level sections too.

First Steps With PowerShell DSC and Azure IaaS

Earlier this month, Microsoft announced new functionality in the PowerShell SDK which allows us to use Desired State Configuration (DSC) in combination with Microsoft’s Azure IaaS offering.

The introductory examples of DSC I’ve seen so far tend to concentrate on the WindowsFeature and File resource types. Whilst these are no doubt useful, (and quite spiffy), I couldn’t see how to use them to achieve some of the more complex operations I’d like to undertake when provisioning VMs in Azure.

One of the tasks I always perform on freshly minted Azure VMs is to change the power plan in Windows from the default of ‘Balanced’ to ‘High Performance’. This is a simple step you can take to improve performance but it’s a hassle to do it manually every time you spin up a VM.

Step up DSC!

Writing the Script

First up I created a script which defines the configuration I want to enact on my new VM:

I’m still new to DSC but I think of ‘Configuration’ as a function and the ‘node’ construct a way to scope which hosts the function is going to run on.

Once the function and the scope are defined we get down to business. Normally, this is where the examples start adding IIS or copying files around. What I wanted to do was run a command. Specifically, the command to set the power plan to high performance.

The script resource in DSC allows us to do exactly this. It’s broken into three sections:

  • TestScript – a block of code which, when run, checks whether the power plan is set to high performance or not. If it returns false the SetScript block is run.
  • SetScript – a block of code which does the heavy lifting. In this instance, setting the power plan to high performance.
  • GetScript – another block of code which, apparently, must return a hash table. (I haven’t really got my head around the GetScript section – more reading required on my part…)

Compiling the Configuration

Having written our script we need to compile it into a MOF. I had a bit of trouble with this but eventually figured out I needed to dot source my script before calling the function configuration I had defined within it (‘SetPowerPlan’ above).

This creates a folder in the current working directory named SetPowerPlan which contains a file called localhost.mof.

Publishing the DSC

Now we’ve written and compiled our configuration it has to be published so it’s accessible to our freshly minted VMs. The new ‘Publish-AzureVMDscConfiguration’ commandlet enables this.

It bundles our compiled code into a .zip file and uploads it to an Azure storage container – where better to provide a central location for our nascent VMs to read their configurations from?

Including the DSC When Provisioning a VM

Now our script is written, compiled and in a location new VMs can access it, we just need to make sure it’s run when we provision a new VM. We can do this by using the ‘Set-AzureVMDSCExtension’ commandlet to inject the DSC script into the VM configuration object.

Then, when the new VM boots, the Azure VM agent will install the PowerShell DSC Extension, which in turn will download the ZIP package that we published previously, execute the “SetPowerPlan” configuration that we included as part of SetPowerPlan.ps1, and then will invoke PowerShell DSC by calling the Start-DscConfiguration cmdlet.

Here’s an example of creating a new VM which includes our DSC script:

Conclusion

So there we go, still a fairly simple example but my mind is already racing trying to come up other uses for this. Another obvious one I’m thinking of is setting the correct locale and time zone in new VMs but really, the possibilities are endless.