The SharePoint Modernization Scanner

While spelunking through Github this week I came across a useful tool in the PNP Tools repo that can generate some pretty interesting data about your Office 365 tenant.

It’s called the SharePoint Modernization Scanner, and it claims to grease the skids for your movement to Modern and Group-ification of your existing sites.

The complete source code is there but they’ve also included a direct link to the executable if you’re not interested in building it and just want to run the darn thing, which is what I did against a few of my tenants.

Running the darn thing

The default configuration for the tool uses a Client ID and Secret for a tenant-scoped App to authenticate into the tenant, which is pretty smart because it’s not guaranteed that admin user accounts will have access to all sites, even with policies in place to enforce it. (It’s the real world, things happen)  So, before you can run this you’ll want to make sure you have such an app and have the client ID and secret. You can also use normal credentials, just be aware of the access issue.

In order to make it work you’ll need to grab a file called webpartmapping.xml from the source code and drop it into the same directory where you’ve downloaded the executable.  Then open a PowerShell session and CD into that directory and run something like this:

./SharePoint.Modernization.Scanner.exe -t tenantname -i {client_id} -s {client_secret}


The process will run for a while, depending on how much stuff is in your tenant. On one of my tenants with 400 site collections, it took about 15 minutes to run, and when it’s done, I got a nice collection of CSV files:


With this data we can see every site, its template, the deployed custom actions, and detailed information about every page and web part in the tenant.


Setting VisibilityTimeout using the Azure WebJobs SDK

The new 2.0 version of the Nuget Package for the Azure WebJobs SDK, released on February 28, contained a neat little item that I wish had existed six months ago: the ability to set a Visibility Timeout on a queue message without having to implement a custom Queue Processor.

What’s a Visibility Timeout?

A visibility timeout determines what happens when an Azure WebJob throws an unhandled exception while processing a queue message.  When such an event occurs, the message is thrown back onto the queue for a re-try, but is left in an “invisible” state for a period of time. The message will not be processed again by the WebJob until the timeout has elapsed.  When a WebJob fails to process a queue message and throws an unhandled exception five times (configurable), the message is thrown onto the “poison queue”.

By setting a value for the VisibilityTimeout, you are banking that whatever condition that caused the failure will be rectified by the time the job runs again.

In my case, I am creating Office 365 SharePoint subwebs beneath a root web, meaning the root web must be completely provisioned before the subweb can be created. Since it takes about ten minutes (more or less) to create a site collection, the ten minute value seemed about right. And the documentation seems to imply that the default timeout value is indeed ten minutes. But in practice, my job would just fail spectacularly five times in a row and shuttle off to the poison queue before I even knew what hit it.

Configuring the Timeout

Prior to v2.0 of the Azure WebJobs SDK, you needed to create a custom QueueProcessorFactory, create a class derived from QueueProcessor, and hook it all up in your WebJob’s configuration object.  I’d show you an example, but it’s pointless, because there is now an easier way.

To implement the timeout, first make sure your project’s Nuget package for Microsoft.Azure.WebJobs is updated to version 2.0.0. Then in your Main() method, just set a value for the VisibilityTimeout on the config.Queues object:


(Yes, I know I’ve committed the cardinal sin of displaying code in a screen shot, but hey, it’s one line.)

Now, create an Azure WebJob, process a message, and throw an unhandled exception. In your Queue Explorer in Visual Studio, you’ll see that your messages are there, but not visible. After the timeout elapses they’ll be picked up and processed again.



I’m speaking at the Troy .NET User group tonight

Tonight I will be speaking at the Troy (MI) .NET User Group on the topic of Azure Resource Manager. I’ll be discussing ways to automate deployment of various types of resources into Azure with speed, repeatability, and consistency as primary factors.

Here are the technical prerequisites you’ll need to install in order to follow along with the demos:

Registration and directions here.

Looking forward to seeing you there!

Wireless networking adventures in Windows 8 and Hyper-V

After rebuilding several of my Hyper-V machines on a new machine I remembered what a pain it was to configure networking on them.  For some reason, Hyper-V and wireless network adapters just don’t get along together.

Steve Sinofsky has written the definitive post on this, but he leaves out a key detail, and so does everyone else who parrots posts like that.  Not even the Virtual PC Guy had any direction that proved to solve my problems.

Fortunately a guy in Australia named Simon Waight had the solution, and I’m posting it here for the next time I forget this important little detail.

There are a couple of standard approaches to make wireless networking work with Hyper-V.  Ben Armstrong, the Virtual PC guy, advocates using Internet Connection Sharing, while Sinofsky advised using an External Switch bound to a wireless adapter, which creates a network bridge.  I liked the external Switch approach because it seemed simpler and more flexible, but Sinofsky’s advice just didn’t work

The solution, as told by Waight:  Right-click the Network Bridge in the adapter settings, and in the Properties window, under ‘The connection uses the following items’, check every checkbox, and click OK.  After some churning both the host and client networking is back online.


SharePoint Saturday Michigan – October 5

I am excited to announce that I will be presenting again at this year’s SharePoint Saturday Michgan, to be held on October 5, 2013 at Washtenaw Community College in Ann Arbor.

I will be presenting: “Creating Dynamic Charts on the Client Side with HTML5 and JavaScript”. We’ll discuss the technologies behind embedding charts in web pages, check out a few third party libraries, talk about techniques to pull data from SharePoint, and of course, show some demos.

We’ll also look at browser compatibility considerations and discuss differences between SharePoint versions.

Check out this blog between now and then as I will be posting some supplemental material as the date gets closer.

For more information go here.

Hope to see you there!

Setting multi-valued lookups in forms with jQuery

The solution presented here can be made to work in 2007, 2010 or 2013. I’ll explain later.

Setting SharePoint form fields using jQuery is a pretty standard practice nowadays, and not too hard either. We can fetch the current user, or a value in the query string, and use it to populate form fields, saving our users from having to do it themselves.

Multi-valued lookup columns, however, are not so easy to figure out, and understanding them requires some deep DOM inspection and trial and error.

Consider the form below. It could be an edit form or a new form, it doesn’t matter. They both work in the same way.


Here I have a multi-valued lookup column called “Project Document” with a number of documents in the parent library. The form shows two large text boxes (‘unselected values’ and ‘selected values’), along with an “add” and a “remove” button to shuttle the parent list items between the two text boxes.

Now you’d think that moving the choices from one text box to the other would be enough to “set” the value in the form, but you’d be wrong. Microsoft uses hidden elements to hold the “true” values present on the form, so in order to set that value we have to update both the visible and invisible elements in the form.

Digging into the DOM

The image below shows the DOM representation of the visible elements we are concerned about. This shows a 2013 environment, but the markup is the same in 2010, at least for this part of the form.


What we see here is the two text boxes (rendered as selects) along with options, about 20 or so in the “unselected” textbox, and one, titled “SET READ ONLY DATABASE” in the “selected” text box. Notice the title attributes on these selects, “Project Document possible values” and “Project Document selected values”. We will refer to these as we “move” an option from one select to the other using jQuery.

The second part, the part SharePoint uses under the hood to actually save the lookup values, is a hidden input element located just above the visible UI we have just seen.


There are actually three hidden input controls here, but we only care about the topmost one. It does not have a handy title attribute, but it has an ID of longstringofcrap_MultiLookup. This is the place where 2010 and 2013 are slightly different. The ID is a little different in 2010. We’ll fetch the input using jQuery by using the “ends with” selector, like so:

“[id$=’MultiLookup’]” for 2013 and “[id$=’MultiLookupPicker’]” for 2010.

The hidden input that stores the actual data for the selected items does so in a peculiar, pipe-delimited format. I’ll leave it to you to soak it in and try to make sense of it:


In our function we will need to create that crazy string using the option’s text and value along with that pipe-T thingy, and add or remove it from the input’s value attribute as needed.

Putting it all together

I wanted to write a function to add a selection by name, and another function to remove a selected option, also by name. I also wanted it to be as reusable as possible, so I made the column name and value as parameters to my functions. By including these functions in a globally-referenced JavaScript file, we can use this functionality everywhere on the site. Anyway here’s the code:

//var selector = "[id$='MultiLookupPicker']"; //for 2010 or 2007
var selector = "[id$='MultiLookup']"; //for 2013

function addChoice(text, columnName) {
    $("[title='" + columnName + " possible values'] option").each(function () {
        if ($(this).text() == text) {
            $(this).appendTo($("[title='" + columnName + " selected values']"));
            var multilookupPickerVal = $(selector).val();
            if ($(selector).val() == undefined || $(selector).val().length == 0) {
                $(selector).val($(this).val() + "|t" + $(this).text());
            else {
                $(selector).val(multilookupPickerVal + "|t" + $(this).val() + "|t" + $(this).text());

function removeChoice(text, columnName) {
    $("[title='" + columnName + " selected values'] option").each(function () {
        if ($(this).text() == text) {
            $(this).appendTo($("[title='" + columnName + " possible values']"));
            var multilookupPickerVal = $(selector).val();
            var valToRemove = $(this).val() + "|t" + $(this).text();
            var newValue = multilookupPickerVal.replace(valToRemove, "");


A couple of things to point out. I added two variable declarations called “selector”. Make sure only one of them is not commented out – the appropriate one for you environment. For updating the visible text boxes I am using the jQuery appendTo function, a really neat function which removes a DOM element from its current home and places it into the specified location.

Edit: Thanks to jameel’s comment below I fixed an earlier issue where I was hard coding the column name in the function. He also verified the 2010 code works for SharePoint 2007 as well.