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.
Appreciate that this is now an old post, but I have an interesting question. If I have a new 3rd party feature that I want to include, only for Site Collection Owners that have paid for the 3rd party feature - how do I ensure that the feature is only exposed to those customers? If I add the feature to an existing feature pack, then all customers with that feature pack will have access to the feature. If I create a new feature pack for the new feature, then once I have several 3rd party features available, I need a new feature pack for every combination of 3rd party features that a customer may possibly want to use - which is clearly unmanageable.
Any advise would be greatly appreciated.
Great post Thank you for the explanation, this is awesome feature in SharePoint.
Multi tenancy helped to centrally publish a feature / or collection of features to tenent.
That implies both feature publishing and content type publishing(hub) are avilable in sharepoint.
SharePoint 2010 rocks!
thanks for the post. I need some info...
If a subscription is not assigned any feature pack...does it then have access to all the features or none?
I want to have a subscription which will have default access to any new features added without me updating the feature pack, everytime a new feature is available.
If we want to use ADFS provider with a multitenant Sharepoint web application, how or what can we do to only show the correct ADFS provider for a particular tenant?