We are preparing to migrate content from a SharePoint 2007 environment to a SharePoint 2013 farm, by way of a third party tool.

As part of the pre migration cleanup, I've been looking at document versions across site collections. We have a large amount of document versions, some of which will not be required.

We are planning to only move the latest version of the documents over, but in some cases, we will need to keep the history of some of the documents. So we will need to pick and choose.

Where there are libraries that have a large number of document versions, I'd like to remove those now, while we analyse what is left over. I was hoping that the following script (from http://www.mukalian.com/blog/post/2011/04/10/PowerShell-Script-to-Delete-All-Versions-in-a-Document-Library.aspx) would be able to pick and chose a sub-site and delete just that site/libraries versions only - but it does it across an entire site collection.

Can anyone tell me if it's possible to modify this script, so that I can target it against a site/library, instead of a full site collection.

[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
# get site
$site = new-object Microsoft.SharePoint.SPSite("http://mossdev:8000")
# loop through webs
foreach ($web in $site.AllWebs)
{
  # loop through all lists in web
  foreach ($list in $web.Lists)
  {
    # examine if BaseType of list is NOT a Document Library
    if ($list.BaseType -ne "DocumentLibrary") 
    {
      # forget the rest and return to top
      continue
    }
    # loop through each item
    foreach ($item in $list.Items)
    {
      # work with the file object as we're in a document library
      $file = $item.File
      # delete all versions
      $file.Versions.DeleteAll()
    }
  }
}
$web.Dispose();
$site.Dispose();

In the script above, I've modified the

$site = new-object Microsoft.SharePoint.SPSite("http://mossdev:8000")

so that it hit a particular site, for example:

http://example.com/sitecollection/site

But what it did was actually hit

http://example.com/sitecollection
(getting rid of all versions across the collection).

  • Depending on your migration tool, you can specify to only copy over the most recent version. We use ContentMatrix from Metalogix and it has the option to copy the most recent version, a set number, or all of them. – Eric Alexander Oct 23 '15 at 12:02
  • Hi Eric, that's the one we're using, however we just want to do some upfront house keeping to get an accurate figure on the DB sizing. Thanks! – Rob Sked Oct 23 '15 at 13:12
  • I would just be hesitant to squash it in your production environment, people tend to get upset when version history and data goes missing. I would do that in the migration itself. If you want to size it, try backing up and recovering the site to a dev/test environment and executing the script there to see the space savings. – Eric Alexander Oct 23 '15 at 13:16
up vote 2 down vote accepted

Single Web:

[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
#get site
$site = new-object Microsoft.SharePoint.SPSite("http://example.com/sitecollection/site")
# get web
$web = site.OpenWeb("website")
# loop through all lists in web
foreach ($list in $web.Lists)
{
    # examine if BaseType of list is NOT a Document Library
    if ($list.BaseType -ne "DocumentLibrary") 
    {
      # forget the rest and return to top
      continue
    }
    # loop through each item
    foreach ($item in $list.Items)
    {
      # work with the file object as we're in a document library
      $file = $item.File
      # delete all versions
      $file.Versions.DeleteAll()
    }
}
$web.Dispose();
$site.Dispose();

Single Library:

[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
#get site
$site = new-object Microsoft.SharePoint.SPSite("http://example.com/sitecollection/site")
# get web
$web = site.OpenWeb("website")
$list = $web.Lists["Library Title"]
# examine if BaseType of list is NOT a Document Library
if ($list.BaseType -eq "DocumentLibrary") 
{
    foreach ($item in $list.Items)
    {
      # work with the file object as we're in a document library
      $file = $item.File
      # delete all versions
      $file.Versions.DeleteAll()
    }
}
$web.Dispose();
$site.Dispose();
  • Thanks Paul - encountered this error when running: New-Object : Constructor not found. Cannot find an appropriate constructor for type Microsoft.SharePoint.SPWeb. At line:3 char:18 + $web = new-object <<<< Microsoft.SharePoint.SPWeb("examples.com/sites/collection/site/site") + CategoryInfo : ObjectNotFound: (:) [New-Object], PSArgumentException + FullyQualifiedErrorId : CannotFindAppropriateCtor,Microsoft.PowerShell.Commands.NewObjectCommand – Rob Sked Oct 23 '15 at 11:34
  • That should say "Microsoft.SharePoint.SPWeb("http:example.com/sites/collection/site/site") - That still doesn't work however – Rob Sked Oct 23 '15 at 11:54
  • Just noticed it's 2007. Updated my answer. OpenWeb() will open root web of the site collection. If you want to open a different web use OpenWeb("SiteCollectionRelativeURLOfTheWeb") (e.g. OpenWeb("web1"); You can use OpenWeb("") for root site as well. – Paul Strupeikis Oct 23 '15 at 12:08
  • Perfect, that's worked like a charm, thanks Paul! – Rob Sked Oct 23 '15 at 13:11

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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