sharepoint, sharepoint 2013

Recursively Copy Document Libraries from SharePoint 2010 to SharePoint 2013

We’ve recently been looking at migrating quite a large amount of content from our legacy SharePoint 2010 Farm to a new clean SharePoint 2013 installation. For a variety of reasons we didn’t want to go the whole content database->site collection upgrade approach, not least of all because we really wanted a clean break from what has been quite a naughty SharePoint 2010 farm. The thing is creaking, it hates all forms of human life and is quite possibly haunted. Because of this we wanted to bring the binary file data across and essentially nothing else.

Migrating documents around would seem to be one of those things that an Enterprise class document management platform should have nailed. However it turns out, its not quite as straightforward as you might think.

Perhaps I’m asking too much, but there didn’t seem to be any simple way of saying, “recursively copy all that, and place it there”.

I came across scores of roll your own scripts, C# apps and seriously expensive bits of software that would charge me by the gigabyte. For various reasons most of the approaches I tried didn’t pan out. We either had to spend a ton of cash to get a pro piece of software to (presumably) do what we needed, or we could spend a lot of time writing our own recursive code via either Powershell or C# and attempt to work around the fact that there is no real recursive copy function in the SharePoint APIs – at least not one that I found.

The approach I ended up going with is undoubtedly brute force, but has been extremely effective. The process is essentially a powershell script that does the following:

  1. Loop through all the target document libraries at the source site
  2. Dynamically create a *mapped drive* to both the Source and Destination locations
  3. Robocopy the files between the two mapped folders – taking advantage of the fact that robocopy doesn’t care that this is sharepoint behind the scenes and handles recursive copy like a walk in the park
  4. Wonder why that wasn’t considerably easier

There is one caveat here – because we were rearranging our library structure, I had already pre-created the destination document libraries. You may well not be in this scenario, in which case you will need to tweak the script to potentially create a document library at the correct location as you go. This would probably be a one line change.

The following script will need to be tweaked to get your source and destination library locations lining up. It won’t work right off the bat, but I did want to provide as a sample to demonstrate that powershell + robocopy can be used to migrate a large amount of content as it took me waaaayy to long to get to this point (thanks MS)


$currentSourceDriveMapping = ""
$currentDestinationDriveMapping = ""

$sourceWeb = Get-SPWeb "http://mysourcelocation"
$destinationWeb =  Get-SPWeb "http://mydestinationsite"

Write-Host "Connected to $sourceWeb"
Write-Host "Connected to $destinationWeb"

Write-Host "Releasing mapped drives"

$sourceLibraries = $sourceWeb.Lists

Write-Host $sourceLibraries.Count + " document libraries found at source location"

$listTemplate = [Microsoft.SharePoint.SPListTemplateType]::DocumentLibrary

$processedCounter = 1

foreach($currentSourceLibrary in $sourceLibraries){
	Write-Host "Mapping Source Library to S drive"
	$currentSourceDriveMapping = "http://mysourcelocation" + $currentSourceLibrary.RootFolder.ServerRelativeUrl
	Write-Host $currentSourceDriveMapping
	# net use will create a mapped drive using the sharepoint location provided 
	net use s: "$currentSourceDriveMapping"
	Write-Host "Mapping Source Library to T drive"
	# NOTE: Voodoo here that won't apply to you - this made sense in my environment due to restructuring that we were doing
	$currentDestinationDriveMapping = $destinationWeb.Url + "/" + $currentSourceLibrary.Description + "/Tech Notes"
	Write-Host $currentDestinationDriveMapping
	net use t: "$currentDestinationDriveMapping"
	Write-Host "Mapping Source Library to T drive"
	# Robocopy all folders apart from the sharepoint specific Forms folder at the root of the source library
	# Note that robocopy is ideal for this as it already implictly handles recursive copying
	robocopy S: T: /e /xd s:\Forms
	Write-Host "Releasing mapped drives"
	net use s: /delete
	net use t: /delete
	Write-Host $processedCounter " records libraries processed successfully"


I’ve used this script to migrate about 25GB worth of content in 2 hours. It’s not lightning fast, but it got the job done.

There are likely numerous caveats that may apply to you but didn’t to me. Amongst them would be the fact that any relvant permissions, history, properties will almost certainly not be copied over.

If you just need a fairly straight recursive dump of content though this may give you some pointers


Leave a Reply

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

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

Google+ photo

You are commenting using your Google+ 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 )


Connecting to %s