Wednesday, May 21, 2014

PowerShell to remove "MissingFeature"

"MissingFeature" error message in Health Analyzer Report is annoying, although it doesn't hurt in most of cases.

Thanks for the post from Phil Childs, which reminded me the possibility to detect the problem.

Below is the PowerShell script I used to remove the "MissingFeature".


Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction "SilentlyContinue" 
cls

function RemoveInvalidSPSiteFeatures([switch]$ReportOnly)
{
    $dictValidFeatures = @{}
    $dictInvalidFeatures = @{}

    $sites = Get-SPWebApplication -IncludeCentralAdministration | Get-SPSite -Limit ALL | ?{$_.ServerRelativeUrl -notmatch "Office_Viewing_Service_Cache"}
    foreach($site in $sites) 
    { 
        #Write-Host "site.Url=" $site.Url
        $dictValidFeatures.Clear()
        $dictInvalidFeatures.Clear()

        $AllFeaturesCount = $site.Features.Count
        #Write-Host "site.Features.Count=" $AllFeaturesCount
        
        Get-SPFeature -Site $site.Url -Limit All | %{
            $dictValidFeatures.Add($_.Id.ToString(), $_)
        }
        $ValidFeaturesCount = $dictValidFeatures.Count
        #Write-Host "dictValidFeatures.Count" $ValidFeaturesCount
        
        if ($AllFeaturesCount -ne $ValidFeaturesCount)
        {
            $site.Features | %{
                $FeatureId = $_.DefinitionId.ToString()
                if ($dictValidFeatures.ContainsKey($FeatureId) -eq $false)
                {
                    $_ | fl *
                    $_.Properties | ft *
                    $dictInvalidFeatures.Add($FeatureId, $site.Url)
                }
            }
        }
        
        foreach($featureItem in $dictInvalidFeatures.GetEnumerator())
        {
            if ($ReportOnly)
            {
                write-host "Invalid Feature " $featureItem.Name " found in site collection:" $featureItem.Value -foregroundcolor yellow
            }
            else
            {
                write-host "Invalid Feature " $featureItem.Name " in site collection:" $featureItem.Value " is removed." -foregroundcolor Red
                $site.Features.Remove($featureItem.Name, $true)
            }
        }
    }
    
    $dictValidFeatures.Clear()
    $dictInvalidFeatures.Clear()
}

function RemoveInvalidSPWebFeatures([switch]$ReportOnly)
{
    $dictValidFeatures = @{}
    $dictInvalidFeatures = @{}

    $sites = Get-SPWebApplication -IncludeCentralAdministration | Get-SPSite -Limit ALL | ?{$_.ServerRelativeUrl -notmatch "Office_Viewing_Service_Cache"}
    foreach($site in $sites) 
    {
foreach($web in $site.AllWebs) 
{
#Write-Host "web.Url=" $web.Url
$dictValidFeatures.Clear()
$dictInvalidFeatures.Clear()

$AllFeaturesCount = $web.Features.Count
#Write-Host "web.Features.Count=" $AllFeaturesCount

Get-SPFeature -Web $web.Url -Limit All | %{
$dictValidFeatures.Add($_.Id.ToString(), $_)
}
$ValidFeaturesCount = $dictValidFeatures.Count
#Write-Host "dictValidFeatures.Count" $ValidFeaturesCount

if ($AllFeaturesCount -ne $ValidFeaturesCount)
{
$web.Features | %{
$FeatureId = $_.DefinitionId.ToString()
if ($dictValidFeatures.ContainsKey($FeatureId) -eq $false)
{
$_ | fl *
$_.Properties | ft *
$dictInvalidFeatures.Add($FeatureId, $web.Url)
}
}
}

foreach($featureItem in $dictInvalidFeatures.GetEnumerator())
{
if ($ReportOnly)
{
write-host "Invalid Feature " $featureItem.Name " found in site:" $featureItem.Value -foregroundcolor yellow
}
else
{
write-host "Invalid Feature " $featureItem.Name " in site:" $featureItem.Value " is removed." -foregroundcolor Red
$web.Features.Remove($featureItem.Name, $true)
}
}
}
    }
    
    $dictValidFeatures.Clear()
    $dictInvalidFeatures.Clear()
}

Start-SPAssignment -Global

#RemoveInvalidSPSiteFeatures –ReportOnly
#RemoveInvalidSPSiteFeatures

RemoveInvalidSPWebFeatures –ReportOnly
#RemoveInvalidSPSiteFeatures

Stop-SPAssignment -Global

Write-Host "" 
Write-Host "Finished! Press enter key to exit." -ForegroundColor Green 
Read-Host 


No comments:

Post a Comment