14 Aug 2012

Removing features from a content database in SharePoint 2010 using PowerShell

The great thing about the Health Analyzer in SharePoint 2010 is that it will report on a number of potential issues with the server farm, which may cause a problem later whilst applying a cumulative update or service pack. Resolving these issues in advance will help to prevent an update failing when you run the SharePoint Configuration Wizard.
One of these problems may occur when a solution is removed from the farm before the corresponding features were deactivated from site collections and sites. The Health Analyzer will place this issue in the “Configuration” category with the title “Missing server side dependencies”.
Missing server side dependencies
The error message reported will look similar to this one:
[MissingFeature] Database [SharePoint_Content_Portal] has reference(s) to a missing feature: Id = [8096285f-1463-42c7-82b7-f745e5bacf29], Name = [My Feature], Description = [], Install Location = [Test-MyFeature]. The feature with Id 8096285f-1463-42c7-82b7-f745e5bacf29 is referenced in the database [SharePoint_Content_Portal], but is not installed on the current farm. The missing feature may cause upgrade to fail. Please install any solution which contains the feature and restart upgrade if necessary.
As shown above, this message reports a content database name (SharePoint_Content_Portal) and feature ID (8096285f-1463-42c7-82b7-f745e5bacf29), but not the sites or site collections where the feature exists. In addition to this, even if you did know where the feature was activated, it will not appear anywhere in the UI for you to deactivate because the solution has been removed from the farm.
The following PowerShell script will interrogate a specified content database and feature ID and do two things:
  1. Produce a report in the PowerShell console showing which sites or site collections contain the offending feature.
  2. Forcibly deactivate the feature from the applicable sites or site collections.
Note: Whilst this article applies specifically to the scenario of deactivating features from removed solutions reported by the Health Analyzer, I have decided to write the script so that it deactivates any specified feature from sites and site collections – not just those missing from the farm. This allows the script to be used in other scenarios, too.
To use the script, run these functions in a PowerShell console with the SharePoint 2010 add-ons loaded:
function Remove-SPFeatureFromContentDB($ContentDb, $FeatureId, [switch]$ReportOnly)
{
    $db = Get-SPDatabase | where { $_.Name -eq $ContentDb }
    [bool]$report = $false
    if ($ReportOnly) { $report = $true }
   
    $db.Sites | ForEach-Object {
       
        Remove-SPFeature -obj $_ -objName "site collection" -featId $FeatureId -report $report
               
        $_ | Get-SPWeb -Limit all | ForEach-Object {
           
            Remove-SPFeature -obj $_ -objName "site" -featId $FeatureId -report $report
        }
    }
}
function Remove-SPFeature($obj, $objName, $featId, [bool]$report)
{
    $feature = $obj.Features[$featId]
   
    if ($feature -ne $null) {
        if ($report) {
            write-host "Feature found in" $objName ":" $obj.Url -foregroundcolor Red
        }
        else
        {
            try {
                $obj.Features.Remove($feature.DefinitionId, $true)
                write-host "Feature successfully removed from" $objName ":" $obj.Url -foregroundcolor Red
            }
            catch {
                write-host "There has been an error trying to remove the feature:" $_
            }
        }
    }
    else {
        #write-host "Feature ID specified does not exist in" $objName ":" $obj.Url
    }
}
You now have two options for using these functions. If you just want to produce a report in the console showing which sites and site collections contain the feature, type the following (note the ReportOnly switch on the end):
Remove-SPFeatureFromContentDB -ContentDB "SharePoint_Content_Portal" -FeatureId "8096285f-1463-42c7-82b7-f745e5bacf29" –ReportOnly
This command will step through all sites and site collections and display the following message whenever it finds the feature specified:
Feature found in site : http://portal/site
If you want to go ahead and remove the feature from all sites and site collections in the content database, type the same command without the ReportOnly switch on the end:
Remove-SPFeatureFromContentDB -ContentDB "SharePoint_Content_Portal" -FeatureId "8096285f-1463-42c7-82b7-f745e5bacf29"
Running this command will step through all sites and site collections, remove the feature specified, and display the following output:
Feature successfully removed from site : http://portal/site
You should now be able to reanalyse the “Missing server side dependencies” issue in the Health Analyzer to clear the problem (providing there are no other issues reported under that title, of course!).
http://get-spscripts.com/2011/06/removing-features-from-content-database.html.

Total Pageviews