MissingAssembly Error in Health Analyzer


One of the most common issues in the Health Analyzer when you deploy custom solutions in your SharePoint 2010 environment, is this one:

 

Assembly [My.Assembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cfc9a4dcd383ae1e] is referenced in the database [WSS_Content], but is not installed on the current farm. Please install any feature/solution which contains this assembly.

 

Most of the times this issue is regarding some bad Event Receivers that you forgot to remove before you delete the custom solution, or another problem related with the feature deactivation and solution retraction.

 

In this post I want to share with you a Power Shell script that can help you to remove this kind of bad Event Receivers.

 

The following script contains 2 functions:

 

Delete-MissingAssembly: This is the main function that goes through every possible container in the specific database that can host an Event Receiver, it means Site, Web or List.

 

Remove-EventReceiver: This function check if the event receiver container has any event receiver with the specific assembly name, shows his information and try to delete it.

 

Also the 2 functions has a parameter to allow directly delete the event receiver or only shows in the screen the information regarding the ER.

 

 

function Delete-MissingAssembly($ContentDb, $Assembly, [switch]$ReportOnly)

{

       [bool]$report = $false

       if ($ReportOnly) { $report = $true }

       $database = Get-SPContentDatabase | ?{$_.Name -eq $ContentDb}

    foreach($site in $database.Sites)

    {

        Remove-EventReceiver -ERContainer $site -Assembly $Assembly -ReportOnly $report

        foreach($web in $site.AllWebs)

        {

            Remove-EventReceiver -ERContainer $web -Assembly $Assembly -ReportOnly $report

            foreach($list in $web.Lists)

            {

                Remove-EventReceiver -ERContainer $list -Assembly $Assembly -ReportOnly $report

            }

        }

    }

}

 

function Remove-EventReceiver($ERContainer, $Assembly, $ReportOnly)

{

    foreach($er in $ERContainer.EventReceivers)

       {

             if($er.Assembly -eq $Assembly)

             {

                    Write-Host "Event Receiver with Id[" $er.Id "], Name[" $er.Name "] and Type [" $er.Type "] found in [" $ERContainer.Url $ERContainer.DefaultViewUrl "]."

                    if($ReportOnly -eq $false)

                    {

                Write-Host "Try to delete the receiver:"   

                $er.Delete()

                Write-Host "ER deleted."

                    }

             }

       }

}

 

 

After you save this script in a PS1 file and import it (Example: Import-Module .\MissingEV.PS1), you can use the function in the following way:

 

Delete-MissingAssembly -ContentDb WSS_Content -Assembly "My.Assembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cfc9a4dcd383ae1e" -ReportOnly

 

And the output could be:

 

 

As you can see the output of the Power Shell shows the Id, Name, Type and location of the specific event Receiver, you can decide if remove it with this script or access through PS or a 3rd tool to remove it.

 

Hope this helped you in the typically Missing server side dependencies issue in the Health Analyzer.

Comments (4)

  1. Anonymous says:

    Hi Julian,

    Great post and this really helped in resolving one of my customer's issue.

    One thing I noted while executing the script was that I got an error in the foreach loop in the Remote-EventReceiver function. Error details:-

    "An error occurred while enumerating through a collection: Collection was modified; enumeration operation may not execute.."

    This looks like an issue with the deletion of an event receiver element within the foreach loop and once I changed the foreach to a for loop, the script execute successfully.

    Once again thanks for this useful script. 🙂

  2. doctors says:

    Great information on MissingAssembly Error in Health Analyzer–the most common issues in the Health Analyzer when you deploy custom solutions in your SharePoint 2010 environment,

    Regards ,

    doctors

    <a href="immediatecarenaperville.com/urgent-care">Urgent care Naperville</a>

  3. Karl Vernet says:

    Hi Julian,

    Thank you for this great article, it saved me hours.
    ReportOnly switch worked fine to get the list of EventReceivers.
    But when trying to delete them, after the first delete I had a “Collection was modified; enumeration operation may not execute.” Exception. And it is quite normal because the collection is modified.
    I had to addapt your script by using “for” instead of “foreach”, and it worked fine !
    Here is the modification, the “foreach” are commented out.

    Add-PSSnapin microsoft.sharepoint.powershell

    function Delete-MissingAssembly($ContentDb, $Assembly, [switch]$ReportOnly)
    {
    [bool]$report = $false
    if($ReportOnly){$report=$true}
    $database = Get-SPContentDatabase | ?{$_.Name -eq $ContentDb}
    #foreach($site in $database.Sites)
    for($s = 0; $s -lt $database.Sites.Count; $s++)
    {
    $site = $database.Sites[$s]
    Remove-EventReceiver -ERContainer $site -Assembly $Assembly -ReportOnly $report
    #foreach($web in $site.AllWebs)
    for($w = 0; $w -lt $site.AllWebs.Count; $w++)
    {
    $web = $site.AllWebs[$w]
    Remove-EventReceiver -ERContainer $web -Assembly $Assembly -ReportOnly $report
    #foreach($list in $web.Lists)
    for($l = 0; $l -lt $web.Lists.Count; $l++)
    {
    Remove-EventReceiver -ERContainer $web.Lists[$l] -Assembly $Assembly -ReportOnly $report
    }
    }
    }
    }

    function Remove-EventReceiver($ERContainer, $Assembly, $ReportOnly)
    {
    #foreach($er in $ERContainer.EventReceivers)
    for($i = 0; $i -lt $ERContainer.EventReceivers.Count; $i++)
    {
    $er = $ERContainer.EventReceivers[$i]
    if($er.Assembly -eq $Assembly)
    {
    Write-Host “Event Receiver with Id[” $er.Id “], Name[” $er.Name “] and Type [” $er.Type “] found in [” $ERContainer.Url $ERContainer.DefaultViewUrl “].”
    if($ReportOnly -eq $false)
    {
    Write-Host “Try to delete the receiver:”
    $er.Delete()
    Write-Host “ER deleted.”
    }
    }
    }
    }

    Thanks a lot !

  4. PANoone says:

    Couldn’t get deletion to work with either ForEach or For. So I used the pipeline to grab the ID for each matching assembly and then deleted them by ID.

    $evenReceiverIds = $ERContainer.EventReceivers | ? { $_.Assembly -like $Assembly } | % { $_.ID }

    $evenReceiverIds | % {
    $er = $ERContainer.EventReceivers[$_]
    Write-Host Deleting $er.Assembly, $er.Class, $er.Type
    if($ReportOnly -eq $false)
    {
    $er.Delete()
    Write-Host " –[DELETED]"
    }
    }

Skip to main content