Going multi-tenancy with SharePoint 2010

I recently needed to do a multi-tenancy installation of SharePoint 2010 for a customer. I was very impressed by the AutoSPInstaller scripts to do a full install of SharePoint, so I figured: I want to use this!

So I modified the script to handle multi-tenancy installations as well. This was actually not that complicated. I altered the Service-Applications to have an additional attribute “PartitionMode”, which can be true or false. This will trigger the corresponding PowerShell switch for creating the Service-Application.

When doing a multi-tenancy installation I also modified the installation of the root web-application for the hosting as described by Spence Harbar in his Rational Guide to Multi Tenancy.

I also added new Configuration-Elements to setup tenants (aka Subscriptions).

This code was originally based on the 2.5.5 version and was recently re-based to 2.5.7.

The patch can be found on the CodePlex project site.

IIS TimeOut while debugging a SharePoint application

Who has not encounterd this problem: you’re just doing some debugging on your favorite SharePoint application and all over sudden – bam! The application pool gets recycled.

iis_app_timeout

Well, the problem is the timeout associated with each application pool. When IIS detects that an application pool is not responding anymore IIS just assumes something terrible happend and recycles the application pool. But all that really happend is some plain-old-debugging.

In order to circumvent this problem you have to disable the pinging of application pools by IIS. Just open up the advanced settings of the IIS application pool and set pinging to false.

iis_adv_setting

No ULS Logging in SharePoint 2010

Sometimes you encounter errors, that seem to stick around forever. I recently noticed on my SharePoint 2010 dev-machine, that the ULS doesn’t seem to be working anymore. For some strange reason the ULS is complete empty. No logmessages whatsoever. Changing the loglevel doesn’t seem to have any impact at all.

Only messages while deploying solutions from Visual Studio 2010 where showing up in the log.

Can you spot the error?

After ignoring this problem for a couple of weeks – who needs logfiles anyway, when you’re doing everyhting the perfect way! – I actually did run into a problem with a custom component and I just couldn’t figure out what’s going wrong. Having SharePoint present me a correlation-id doesn’t help at all if you have no logmessages!

The Solution!

The solution is actually quite simple, and it’s always the same cause when working with SharePoint: permissions! I get the feeling, that 90% of all errors and problems are related to permissions and security. This kinda leads me to thinking, that no two SharePoint installations are the same. When I comes down to security and permission settings all installations differ. Even if it’s just a tiny bit – this is sometimes all it needs to take a system down.

Back to my originial problem, well actually to the solution of my problem. The solution was, to add the account for application pools to the “Performance Log Users” group. So far the accounts where just a member of the “Performance Monitor Users”.

Heaven knows why and how this happened. A quick comparision with another SharePoint installation revealed, that on that machine the application pool account was just a member of the local users group. The account was not a member of any other group (WTF?).

Delete SharePoint Application Pools

Even though you deleted an application pool in IIS, sometimes SharePoint doesn’t seem to care. I recently had some trouble setting up the user profile service, and needed to delete the UPS because of some misconfiguration. When I wanted to recreate the application pool I got an error, stating the application already exists.

app_pool_1

But what when I can’t see this app-pool in IIS? Well PowerShell to the rescue:

Remove-SPServiceApplicationPool [AppPoolName]

This is almost to easy to be true.

BTW: when deleting the UPS (the service application), the application pool does not get deleted in IIS. This is extremely ugly, especially since the app-pool name is just some guid. When re-creating the service-application using the same settings as before (especially the same app pool name), this fails, because the name of the app-pool and the corresponding guid name for IIS seems to be stored in the configuration database.

Creating new sites in a batch

During SharePoint development you just need a whole bunch of sites. Creating them just for test purpose using the central administrations seems to be to much hassle. Instead I created a little batch-file to take care of spinning up a new test-site.

Basically you just have to edit the variables at the beginning of the script. Just specify the port, the site name, title and description. The name is used to create the web-application, application pool, the database and the stuff.

When creating the new site-collection for the web-application I did not provide a template; this way I can choose a template at the first call to the newly create site.

@echo off
setlocal
pushd .
    set SPLocation=%CommonProgramW6432%\Microsoft Shared\web server extensions\12
    set SPAdminTool=%SPLocation%\BIN\stsadm.exe
    set sitePort=6001
    set siteName=SampleSite
    set siteDescription=Demo a SharePoint Web-Application
    set siteTitle=Web-App Demo
echo Creating WebApplication '%siteName%' at port '%sitePort%'
"%SPAdminTool%" -o extendvs -url http://localhost:%sitePort% -owneremail me@acme.local -ownerlogin acme\me -ownername "Acme Big Boss" -databasename WSS_Content_%siteName%_%sitePort% -description "%siteDescription%" -apcreatenew -apidname "WSS_AppPool_%siteName%_%sitePort%" -apidtype NetworkService -donotcreatesite
echo Creating WebSite '%siteTitle%'
"%SPAdminTool%" -o createsite -url http://localhost:%sitePort%/ -owneremail me@acme.local -ownerlogin acme\me -ownername "Acme Big Boss" -lcid 1031 -description "%siteDescription%" -title "%siteTitle%"
popd
endlocal

SharePoint 2010 version numbers

I already created a list of version numbers for SharePoint 2007 (which seems to be a little outdated as it seems).

Well, so now I give that a new try for SharePoint 2010:

Update Name Version number
RTM (all components) 14.0.4763.1000
RTM (farm build version) 14.0.4762.1000
June 2010 CU 14.0.5114.5003
August 2010 CU 14.0.5123.5000
October 2010 CU 14.0.5128.5000
December 2010 CU 14.0.5130.5002
February 2011 CU 14.0.5136.5002
April 2011 CU 14.0.5138.5000

One Content-type, multiple templates

Let’s assume I want to store different documents in a document-library in SharePoint, based on different templates. The easiest way would be to create different content-types for each kind of document. Each content-type can have an individual template in turn.

But what if I have just one logical content-type, but I have different document templates? I could create master content-type, which holds all properties. Then I create sub content-types and assign the different templates to those. This way I can maintain the properties on the master content-type and don’t have to worry about the sub content-types.

Problem solved!

But what I actually wanted was to have dedicated links to add new documents based on a certain template to my document library. I achieved this, but I needed to created three content-types in order to do so.

A different approach.

Instead of creating different content-types with different templates, I just create two hyperlinks “create document a” and “create document b”. With a couple of lines of javascript I’m ready to go.

First of I need a document library to store my templates. In the next step I add a content editor webpart to my listview. Because I cannot add javascript code to the content editor webpart directly, I placed my code in a separate file, which I also placed in the template document library (to keep thinks simple for now). So I reference this file in the content editor webpart.

This file basically contains some javascript to add new documents based on a certain template to the library:

function NewWord()
{
    var strTemplate = makeAbsUrl("/Template/WordTemplate.docx");
    var strSaveLocation = makeAbsUrl("/Shared Documents");
    var strProgId = "SharePoint.OpenDocuments";
    createNewDocumentWithProgID(strTemplate, strSaveLocation, strProgId, false);
    return false;
}
function NewExcel()
{
    var strTemplate = makeAbsUrl("/Template/ExcelTemplate.xlsx");
    var strSaveLocation = makeAbsUrl("/Shared Documents");
    var strProgId = "SharePoint.OpenDocuments";
    createNewDocumentWithProgID(strTemplate, strSaveLocation, strProgId, false);
    return false;
}

This with some little HTML …

<span style="width: 10px; height: 10px; overflow: hidden; display: inline-block; position: relative;">
    <img style="left: 0px !important; top: -128px !important; position: absolute;" src="/_layouts/images/fgimg.png" alt=""/>
</span>&#160;<a onclick="NewWord();" href="#">New Word-Document</a>&#160;|&#160;
<span style="width: 10px; height: 10px; overflow: hidden; display: inline-block; position: relative;">
    <img style="left: 0px !important; top: -128px !important; position: absolute;" src="/_layouts/images/fgimg.png" alt=""/>
</span>&#160;<a onclick="NewExcel();" href="#">New Excel-Document</a>

… could just do.

SharePoint 2010: to RBS or not to RBS

… that’s the question.

Joel Olsen recently wrote a blog post about the pros and cons of using Remote Blob Storage (RBS) (formerly know as External Blob Storage – EBS). This post also contains a bunch of links to various resources from Microsoft and other vendors of RBS technology.

The bottom line is, that using RBS can greatly improve performance when working with large documents in SharePoint, while the actual data-size is much lower than storing those documents in the SharePoint content-database.

On the other side RBS is would be the wrong choice, when mostly small documents or listdata is stored in SharePoint, because in this case the overhead of moving the data out of SQL-server and into the filestream is too costly. Back in 2006 Microsoft already published a paper called “To BLOB or Not To BLOB: Large Object Storage in a Database or a Filesystem”, which concludes that files smaller than 256 KB would be best stored in the database, while files larger than 1 MB are most efficiently sored in the filesystem. Everything in between “depends”.