Powershell Script for purging recycle bin SharePoint 2007/2010

I was faced with a large RecyleBin and clearing the bin from the user interface would cause the browser to time out. I wrote a Powershell script that you may find handy. I would like to hear from anybody who has faced such an issue and how did they go about solving.

Caveats:

Depending on the number of rows in the RecycleBin, the purge may take a while. Updates from Microsoft in the October of 2010 have dramatic improvements in the purge rate.

WSS Oct 2010 CU – http://support.microsoft.com/default.aspx?scid=kb;EN-US;2412268
MOSS Oct 2010 CU – http://support.microsoft.com/default.aspx?scid=kb;EN-US;2412267

Please note that the above fixes are for MOSS/WSS 3.0 only. SharePoint 2010 is well optimized out of box.

I noticed that changing the batchsize can alter the rate of purge although the change was not significant.

Turning off the RecycleBin using Central Administration was near impossible because each time I tried, SharePoint would kick of a job to purge and this would cause the UI to time out.

[System.Reflection.Assembly]::LoadWithPartialName(”Microsoft.SharePoint”)#$batchsize=10
function OutHorRuler
{
write-host "-----------------------------------------------------------------"
}

function DisplayTimeStamp
{
$a=get-date
write-host $a.ToLongTimeString()
}

###############################################################################
#
#function to loop through items in the Recycle Bin and purge them using DeleteAll
#
# $ListURL=the absolute URL to a site or web
# $batchSize=number of items queried in every iteration
# $stage=specifies the stage of the recyle bin 1 or 2
#
###############################################################################

function PurgeRecycleBinUsingDeleteAll

{param ($ListURL,$batchSize,$stage)

$mySite = new-object Microsoft.SharePoint.SPSite($ListURL)
$myWeb = $mySite.OpenWeb()
Write-host "Intializing SPWeb, SPSite for " $ListURL
OutHorRuler

$itemCount=0
$recylebinQuery=new-object Microsoft.SharePoint.SPRecycleBinQuery
$recylebinQuery.RowLimit = $batchSize

write-host "Going to delete all items using DeleteAll in the recycle bin with batch size: " $batchSize
$loop=1
While ($loop -gt 0)
{
write-host "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
DisplayTimeStamp
write-host "Begin query"
$itemColl=$myWeb.GetRecycleBinItems($recylebinQuery)
$loop=$itemColl.Count

$itemColl.DeleteAll()
write-host "DeleteAll complete"
DisplayTimeStamp
write-host "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
}

write-host "About to dispose SP objects"
$myweb.Dispose()
$mySite.Dispose()
}

###############################################################################
#
#function to loop through items in the Recycle Bin and purge them using DeleteOneByOne
#
# $ListURL=the absolute URL to a site or web
# $batchSize=number of items queried in every iteration
# $stage=specifies the stage of the recyle bin 1 or 2
# $deletemode=specifies whether to do a DeleteAll(=2) or Delete one by on(=1)
#
###############################################################################

function PurgeRecycleBinUsingDeleteOneByOne

{param ($ListURL,$batchSize,$stage,$deletemode)

$mySite = new-object Microsoft.SharePoint.SPSite($ListURL)
$myWeb = $mySite.OpenWeb()
Write-host "Intializing SPWeb, SPSite for " $ListURL
OutHorRuler

$itemCount=0
$recylebinQuery=new-object Microsoft.SharePoint.SPRecycleBinQuery
$recylebinQuery.RowLimit = $batchSize
#if ($stage -eq 1)
# {
# $recylebinQuery.ItemState=[Microsoft.SharePoint.SPRecycleBinItemState]::FirstStageRecycleBin
# }
#else
# {
# $recylebinQuery.ItemState=[Microsoft.SharePoint.SPRecycleBinItemState]::SecondStageRecycleBin
# }

$starttime=get-date
write-host "Going to delete all items OneByOne in the recycle bin with batch size: " $batchSize
$totalcount=[system.int32]0
$loop=1
While ($loop -gt 0)
{
write-host "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
DisplayTimeStamp
write-host "Begin query"
$starttimeForThisLoop=get-date
if ($stage -eq 1)
{
$recylebinQuery.ItemState=[Microsoft.SharePoint.SPRecycleBinItemState]::FirstStageRecycleBin
$itemColl=$myWeb.GetRecycleBinItems($recylebinQuery)
}
else
{
$recylebinQuery.ItemState=[Microsoft.SharePoint.SPRecycleBinItemState]::SecondStageRecycleBin
$itemColl=$mySite.GetRecycleBinItems($recylebinQuery)
}

write-host "End query"
DisplayTimeStamp

$loop=$itemColl.Count
write-host "Got the count of items to delete:" $loop
DisplayTimeStamp
if ($deletemode -eq 1)
{
write-host "Performing Item by Item deletion"
foreach ($itemtodelete in $itemColl)
{
$idsarray = [System.Guid]$itemtodelete.ID
$itemColl.Delete($idsarray)
}
}
else
{
write-host "Performing DeleteAll"
$itemColl.DeleteAll()
}

write-host "Finished deletion"
DisplayTimeStamp

$totalcount=$totalcount+$loop
$endtime=get-date

$span=[System.timespan]($endtime - $starttime)
$timeelapsed=$span.TotalSeconds
$rateofdelete=$totalcount/$timeelapsed*60

$spanForThisLoop=[System.timespan]($endtime - $starttimeForThisLoop)
$timeelapsedForThisLoop=$spanForThisLoop.TotalSeconds
$rateOfDeleteForThisLoop=$loop/$timeelapsedForThisLoop*60
write-host "OneByOneDelete complete, items deleted:" $totalcount " stage:" $stage " deletemode:" $deletemode
write-host "Average rate of deletion/min:" $rateofdelete
write-host "Current rate of deletion/min:" $rateOfDeleteForThisLoop
DisplayTimeStamp
write-host "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
}

write-host "About to dispose SP objects"
$myweb.Dispose()
$mySite.Dispose()
}

write-host $timeelapsed

$batchsize=100

$deletemode=2

$sitecollection="http://myserver/sites/mysitecollection/"

DisplayTimeStamp

write-host "clear the first stage"
PurgeRecycleBinUsingDeleteOneByOne $sitecollection $batchsize 1 $deletemode

write-host "clear the second stage"
PurgeRecycleBinUsingDeleteOneByOne $sitecollection $batchsize 2 $deletemode

DisplayTimeStamp

About these ads

About saurabhmoss
I worked with Microsoft Consulting Services for the past 7 years. I am now an independent SharePoint & Microsoft .NET technology contractor in UK

4 Responses to Powershell Script for purging recycle bin SharePoint 2007/2010

  1. Richard says:

    I have 4 million items remaining in my recycle bins (down from nearly 8 million after months of manual and item by item script deletes) so am very interested in a batch delete script. I don’t have the skills myself so am interested to find something that will help me out. Unfortunately on my server your script is finding 0 items to delete in the end user bin and $batchsize (whatever it’s set to) in the admin bin (both are populated) and deletes nothing over a long period of time. If you could get in touch with a suggestion or two, I’d be very grateful. Thanks! Richard

    • saurabhmoss says:

      I did experience this once and that was when I discovered that all items in one of the stages had been cleared. Can you confirm that regardless of the stage (1 or 2) the the script finds zero items? Another suggestion would be to observe if the left over items belong to a speific subsite – if that is the case then you could try specifying an absolute URL to the subsite as opposed to specifying the root site collection. e.g. http://myserver/sites/mysite/subsite1/subsite2

  2. ashish trivedi says:

    Compared with the above one, Here is a Simple and neat PowerShell code to Empty SharePoint Recycle bins:

    Empty SharePoint Recycle Bins Programmatically with PowerShell

  3. LSI Keyword says:

    You can definitely see your enthusiasm within the article you write.
    The arena hopes for more passionate writers like you who aren’t afraid to mention how they believe. At all times go after your heart.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: