SharePoint 2007: How to Remove Orphaned Features Using PowerShell
I recently had to use content deployment on some old MOSS 2007 systems. These systems are alive for a long time and a lot of solutions/features have been deployed to them.
If features are not deactived before removal they stay as an orphan in the system (contentdb) and can cause issues lateron. I had to cleanup orphaned features before the content deployment worked properly.
The procedure for identyfing and removing orphaned features is quite straightforward:
- Go through every site collection and site recursively
- For each SPWebApp, SPSite and SPWeb
- Iterate through the *.Features collection
- For each feature, if the definition is null the script removes it from the feature collection
[system.reflection.assembly]::LoadWithPartialName("Microsoft.SharePoint")
function ListFeaturesAux($header, $features, $obj, $boolremove)
{
foreach ($feature in $features)
{
if( $feature.Definition -eq $NULL)
{
write-host "Missing feature definition (feature id:" $feature.DefinitionId "), Scope: " $header
if( $boolremove -eq $TRUE)
{
try
{
$obj.Features.Remove($feature.DefinitionId,$true)
write-host "Feature " $feature.DefinitionId " has been removed."
}
catch
{
write-host "An error occured while removing feature:" $feature.DefinitionId
}
}
}
}
}
function ListFeaturesWeb($web, $boolremove)
{
$header = "Web: " + $web.Url
ListFeaturesAux $header $web.Features $web $boolremove
foreach( $subweb in $web.Webs)
{
ListFeaturesWeb $subweb $boolremove
}
}
function ListFeaturesSite($site, $boolremove)
{
$header = "Site collection: " + $site.Url
ListFeaturesAux $header $site.Features $site $boolremove
}
function list-orphaned-Features ($url,$boolremove)
{
$webapp = [Microsoft.SharePoint.Administration.SPWebApplication]::Lookup($url)
write-host $webapp.displayname
foreach($Site in $webapp.Sites )
{
ListFeaturesSite $Site $boolremove
ListFeaturesWeb $Site.RootWeb $boolremove
}
}
#change parameter boolremove from $false to $true to remove the feature
list-orphaned-Features "http://sp2007" $false