Sunday, 25 July 2010

Feature upgrade (part 3) – introducing SPFeatureUpgrade kit

In this article series:

  1. Feature upgrade (part 1) – fundamentals
  2. Feature upgrade (part 2) – a sample to play with
  3. Feature upgrade (part 3) – introducing SPFeatureUpgrade kit (this article)
  4. Feature upgrade (part 4) – advanced scenarios
  5. Feature upgrade (part 5) – using PowerShell to upgrade Features

This is the third article in my Feature upgrade series. I wanted to post this earlier but (typical developer) I got caught up in doing some more work on the tool I’m introducing here. Back in the ‘Feature upgrade fundamentals’ post, I mentioned that although we now have this great framework for versioning and upgrading Features (thus providing a great vehicle to roll out new/modified functionality to our SharePoint sites), there are no tools out-of-the-box to help manage this process. This often confuses people when they start to look at Feature upgrade – no amount of redeploying/upgrading solutions or deactivating/reactivating Features will trigger the upgrade event (because reactivation is *not* upgrade, by design!), and SharePoint 2010 does not ship with any user interface, STSADM command or PowerShell cmdlet to do this. In other words, a situation also known as a “partner opportunity”! What you do get is a series of methods in the API – although it doesn’t take too much to throw together a console app which will fill most of this gap, there are a few permutations and there is some complexity around handling failed upgrades. And anyway, in my world it’s always nice to have the option of doing things visually.

So, just like the Content Deployment Wizard plugged the gap of SharePoint’s content deployment framework not having a rich UI, my SPFeatureUpgrade kit on Codeplex might be useful if you start to version/upgrade Features in your environment. The kit installs as a WSP and all source code is published on the Codeplex site.

The following is a slightly expanded version of the Codeplex blurb – any of the images can be clicked on to enlarge.

What's in the kit

The kit is comprised of 3 things:
  • An application page in Central Admin - administrators can use this to upgrade Features of any scope across the entire farm
  • An OPTIONAL page in each site collection's Site Settings area - this can be used to devolve responsibility for upgrading Features (and therefore updating functionality provided by developers) to local site administrators. A Feature must be enabled on each site to enable this.
  • [Coming soon] - a PowerShell cmdlet which allows Feature upgrade to be run from script. (This is the final piece and will be ready shortly, since I’ve got the core logic implemented already.)

One useful thing that the application pages allow you to do is selectively upgrade Features – it could be that you don’t want all sites or webs to receive the new functionality in the upgraded Feature. These pages display checkboxes next to each Feature instance so you can control what gets upgraded where. This is also useful if you plan to ‘phase’ the rollout of new functionality deployed using Feature upgrade.

[Sidenote – Feature upgrade is typically a developer-led thing, since it’s developers who build Features. If developers do not have permissions to to use the admin pages (or PowerShell) then clearly some communication will be required with the administrators who do. Note also that, as I discussed in Upgrading sandboxed solutions, the Feature upgrade concept does not apply in the sandbox since all Features instances there are automatically upgraded when a sandboxed solution is updated.]

Usage

Central Admin page

After deploying updates to a Feature, this page can be used to find and upgrade instances of the Feature across the farm. The tool is accessed from the ‘System Settings’ area with Central Admin:

CentralAdmin_FeatureUpgradeLink

Farm administrators can then select the scope (Farm, WebApplication, Site or Web) and then find Feature instances which require upgrade (this uses a set of methods named QueryFeatures() in the SharePoint API). In the image below I've selected 'WebApplication' as the scope and clicked 'Search' to display the results – I get a table of Features in different web applications which need upgrade (i.e. an updated version has been deployed but not yet upgraded):

(click any image to see larger/clearer version)
CentralAdmin_UpgradeWebAppFeatures 
I can use the checkboxes to selectively upgrade some instances and not others (by default all will be upgraded, but this can be controlled by deselecting checkboxes). In the image below I've upgraded 1 of the 2 web application Features found previously - the success/failure result of all feature instances are shown on the page:

CentralAdmin_CompletedUpgradeWebAppFeatures

In the example above, the selected Feature has now been upgraded.

To help the experience when used in larger farms, when the Central Admin page is used to upgrade Site or Web scoped Features, additional filters appear to allow you to restrict the scope of the query. [Sidenote - this uses some gratuitous jQuery to slide the filter controls in – I can practically hear a couple of server admins (or Spence :)) complaining about things sliding around, but hey I’ve got to have somewhere to practice!]. So for upgrading Site-scoped Features, a selector appears allowing to select the parent web application:

CentralAdmin_UpgradeSiteFeatures

Similarly for Web-scoped Features, you filter on parent site collection:

CentralAdmin_UpgradeWebFeaturesFiltering

Usage

Site Settings page
The Site Settings page works in a very similar way, except only Site and Web-scoped Features can be upgraded (in the current site collection). The ‘COB.SharePoint.Utilities.SiteSettingFeatureUpgrade’ Feature must be activated against each site collection which should show a link to this page. When enabled, the tool is accessed from the Site Settings area for the site collection:

SiteSettings_FeatureUpgradeLink

Site collection administrators can then select the scope (e.g. Site or Web) and then find the Features which require upgrade. In the image below I've selected 'Web' as the scope and clicked 'Search' to display the results:

CentralAdmin_UpgradeWebFeatures

As before, I can use the checkboxes to selectively upgrade some instances and not others (by default all will be upgraded, but this can be controlled by deselecting checkboxes). In the image below I've upgraded 2 of the 4 web Features found previously - the success/failure result of all feature instances are shown on the page:

FeatureUpgradeResult

Summary

SharePoint 2010 introduces the ability to version and upgrade Features, but doesn’t provide any high-level tools to manage this process. I’m providing tools for farm administrators and (optionally) site collection administrators to do this. At the time of writing this article, a final piece in the form of a PowerShell cmdlet is still in progress but should be available soon.

The kit can be downloaded from http://spfeatureupgrade.codeplex.com/

8 comments:

Luca said...

That's a great feature! I've just used it and works like a charm.

But how could I manage frequently and partially upgrading during my development ? I mean, I need to upgrade from 1.0.0.0 to 1.0.0.1 but during the development I will need to do partial upgrading that will lead to the final 1.0.0.1 set of deployable features.

Could I rollback an upgrade ?

Chris O'Brien said...

@Luca,

Thanks, glad you like the tool.

That's a great question - you do indeed need to test *multiple* Feature upgrade iterations as you develop your Feature upgrade XML/code. You cannot specifically "rollback" an upgrade as such, but by reverting back the version number to the real one you want to use (e.g. 1.0.0.1) and *reinstalling* the Feature (i.e. by retracting/redeploying the WSP rather than upgrading), the end result is that the Feature is installed at that version with the current Feature contents. You can then use this as the version of your Feature to take forward to other environments. In other words, SharePoint does not maintain historic versions of a Feature's state.

Does that make sense?

Thanks,

Chris.

Luca said...

yes, that make sense.

Thanks a lot,
Luca

Sam Venables said...

Top work, Chris. Such a useful tool - clean UI, easy to use, and so critical for those of us using SP as a development platform that I can't believe Microsoft didn't bother writing something like this for Central Admin themselves!

Chris O'Brien said...

Thanks Sam :)

Jörg Spilker said...

Does anyone has an idea why this happens on the Web scope?

Farm/WebApp/SiteCollection Scope is working well, but the WebScope gives this error for all Site Collections I've tried.

Unable to access web scoped feature (Id: 00bfea71-d1ce-42de-9c63-a44004ce0104) because it references a non-existent or broken web (Id: 581e2333-fc2d-43e3-8cb0-96a3db718145) on site 'http://lenzeweb-test.lenze.com/app/akb'. Exception: System.Threading.ThreadAbortException: Thread was being aborted.
at System.Threading.Thread.AbortInternal()
at System.Threading.Thread.Abort(Object stateInfo)
at System.Web.HttpResponse.End()
at Microsoft.SharePoint.Utilities.SPUtility.Redirect(String url, SPRedirectFlags flags, HttpContext context, String queryString)
at Microsoft.SharePoint.Utilities.SPUtility.RedirectToAccessDeniedPage(HttpContext context)
at Microsoft.SharePoint.Utilities.SPUtility.HandleAccessDenied(HttpContext context)
at Microsoft.SharePoint.Utilities.SPUtility.HandleAccessDenied(Exception ex)
at Microsoft.SharePoint.Library.SPRequest.GetAllWebsOfSite(String bstrUrl, Object& pvarWebs, Object& pvarWebIds, Object& pvarParentWebs, Object& pvarLangs, Object& pvarTitles, Object& pvarUIVersions, Object& pvarFlags, Object& pvarWebTemplates, Object& pvarConfigurations, Object& pvarMasterUrls, Object& pvarCustomMasterUrls)
at Microsoft.SharePoint.SPSite.SPWebCollectionProvider.GetWebsData(String[]& strNames, String[]& strServiceRelUrls, Guid[]& guidWebIds, Int32[]& nLanguages, String[]& strTitles, String[]& strDescriptions, String[]& strCreationTimes, String[]& strModifiedTimes, Boolean[]& bUserIsWebAdmins, Int32[]& nWebTemplates, Int16[]& nProvisionConfigs, Int16[]& nMeetingCounts, Int32[]& nUIVersions, Int32[]& nFlags, String[]& strMasterUrls, String[]& strCustomMasterUrls)
at Microsoft.SharePoint.SPWebCollection.EnsureWebsData()
at Microsoft.SharePoint.SPWebCollection.get_Item(Guid id)
at Microsoft.SharePoint.SPFeatureEnumeratorBase.GetCachedWeb(SPSite site, Guid webId, Guid featureId)

Antonsen said...

"[Coming soon] - a PowerShell cmdlet which allows Feature upgrade to be run from script. (This is the final piece and will be ready shortly, since I’ve got the core logic implemented already.)"

... comming soon? ;-)

Chris O'Brien said...

@Antonsen,

This was published in the 5th article in this series - http://www.sharepointnutsandbolts.com/2010/08/feature-upgrade-part-5-using-powershell.html

Cheers!

Chris.