Creating Pinned Sites Jump Lists for SharePoint 2010

This idea came to me after attending the HTML 5 Boot camp in Ottawa back in April 2011. The boot camp introduced me to a new concept in Internet Explorer 9, called Pinned Sites. Basically, this feature allows web developers to build web sites that can interact with the Desktop when users pin the site to their taskbar. Sites can be pinned in Windows 7 and Windows Server 2008 R2 by dragging the site’s tab from internet explorer down onto the taskbar. You can read more about pinned site on the following MSDN site:

http://msdn.microsoft.com/en-us/library/gg131029(v=vs.85).aspx

Controlling the behavior of the pinned sites is really easy to do from any html page. However it gets a little trickier when doing from inside of SharePoint. For example, one needs to modify the Master Page’s <head> section to be able to specify a custom color for the Navigation buttons (back and forward arrows). Note however, that if you site is using a custom Favorite Icon (favicon.ico, normally located at http://<server>/_layouts/images/favicon.ico), the navigation button will adjust their colors to match the icon’s.

Back in early June, while chatting with Todd Klindt (@ToddKlindt) during one of his “world-famous” Netcasts, he asked the chat room if anybody had any suggestions on how he could make his blog more attractive and user friendly. One of my suggestions to him was to leverage the pinned site’s features of IE. Todd had a couple of key blog posts he wanted to promote, so Jump Lists inside of a Pinned Site would work perfectly.

I then decided to venture on my own, and developed a very simple sandboxed web part that would allow non-developers folks, like Todd, to easily leverage some of the Pinned Site functionality. The web part allows users to specify a Category for their Jump List, and to enter up to 5 items in it. The following Blog post describes how to deploy and use the custom web part. Since my web part is Sandboxed, you can simply upload it in the Site Collection’s Solution Gallery and have it activated from there.

By activating the solution on your site, you will automatically get a new web part named “Pinned Site Generator”.

Simply drag and drop it onto the page you want users to pin to their desktop. Once the web part is placed on a page, go edit its properties. Under the Miscellaneous header, you will find 11 custom properties that you can fill in. The very first one is the Category Name. This is a required field if you want your jumplist to be visible at all from your pinned site. This value will show up as the heading to your list. Logical values for this field could be anything like “Articles, Sections, News, etc”. The other fields are paired together, and they include a place to specify the name of the item, and the url it will point to. If we take back the example stated above, where Todd is looking to promote specific Blog articles, then the name of the item could be “Loopback Check”, and the url value would point to Todd’s blog post at: http://toddklindt.com/loopback .

Assuming the values entered above, here is what the final result of the pinned site’s jumplist will look like:

The solution (.wsp) is available to download from my company’s Office 365 site at the following location:

http://www.ignitesoft.ca/Documents/PinnedSiteGenerator.wsp

Now, I’m sure you guys will agree with me, the value added by creating pinned sites isn’t that great, but you can be sure that the next version of IE will continue to build and improve on this front. So please, don’t be pinless, and start creating dynamic Pinned SharePoint sites.

Comparing Administrative Options for SharePoint 2010

The following exercise was undertaken in preparation for my upcoming session at the Federal SharePoint Technical User Group session on PowerShell. I wanted to prove to my audience just how fast and better PowerShell was compared to all the other Administrative options for SharePoint. I decided to go ahead and do a fairly quick and sample test, and calculate benchmarks out of it for each option.

 

The tests consisted in creating 5 site collections (each under a distinct Web Application), and have 15 new Webs created under each of them, for a total of 75 webs, and 5 site collections. The following blog article describes the benchmarks for each of the following options:

  1. STSAdm
  2. Object Model
  3. PowerShell
  4. Web Services

 

STSAdm

Alright, so we all know STSAdm. It’s been around for ages, since the original SharePoint Team Sites product in the early 2000. I went ahead and created the following batch file that implicitly called the STSAdm executable for every command:

prompt $p$g $t –

cd “C:\Program Files\Common Files\Microsoft Shared\Web server Extensions\14\BIN\”

 

stsadm -o createsite -url “http://spdemo:82/sites/SiteColl1” -ownerlogin “litware\Nik.Charlebois” -owneremail “Nik.Charlebois@Litware.com”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl1/Web1”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl1/Web2”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl1/Web3”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl1/Web4”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl1/Web5”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl1/Web6”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl1/Web7”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl1/Web8”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl1/Web9”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl1/Web10”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl1/Web11”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl1/Web12”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl1/Web13”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl1/Web14”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl1/Web15”

 

stsadm -o createsite -url “http://spdemo:82/sites/SiteColl2” -ownerlogin “litware\Nik.Charlebois” -owneremail “Nik.Charlebois@Litware.com”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl2/Web1”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl2/Web2”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl2/Web3”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl2/Web4”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl2/Web5”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl2/Web6”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl2/Web7”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl2/Web8”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl2/Web9”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl2/Web10”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl2/Web11”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl2/Web12”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl2/Web13”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl2/Web14”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl2/Web15”

 

stsadm -o createsite -url “http://spdemo:82/sites/SiteColl3” -ownerlogin “litware\Nik.Charlebois” -owneremail “Nik.Charlebois@Litware.com”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl3/Web1”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl3/Web2”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl3/Web3”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl3/Web4”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl3/Web5”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl3/Web6”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl3/Web7”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl3/Web8”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl3/Web9”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl3/Web10”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl3/Web11”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl3/Web12”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl3/Web13”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl3/Web14”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl3/Web15”

 

stsadm -o createsite -url “http://spdemo:82/sites/SiteColl4” -ownerlogin “litware\Nik.Charlebois” -owneremail “Nik.Charlebois@Litware.com”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl4/Web1”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl4/Web2”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl4/Web3”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl4/Web4”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl4/Web5”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl4/Web6”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl4/Web7”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl4/Web8”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl4/Web9”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl4/Web10”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl4/Web11”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl4/Web12”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl4/Web13”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl4/Web14”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl4/Web15”

 

stsadm -o createsite -url “http://spdemo:82/sites/SiteColl5” -ownerlogin “litware\Nik.Charlebois” -owneremail “Nik.Charlebois@Litware.com”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl5/Web1”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl5/Web2”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl5/Web3”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl5/Web4”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl5/Web5”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl5/Web6”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl5/Web7”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl5/Web8”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl5/Web9”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl5/Web10”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl5/Web11”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl5/Web12”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl5/Web13”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl5/Web14”

stsadm -o createweb -url “http://spdemo:82/sites/SiteColl5/Web15”

 

Running this script took a total of 14 minutes and 36 seconds (14:26).

Object Model

The Object Model on the other hand, allows one to write recursive loops in a more friendly way than writing them in command line script would have been. I created a new console application in C#, added a reference to the Microsoft.SharePoint v14 assembly, and made elevated calls to the proper methods. Here’s the code for the method I used:

static void Main(string[] args)

{

SPSecurity.RunWithElevatedPrivileges(delegate(){

 

DateTime time = DateTime.Now;

SPWebApplication webAPP = SPWebApplication.Lookup(new Uri(“http://spdemo:83”));

for (int i = 1; i <= 5; i++)

{

try

{

using (SPSite site = webAPP.Sites.Add(“http://spdemo:83/sites/SiteColl” + i.ToString(), @”Litware\Nik.Charlebois”, “nik.Charlebois@Litware.com”))

{

Console.Out.WriteLine(“Site Collection #” + i.ToString() + ” Created”);

for (int j = 1; j <= 15; j++)

{

using (SPWeb web = site.AllWebs.Add(“Web” + j.ToString()))

{

Console.Out.WriteLine(“\tWeb #” + j.ToString() + ” Created”);

}

}

}

}

catch { }

}

Console.Out.WriteLine(“\r\nIt took ” + (DateTime.Now.Subtract(time).TotalSeconds).ToString() + ” seconds to execute”);

});

}

 

Executing the operation using the Object Model took a total of 1,063 seconds so 17 minutes total.

PowerShell

The third option, which really was the focus of my little exercise, is PowerShell. IT people have been able to use PowerShell to manage SharePoint since the 2007 version, and even if I’ve never played with it, it could be done for SharePoint 2003. PowerShell is such an amazing tool. I find it finally gets rid of that Gap between developers and IT Pros. Administrators now have to start learning the artifacts of the SharePoint ecosystem, and finally get to start speaking the same language as developers (SPWebs, SPSite, etc). Here’s my PowerShell code for executing the operations. Please note that if you start it directly from the SharePoint PowerShell Management Shell, you do no need to include the first line to add the SharePoint Snapin.

Add-PSSnapin Microsoft.SharePoint.PowerShell

$time = Get-Date

$spWebApp = Get-SPWebApplication http://spdemo:81;

 

for($i = 1; $i -le 5; $i++)

{

$url =” http://spdemo:81/sites/SiteColl$i”;

new-spsite $url -OwnerAlias “Litware\Administrator” -OwnerEmail “Administrator@Litware.com”;

Write-Host “Site Collection #$i Created”;

for($j = 1; $j -le 15; $j++)

{

$url = ” http://spdemo:81/sites/SiteColl$i/Web$j”;

 

new-spweb $url;

Write-Host “Web #$j Created”;

}

}

$now = Get-Date

$benchmark = $now.Subtract($time)

Write-Host $benchmark.TotalSeconds;

 

Just look at how simple the code is, and just how close to the Object Model code it looks. I wasn’t surprised to see that PowerShell was the fastest of all tests, scoring a 296 seconds or 5 minutes to execute.

Web Services

Just to be fair, I had to go and evaluate all possible options, including this last one, the Web Service API. SharePoint out of the box comes with a wide range of different Web Services of all kinds of flavor. To execute this test, I had to make calls to 2 distinct web services. The first one, being the Central Admin service, which allows us to create new Site collections. By default, this web service is located at http://<servername>/_vti_adm/admin.asmx. The second web service, is the one that would allow me to create Webs under the newly created Site Collection. This one is located at http://<servername>/_vti_bin/sites.asmx. To test this API, I went ahead and created a new Console App in C#, and called the following method:

static void Main(string[] args)

{

DateTime begin = DateTime.Now;

CentralAdmin.Admin proxy = new CentralAdmin.Admin();

SitesWS.Sites sitesWS = new SitesWS.Sites();

sitesWS.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;

proxy.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;

 

for (int i = 1; i <= 5; i++)

{

proxy.CreateSite(“http://spdemo:84/sites/SiteColl” + i.ToString(), “SiteColl” + i.ToString(), “”, 1033, “STS#1”, “Litware\\Administrator”, “Nik”, “Administrator@Litware.com”,””,””);

Console.WriteLine(“Site Collection #” + i.ToString() + ” Created…”);

for (int j = 1; j <= 15; j++)

{

sitesWS.Url = “http://spdemo:84/sites/SiteColl” + i.ToString() + “/_vti_bin/sites.asmx”;

try

{

sitesWS.CreateWeb(“Web” + j.ToString(), “Web #” + j.ToString(), “”, “STS”, 1033, true, 1033, true, 1033, true, true, true, true, true, true, true);

}

catch { }

Console.Out.WriteLine(“\tWeb #” + j.ToString() + ” Created…”);

}

}

Console.WriteLine(“Completed in ” + DateTime.Now.Subtract(begin).TotalSeconds);

}

 

In theory, I was expecting this test to be the slowest one of them all. I was very surprised to see that it scored a respectable 13 minutes and 30 seconds. Therefore beating both STSAdm and the Object Model has the fastest method of creating batch sites. Please note, however that this was executed on the SharePoint server itself, so there was no delay sending the Soap Envelops over the wire.

 

Summary

Here’s a table to summarize my findings. PowerShell, as expected is the undisputed King of Management tools for SharePoint!

Method Name Time of Execution (in minutes)
STSAdm 15
Object Model 17
PowerShell 5
Web Services 13.5