I’ve done a couple of blogs now about some of the multi-tenant features in SharePoint 2010 (http://blogs.technet.com/speschka/archive/2009/11/30/enabling-multi-tenant-support-in-sharepoint-2010.aspx and http://blogs.technet.com/speschka/archive/2009/12/30/multi-tenancy-in-sharepoint-2010-part-2.aspx). In this post I’m going to talk about something called feature packs (A.K.A. feature sets in previous builds and blogs). A feature pack is a way to take a set of site- and/or web-scoped features and group them together. Once grouped together in that pack, they can be associated with a subscription. At that point, all the site collections in that subscription can use only the site- and web-scoped features that are part of that pack. As you can imagine, it gives you the opportunity to do things like create different service levels and charge higher rates for more features, lock down features for different subscriptions, etc.
So let’s get started – how do you create a feature pack? You can use the PowerShell cmdlet New-SPSiteSubscriptionFeaturePack. To back up a little though, as described in part 2 of the multi tenant blog series, we’re going to get a reference to a site subscription. So I’ll start with that – here I’m getting a reference to one of my subscriptions:
$sub = Get-SPSiteSubscription -identity 7bc0cb76-a355-485d-ac7e-8332d40147f2
Now I’m going to create a new feature pack:
$pack = New-SPSiteSubscriptionFeaturePack
Pretty easy, right? Just like site subscriptions, feature packs are devoid of frilly goo, like say a name. J So now if I just type $pack in PowerShell and hit Enter it will give me all the info it has about it:
Creating the feature pack using the object model is similarly straightforward:
SPSiteSubscriptionSettingsManager mgr = SPSiteSubscriptionSettingsManager.Local;
SPSiteSubscriptionFeaturePack fs = mgr.CreateFeaturePack();
Note that you must call the Update method or your feature pack will not be persisted. Now that we have a feature pack we want to start adding features to it. To add new features to a pack you can use the Add-SPSiteSubscriptionFeaturePackMember PowerShell cmdlet. To do that we’ll need to pass in two variables: the ID of our feature pack and the ID of a feature. While I don’t want to stray too far from our objective here, remember that you can only add a site- or web-scoped feature to a subscription; it will automatically use farm- and web application-scoped features. Using PowerShell we have three options to get a list of the features that might work for a feature pack then:
get-spfeature –site http://urlToSite (returns all the enabled features on the site – both full trusted and partially trusted code)
get-spfeature –site http://urlToSite –sandboxed (returns all installed partially trusted code feature definitions on the site)
get-spfeature –web http://urlToWeb (returns all the enabled features in the web)
So pick your poison and get the ID to a feature that you want to add to the feature pack. In this example I’m going to add the Search Web Parts feature to my feature pack. So my PowerShell command looks like this:
Add-SPSiteSubscriptionFeaturePackMember -identity $pack -FeatureDefinition eaf6a128-0482-4f71-9a2f-b1c650680e77
There you go – feature added. Now if I type in $pack in PowerShell and press Enter it looks like this (only without the word wrap):
The object model follows a similar pattern – here is that code:
//get the site subscriptions manager
SPSiteSubscriptionSettingsManager mgr =
//get all the feature packs
SPSiteSubscriptionFeaturePackCollection fSec = mgr.GetAllFeaturePacks();
//retrieve the pack we want to work with
SPSiteSubscriptionFeaturePack fs = fSec[new Guid(yourFeaturePackGUID)];
//define a new feature definition
SPFeatureDefinition fd = null;
//get the collection of feature definitions
SPFeatureDefinitionCollection fDefs = SPFarm.Local.FeatureDefinitions;
//get the feature definition we want to add to the feature pack
fd = fDefs[new Guid(yourFeatureGUID)];
//add to the feature pack
Okay, we’re making good progress now. We’ve created a feature pack. We know how to add features to it. Because I am occasionally sadistically anal I will briefly cover how to remove a feature from a feature pack. In PowerShell use the Remove-SPSiteSubscriptionFeaturePackMember cmdlet. Like the cmdlet to add a feature to a pack, you must again provide as parameters the feature pack and feature ID that should be removed from it. If you’re using the object model you would just use the Remove method on the SPSiteSubscriptionFeaturePack instance and then call the Update method.
The last step of course is now to associate our feature pack with a site subscription. Going back to the beginning of this post, I used the $sub variable to get a reference to my subscription. Now I going to use that to make that association between subscription and feature pack. In PowerShell I need to get a reference to the local subscription settings manager, then associate my feature pack with my subscription. Here’s what that looks like:
$mgr = [Microsoft.SharePoint.SPSiteSubscriptionSettingsManager]::Local
The object model basically uses the same exact code as PowerShell; you can use the code shown previously in this blog to get your reference to the site subscription and feature pack. Then you just get an instance of Microsoft.SharePoint.SPSiteSubscriptionSettingsManager.Local and call the AssignFeaturePackToSiteSubscription method.
For completeness, if you want to disassociate a feature pack with a subscription, you would assign $Null as the feature pack reference in the AssignFeaturePackToSiteSubscription method. Also, if you wanted to delete a feature pack you would use the Remove-SPSiteSubscriptionFeaturePack cmdlet; in the object model you get a reference to the SPSiteSubscriptionFeaturePack instance and call the Delete method.
This the last of the features and configuration that I’ll probably cover for multitenant. I have an idea of another related topic to this, but you’ll just have to stay tuned to see if I can pull that together. Hope everyone is enjoying their new year.