Deleting Orphaned Event Receivers using PowerShell

Posted on Posted in Article, Scripts, SharePoint 2007

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:

$site = get-spsite -url http://portal
foreach ($web in $site.AllWebs) {
    $lists = $web.Lists | where {$_.EventReceivers.Count -gt 0}
    foreach ($list in $lists) {
        $evts = $list.EventReceivers | where {$_.Class -eq MyCompany.SharePoint.MyFeature.EventReceivers.MyEventReceiver"}
        if ($evts.Count -gt 0) {
            foreach ($evt in $evts) {
                Write-Host("Deleting..." + $list.RootFolder.ServerRelativeUrl + ", " + $evt.Type)
                $evt.Delete()
            }
        }
    }
}

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.

4 thoughts on “Deleting Orphaned Event Receivers using PowerShell

  1. I noticed an issue when using this technique against a list that had only 1 feature receiver attached.

    The value for $evts.Count was set to $null, not 1, because the $evts.GetType().BaseType was being returned as a “Microsoft.SharePoint.Administration.SPAutoSerializingObject” and not as a “System.Array”.

    All worked fine for lists that had more than 1 event receiver attached.

  2. You seem to be missing a quote on the left side of the class name:

    $evts = $list.EventReceivers | where {$_.Class -eq MyCompany.SharePoint.MyFeature.EventReceivers.MyEventReceiver”}

    ..should be:
    $evts = $list.EventReceivers | where {$_.Class -eq “MyCompany.SharePoint.MyFeature.EventReceivers.MyEventReceiver”}

    Minor but caused me a moment of dumb confusion. 😉

Leave a Reply

Your email address will not be published. Required fields are marked *

*