Multi Tenancy in SharePoint 2010 Part 3

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:

FeatureDefinitions

Id

——————

{}

b329f3b0-58ec-408b-86c9-bd13661acd45

 

Creating the feature pack using the object model is similarly straightforward:

SPSiteSubscriptionSettingsManager mgr = SPSiteSubscriptionSettingsManager.Local;

SPSiteSubscriptionFeaturePack fs = mgr.CreateFeaturePack();

fs.Update();    

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):

FeatureDefinitions

Id

——————

{FeatureDefinition/eaf6a128-0482-4f71-9a2f-b1c65068…

b329f3b0-58ec-408b-86c9-bd13661acd45

 

The object model follows a similar pattern – here is that code:

//get the site subscriptions manager

SPSiteSubscriptionSettingsManager mgr =

SPSiteSubscriptionSettingsManager.Local;

 

//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

fs.Add(fd);

 

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

$mgr.AssignFeaturePackToSiteSubscription($pack, $sub)

 

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.

Advertisements

Multi Tenancy in SharePoint 2010 Part 2

In this posting I wanted to come back to the topic of multi tenancy.  In a previous post (http://blogs.technet.com/speschka/archive/2009/11/30/enabling-multi-tenant-support-in-sharepoint-2010.aspx) I described some of the basic features of multi tenancy and a) how to create the basic service application infrastructure needed to support multi tenancy and b) how to create a “multi tenant aware” service application instance.  I didn’t really go into how to create a new subscription, a multi tenant admin site, or add sites to a subscription.  I’ll cover that in this post, and then in part 3 of multi tenancy (at a later date) I’ll cover the concepts of feature packs – how you create and manage them.

 

To begin with, let’s cover how one creates a new subscription; the ID associated with a subscription is how we associate all the sites, data and features together.  In PowerShell you can create a new subscription like this: 

 

$sub = New-SPSiteSubscription

 

The “$sub” is not really necessary, but it’s useful because then you can use it in other PowerShell commands to continue working with the subscription.  All you’ve got at this point is a subscription and a GUID to identify it – there aren’t any sites associated with the subscription.  If you want to create a new site and associated it with the subscription, you can do so like this:

 

New-SPSite –Url http://yourNewSite  -OwnerAlias myDomain\myUser  -OwnerEmail myemail@mydomain.com  -Template STS#0  -SiteSubscription $sub

 

So in this example I’ve just reused the $sub variable from the previous command, created a new site, and it is then associated with that subscription.  Using the object model, I can do it like this:

 

//get the site to make sure it’s valid

SPSite newSite = new SPSite(“http://yourNewSite”);

 

//create a new subscription

SPSiteSubscription sub = SPSiteSubscription.Create();

 

//add the site to the subscription

sub.Add(newSite);

 

So now I’ve got a subscription and I’ve got a site that is part of that subscription.  I probably also want to create the administration site for that subscription.  In beta 2 it is a two step process; by RTM it will hopefully be one.  The first step is to create a new site and configure it to use the tenant admin site template:

 

$admin = New-SPSite –Url http://yourAdminSite  -OwnerAlias myDomain\myUser  -OwnerEmail myemail@mydomain.com  -Template tenantadmin#0  -SiteSubscription $sub

 

Now that you have the admin site created, you need to set the AdministrationSiteType property, using the SPAdministrationSiteType enum.  In PowerShell it would look like this:

$admin.AdministrationSiteType = [Microsoft.SharePoint.SPAdministrationSiteType]::TenantAdministration

 

When the command completes it echos back the new AdministrationSiteType value for the site.  By RTM we’re hoping that the New-SPSite cmdlet will include a parameter called –AdministrationType and you would just pass in the value of TenantAdministration.

 

If you were doing this via the object model, the code would be very similar to what I showed above.  The only differences would be a) you would want to make sure you use the tenantadmin#0 site template for the new site and b) after the site is created you need to set the AdministrationSiteType property to SPAdministrationSiteType.TenantAdministration.

 

Finally, to add an existing site you need to get the site, then add it to the subscription.  Here is an example:

 

$newSite = Get-SPSite –identity http://urlToYourSite

$sub.Add($newSite)

 

That’s all there is too it.  Using the object model is very similar, as you would hope.  You just need to get a reference to an SPSite object, then a reference to an SPSiteSubscription, then Add the site.  Here is an example (NOTE: yes, I am not showing the Dispose and all that stuff but please use best practices in your code):

 

//get the site to make sure it’s valid

SPSite newSite = new SPSite(“http://urlToYourSite”);

 

//get the subscription

SPSiteSubscription sub = theFarm.SiteSubscriptions[new Guid(yourGuidHere)];

 

//add the site to the subscription

sub.Add(newSite);

 

You should be well on your way now to getting your multi tenancy features up and running.  Next time we’ll look at feature packs.

Enabling Multi Tenant Support in SharePoint 2010

SharePoint 2010 adds some new features to support hosting environments, which we generally refer to as multi tenant support.  In the beta release, the core multitenant infrastructure is not turned on by default.  It requires a custom service application to be provisioned, and once that’s done you can begin configuring the different pieces of multi tenancy.  Here’s just a brief rundown on what those features are:

  1. Multi tenant admin sites:  these sites give you a central location where all of the sites for a particular tenant can be managed.  It includes things like managing certain aspects of service applications (like user profiles, managed metadata store, etc.).  It also allows you to view all of the site collections in the tenancy, create new site collections, manage the owners of those site collections, etc.
  2. Multi tenant member sites:  tenancy in SharePoint 2010 is managed through something we call a subscription.  Simply stated, a subscription is just a GUID that we can use to identifiy members of a subscription as well as data associated with a subscriber.  The membership identity is how we can determine which site collections are part of which tenancy.  From a data perspective, we can use that subscriber key when data is stored in a service application.  For example, so tenant A can have a set of administrators and data in the managed metadata service application, and tenant B can have an entirely different set of admins and data.  From a farm perspective in this scenario, you are only using one instance of the managed metadata service application, but it is being shared by all tenants.  However their data is isolated and secured from one another by virtue of their subscriber ID.
  3. Feature Packs:  feature packs are ways in which SharePoint features, the same regular features you know and love, can be organized into groups (NOTE:  “feature packs” is what this has been called, it may be called something else by the time the product ships).  Once you organize these features into feature packs, you can associate them with a subscriber.  Once that’s been done, that subscriber can only use those features that have been added to the feature pack.  That gives you control over which tenants are using which features, as well as giving you a means by which you can create different packaged offerings at different prices for hosting customers.

That’s the really brief overview of what it does – I’m sure the SharePoint user assistance folks (the people that write all that content for TechNet) will have a lot more detail on this in the months ahead.  In the meantime, if you want to get the basic infrastructure in place you can get started by running this PowerShell script:

Get-SPServiceInstance | where{$_.GetType().Name -eq “SPSubscriptionSettingsServiceInstance”} | Start-SPServiceInstance

$acc = Get-SPManagedAccount  “Specific Account Name”   ( OR create a new managed account)

$appPool = New-SPIisWebServiceApplicationPool -Name SettingsServiceAppPool -Account $acc
$app = New-SPSubscriptionSettingsServiceApplication –ApplicationPool $appPool –Name SettingsServiceApp –DatabaseName SettingsServiceDB
$proxy = New-SPSubscriptionSettingsServiceApplicationProxy –ServiceApplication $app

Once you have that in place, you can create new subscriptions, add existing site collections to subscriptions, create tenant admin sites, create feature packs, associate feature packs with subscribers, etc. I actually have a simple winforms app that does all of this now; I will try and write a future post that describes how to do some of these things in PowerShell, and post my admin app as well to help get you started.  One quick note I will make here, if you are exploring on your own and want to create a tenant admin site, you need to make sure you include the “-AdministrationType TenantAdministration” flag when using the new-spsite cmdlet. 

To take advantage of these features in a service application, you need to use the -PartitionMode flag when creating the service application.  Here’s an example of a PowerShell script to create a new instance of the managed metadata service in multi tenant mode:

$pool = Get-SPIisWebServiceApplicationPool -Identity ‘SharePoint Web Services Default’
$meta = New-SPMetadataServiceApplication -HubUri
http://hosting -ApplicationPool $pool -Name ‘Tenant Managed Metadata’ -DatabaseName O14_TenantMetadataDB -DatabaseServer SP14B -PartitionMode -SyndicationErrorReportEnabled
$proxy = New-SPMetadataServiceApplicationProxy -PartitionMode -ContentTypePushdownEnabled -DefaultKeywordTaxonomy -DefaultSiteCollectionTaxonomy -Name ‘Tenant Managed Metadata Proxy’ -DefaultProxyGroup -ServiceApplication $meta

Hopefully that’s enough to get you curious and started for now.  I’ll follow up with additional scripts and the tenant admin app later.