You’re a Farm Admin (and Full Control User Policy, too!). But you can’t delete that item.

So over in the SharePoint TechNet Forums (other MCCs, MVPs, MCMs, please get involved!), there was a thread where an Administrator who had Full Control over all of the appropriate aspects of the farm could not move an item to the Second Stage Recycle Bin, nor could he delete the item using the following PowerShell script”

So here we loop through the all of the items in the First Stage Recycle Bin and if the Title of the item matches the desired filter, we move it to the Second Stage Recycle Bin and finally Delete it.  Works fine if you (the Farm Admin) delete items that you have personally deleted from the site, but not on other user’s items.  When attempting to MoveToSecondStage() or Delete(), we get the errors:

Well, so what is the current state of the object?  If we take a look at it, the ItemState is “FirstStageRecycleBin”, exactly what we’d expect.  So why are we encountering this error?  Turns out the sproc in the Content Database is throwing us off…

First, in the Microsoft.SharePoint.SPRecycleBinUtility class, and I’m cutting out a whole lot of unnecessary code, we encounter this section:

Notice how if web is null, we are not passing a GUID and are setting the UserId to 0?  Well, let’s take a look at dbo.proc_MoveRecycleBinItemToSecondStage in our selected Content Database:

See the difference?  If you happen to have a UserId of “0” (which as the Farm Admin, you won’t, it will be at least 1), our SELECT statement includes nothing about a UserId!  But if we do have a UserId, we pass that UserId into the SELECT statement (which is selecting items from the dbo.RecycleBin table).  When running PowerShell commands, the database context will be under the account the PowerShell window was run under, unlike via the web, where the database connection is in the context of the Application Pool account.

Since you’re not the user who deleted the item into the First Stage Recycle Bin, the SELECT statement will skip over that item and we’ll end up with error 1168 (0x490 or ERROR_NOT_FOUND), which is an accurate error.

So what is the solution?  A small modification to the PowerShell script:

While we still loop through the items in the same fashion, we pass the ItemId back to the RecycleBin object and use the RecycleBin object methods MoveToSecondStage(item) and Delete(item) instead of using the item’s object methods.

Leave a Reply