In this article I want to share how to use PowerShell to attach event receiver to a list, provide configuration values from an xml. And also, how to use PowerShell to view a list of existing event receivers.
Recently, in our production environment, the functionality added by an event handler was not working. I had used the visual studio to add an event receiver, which automatically adds CAML markup to attach the event handler.
We had already provisioned the document library. So, activation of the feature containing the above CAML to attach the event handler did not seem to work.
In order to confirm that the event handler was not attached, I wrote a PowerShell script to list all the event handlers attached to that particular library.
I loop the EventReceivers
in descending order of index. This is because if we were to add code to remove the existing event handers, we can insert the following command:
$Receiver.Delete();
Within the loop, we cannot add or remove items from the collection if we are looping the index in the ascending order i.e start with 0 till the end of the loop (we get an error that the collection was modified if we do that). In this case, since we are just listing the event receivers we can even use ascending loop.
Also, in case you are planning to remove any event receivers, ensure that you take a backup of the list of event receivers. Because, if we don’t and we remove the event receivers in a loop, we do not have the information to add them back.
To copy the information of existing event receivers, insert a line such as
$list.EventReceivers | Out-File -filepath "C:\ListName-EventReceivers.txt"
if ((Get-PSSnapin -Name Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue) -eq $null )
{
Add-PsSnapin Microsoft.SharePoint.PowerShell
}
$config = (Get-Content "Config.xml")
if ($config -eq $null ) {
Write-Host "Parameter XML not Loaded "
exit
}
$site = $config.EventHandlerInfo.Web;
$webUrl = $site.WebUrl;
Write-Host($webUrl);
Write-Host "Opening web $webUrl" -nonewline
$web = Get-SPWeb $webUrl
Write-Host "$web"
Write-host " – done " -foreground green
foreach($handler in $site.EventHandler)
{
$ListName = $handler.ListName
$assembly = $handler.Assembly
$class = $handler.Class
Write-Host "Opening ‘$ListName’ list" -nonewline
$list = $web.Lists[$ListName]
if ($list -eq $null)
{
Write-host " – can’t open list " -foreground red
return
}
else
{
Write-host " – done " -foreground green
}
Write-Output "Existing event receivers:"
$count = $list.EventReceivers.Count
if ($count -gt 0)
{
for($i = $count -1; $i -gt -1; $i–-)
{
$Receiver = $list.EventReceivers[$i] ;
$type = $Receiver.Type ;
$asm = $Receiver.Assembly ;
$cls = $Receiver.Class;
Write-Host " [$i] – $type – $asm – $cls";
}
}
else
{
Write-Host " – no existing EventReceivers found." -foreground green
}
}
We could have probably used code (feature activated code or console application) to attach the event handler. However, I think for these kinds of one time activities, it would be better to use PowerShell.
Below PowerShell attaches the event handler to a document library. I have initialized a sequence number and increment this number every time we attach an event handler. This is because, we need to specify a different sequence number for each event handler to indicate the order in which they should be executed.
if ((Get-PSSnapin -Name Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue) -eq $null )
{
Add-PsSnapin Microsoft.SharePoint.PowerShell
}
$config = (Get-Content "Config.xml")
if ($config -eq $null ) {
Write-Host "Parameter XML not Loaded "
exit
}
$site = $config.EventHandlerInfo.Web;
$webUrl = $site.WebUrl;
Write-Host($webUrl);
Write-Host "Opening web $webUrl" -nonewline
$web = Get-SPWeb $webUrl
Write-Host "$web"
Write-host " – done " -foreground green
foreach($handler in $site.EventHandler)
{
$ListName = $handler.ListName
$assembly = $handler.Assembly
$class = $handler.Class
Write-Host "Opening $ListName ..." -nonewline
$list = $web.Lists[$ListName]
if ($list -eq $null)
{
Write-host " – can’t open list " -foreground red
return
}
else
{
Write-host " – done " -foreground green
}
$seqNum = 1001;
foreach($typeInfo in $handler.Types.Type)
{
$type = $typeInfo.Id
$sync = $typeInfo.Sync
Write-Host "Adding new event receivers: $class $type"
$spEventReceiver = $list.EventReceivers.Add();
$spEventReceiver.Assembly = $assembly
$spEventReceiver.Class = $class
$spEventReceiver.Type = $type
$spEventReceiver.SequenceNumber = $seqNum;
$seqNum= $seqNum +1;
$spEventReceiver.Synchronization = $sync;
$spEventReceiver.Update();
}
}
Note that we need to provide the full path with the namespace while specifying the Class attribute.
The Type -> Id is used for the Type of event handler. Below is a full list of types for event receivers.
InvalidReceiver = -1,
ItemAdding = 1,
ItemUpdating = 2,
ItemDeleting = 3,
ItemCheckingIn = 4,
ItemCheckingOut = 5,
ItemUncheckingOut = 6,
ItemAttachmentAdding = 7,
ItemAttachmentDeleting = 8,
ItemFileMoving = 9,
FieldAdding = 101,
FieldUpdating = 102,
FieldDeleting = 103,
ListAdding = 104,
ListDeleting = 105,
SiteDeleting = 201,
WebDeleting = 202,
WebMoving = 203,
WebAdding = 204,
WorkflowStarting = 501,
ItemAdded = 10001,
ItemUpdated = 10002,
ItemDeleted = 10003,
ItemCheckedIn = 10004,
ItemCheckedOut = 10005,
ItemUncheckedOut = 10006,
ItemAttachmentAdded = 10007,
ItemAttachmentDeleted = 10008,
ItemFileMoved = 10009,
ItemFileConverted = 10010,
FieldAdded = 10101,
FieldUpdated = 10102,
FieldDeleted = 10103,
ListAdded = 10104,
ListDeleted = 10105,
SiteDeleted = 10201,
WebDeleted = 10202,
WebMoved = 10203,
WebProvisioned = 10204,
WorkflowStarted = 10501,
WorkflowPostponed = 10502,
WorkflowCompleted = 10503,
EmailReceived = 20000,
ContextEvent = 32766
We used the below configuration file Config.xml to provide the configuration values to the powershell script.
<EventHandlerInfo>
<Web>
<WebUrl>http:
<EventHandler>
<ListName>Document Library</ListName>
<Assembly>Company.Namespace.Assembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=replacetoken</Assembly>
<Class>Company.Namespace.EventReceiverClass</Class>
<Types>
<Type>
<Id>10001</Id>
<Sync>0</Sync>
</Type>
<Type>
<Id>3</Id>
<Sync>0</Sync>
</Type>
</Types>
</EventHandler>
</Web>
</EventHandlerInfo>
The post PowerShell to attach event receiver to a list appeared first on SharePoint Guide.