2

I have a powershell script that I am using to update some list items programatically. It seems to work as I expected when I disable the event reciever that is associated with the list however when I re-enable it I am unable to perform the updates and I get this error:

Exception calling "Update" with "0" argument(s): "The file [Filename] has been modified by SHAREPOINT\system on 16 Jul 2013 14:53:52 -0400."

The scenario seems almost identical to this question: Sharepoint 2007 Powershell: $item.update() gives error that file has been modified

Here is my code for the event reciever that as you can see includes the EventFiringEnabled settings as suggested in the post above.

public override void ItemAdded(SPItemEventProperties properties)
        {
            logULS("ItemAdded Started.");
            base.ItemAdding(properties);

            var web = properties.Web;
            var item = properties.ListItem;
            var id = String.Empty;
            try
            {
                web.AllowUnsafeUpdates = true;
                this.EventFiringEnabled = false;

               //Update Item Fields Here                
            }
            catch (Exception ex)
            {
                logULS("ItemAdded Error: " + ex.Message + "/" + ex.StackTrace);
            }
            finally
            {
                this.EventFiringEnabled = true;
                web.AllowUnsafeUpdates = false;
            }
            logULS("ItemAdded Ended.");
        }

The powershell code is quite lengthy but in summary, if looks for an item and if it doesn't exist then it adds it, then it sets some of the fields associated with the item. It is on the update where it fails.

$uploaded = $spFileCollection.Add( $($spFolder.Url)+"/"+$newFileName , $data, $true )

$spItem = $uploaded.Item 
$spItem["Title"] = $row.Title

UpdateAuthorEditor $spItem  $spWeb $row.CreatedBy $row.ModifiedBy
$encodedUrl = [System.Web.HttpUtility]::UrlPathEncode($url)
UpdateReadOnlyFieldValue ([REF]$spItem) "Old Meta Data" ("Old URL: "+ $encodedUrl )

$spItem.Update()

Now I realize I can just disable the event reciever when I run this script however I would like to avoid that if possibile because it is possible other people could be using the list at the same time and also it's not first time we have encountered this problem.

2 Answers 2

3

What is happening is that your event receiver is kicking in before your PowerShell is done, and modifying it on a different thread before your PowerShell update occurs. When SharePoint hits your update statement, it sees that the item in the database is no longer the same as the one it's trying to update.

I've got 3 different approaches:

  1. Set all of your fields at add time, so you don't need the update.
  2. Disable event firing in the PowerShell around your add, as described here: How to disable event firing outside an event?
  3. Retrieve a fresh copy of your item after the add - $spItem = $list.GetItemById($uploaded.Item.Id); this may require a bit of waiting logic if your event receiver is asynchronous to make sure it has a chance to fire.
2
1

You are calling base.ItemAdding from within the ItemAdded event receiver. It may not be the actual cause of the problem, but it's the first thing I would fix.

public override void ItemAdded(SPItemEventProperties properties)
    {
        logULS("ItemAdded Started.");
        base.ItemAdding(properties);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.