While looking through the event logs at a client of mine the other day I came across an odd error that was occurring regularly. Apparently they had developed a Feature which contained an Event Receiver which was programmatically bound to a series of lists. As time went on their requirements changed so they deleted the event receiver class. Problem was that the binding to the lists still exists so every time an item was updated an error would be dumped to the event log about a missing type in the specified assembly.

Fortunately it’s pretty easy to fix this using some simple PowerShell:

 1$site = Get-SPSite -url "http://portal"
 2foreach ($web in $site.AllWebs) {
 3    $lists = $web.Lists | where {$_.EventReceivers.Count -gt 0}
 4    foreach ($list in $lists) {
 5        $evts = $list.EventReceivers | where {$_.Class -eq "MyCompany.SharePoint.MyFeature.EventReceivers.MyEventReceiver"}
 6        if ($evts.Count -gt 0) {
 7            foreach ($evt in $evts) {
 8                Write-Host("Deleting..." + $list.RootFolder.ServerRelativeUrl + ", " + $evt.Type)
 9                $evt.Delete()
10            }
11        }
12    }
13}

The only thing that threw me off when I was putting this little snippet together was the fact that I couldn’t work with the collections directly due to errors about the collection being modified during the enumeration (so a for loop rather than a foreach loop would have worked just as easily as doing filtering as I am above).

The code above is great for when you know the class name of a specific event receiver that needs to be pulled. If you don’t know the name then you’ll have to add in some reflection to look for the assembly and type – just be careful as the assembly may or may not be in the GAC.