Requirement: Copy a document library to another SharePoint Online site using PowerShell.
Have you ever needed to copy a document library from one SharePoint Online site to another? Maybe you needed to move content from an old site to a new one, or create a “test” environment for development work. In this article, I’ll show you how to use PowerShell to copy a document library between two sites. Let’s get started!
The latest document library creation feature introduced in SharePoint Online lets you copy an existing library from any existing site. Here is how it works:
This will copy the source list along with all its columns and settings (but not any contents of the library). Once created, You can use the “Copy to” option from the source library to copy its content to the target document library created.
We can use the PnP PowerShell cmdlet Copy-PnPList to copy a document library to another site. Here is how:
#Variables $SourceSiteURL = "https://crescent.sharepoint.com/sites/Operations" $TargetSiteURL = "https://crescent.sharepoint.com/sites/Sales" $LibraryName = "Invoices" #Connect to Pnp Online Connect-PnPOnline -Url $SourceSiteURL -Interactive #Copy the document library to destination site Copy-PnPList -Identity $LibraryName -DestinationWebUrl $TargetSiteURL -Title $LibraryName
Now, the next part: Copy all files and folders from the source to the destination document library!
#Parameters $SourceSiteURL = "https://crescent.sharepoint.com/sites/Operations" $SourceLibrarySiteRelativeUrl = "/Invoices" $TargetLibraryServerRelativeUrl = "/sites/Migration/Invoices" #Connect to the Source site Connect-PnPOnline -Url $SourceSiteURL -Interactive #Get All Files and Subfolders from Source Library's Root Folder $RootFolderItems = Get-PnPFolderItem -FolderSiteRelativeUrl $SourceLibrarySiteRelativeUrl | Where <($_.Name -ne "Forms") -and (-Not($_.Name.StartsWith("_")))>#Copy Items to the Destination $RootFolderItems | ForEach-ObjectIn classic sites, (or an alternative approach) you can use this method to copy a document library:
Sounds like a lot of manual work? Well, If you need to copy a document library from one SharePoint Online site to another, PowerShell is the way to go. Let me show you how to use PowerShell to copy a document library, including all its contents, from one site to another.
Custom script must be enabled both in source and the destination sites, before running this script! How to Enable Custom Script in SharePoint Online?
Use this PowerShell script to copy a document library with its files and folders to either the same or a different site.
#Function to Copy library to Another site Function Copy-PnPLibrary < param ( [parameter(Mandatory=$true, ValueFromPipeline=$true)][string]$SourceSiteURL, [parameter(Mandatory=$true, ValueFromPipeline=$true)][string]$DestinationSiteURL, [parameter(Mandatory=$true, ValueFromPipeline=$true)][string]$SourceLibraryName, [parameter(Mandatory=$true, ValueFromPipeline=$true)][string]$DestinationLibraryName ) Try < #Connect to the Source Site $SourceConn = Connect-PnPOnline -URL $SourceSiteURL -Interactive -ReturnConnection $SourceCtx = $SourceConn.Context #Get the Source library $SourceLibrary = Get-PnPList -Identity $SourceLibraryName -Includes RootFolder -Connection $SourceConn #Get the List Template $SourceRootWeb = $SourceCtx.Site.RootWeb $SourceListTemplates = $SourceCtx.Site.GetCustomListTemplates($SourceRootWeb) $SourceCtx.Load($SourceRootWeb) $SourceCtx.Load($SourceListTemplates) $SourceCtx.ExecuteQuery() $SourceListTemplate = $SourceListTemplates | Where $SourceListTemplateURL = $SourceRootWeb.ServerRelativeUrl+"/_catalogs/lt/"+$SourceLibrary.id.Guid+".stp" #Remove the List template if exists If($SourceListTemplate) < #Remove-PnPFile -ServerRelativeUrl $SourceListTemplateURL -Recycle -Force -Connection $SourceConn $SourceListTemplate = Get-PnPFile -Url $SourceListTemplateURL -Connection $SourceConn $SourceListTemplate.DeleteObject() $SourceCtx.ExecuteQuery() >Write-host "Creating List Template from Source Library. " -f Yellow -NoNewline $SourceLibrary.SaveAsTemplate($SourceLibrary.id.Guid, $SourceLibrary.id.Guid, [string]::Empty, $False) $SourceCtx.ExecuteQuery() Write-host "Done!" -f Green #Reload List Templates to Get Newly created List Template $SourceListTemplates = $SourceCtx.Site.GetCustomListTemplates($SourceRootWeb) $SourceCtx.Load($SourceListTemplates) $SourceCtx.ExecuteQuery() $SourceListTemplate = $SourceListTemplates | Where #Connect to the Destination Site $DestinationConn = Connect-PnPOnline -URL $DestinationSiteURL -Interactive -ReturnConnection $DestinationCtx = $DestinationConn.Context $DestinationRootWeb = $DestinationCtx.Site.RootWeb $DestinationListTemplates = $DestinationCtx.Site.GetCustomListTemplates($DestinationRootWeb) $DestinationCtx.Load($DestinationRootWeb) $DestinationCtx.Load($DestinationListTemplates) $DestinationCtx.ExecuteQuery() $DestinationListTemplate = $DestinationListTemplates | Where $DestinationListTemplateURL = $DestinationRootWeb.ServerRelativeUrl+"/_catalogs/lt/"+$SourceLibrary.id.Guid+".stp" #Remove the List template if exists If($DestinationListTemplate) < #Remove-PnPFile -ServerRelativeUrl $DestinationListTemplateURL -Recycle -Force -Connection $DestinationConn $DestinationListTemplate = Get-PnPFile -Url $DestinationListTemplateURL -Connection $DestinationConn $DestinationListTemplate.DeleteObject() $DestinationCtx.ExecuteQuery() >#Copy List Template from source to the destination site Write-host "Copying List Template from Source to Destination Site. " -f Yellow -NoNewline Copy-PnPFile -SourceUrl $SourceListTemplateURL -TargetUrl ($DestinationRootWeb.ServerRelativeUrl+"/_catalogs/lt") -Force -OverwriteIfAlreadyExists -Connection $SourceConn Write-host "Done!" -f Green #Reload List Templates to Get Newly created List Template $DestinationListTemplates = $DestinationCtx.Site.GetCustomListTemplates($DestinationRootWeb) $DestinationCtx.Load($DestinationListTemplates) $DestinationCtx.ExecuteQuery() $DestinationListTemplate = $DestinationListTemplates | Where #Create the destination library from the list template Write-host "Creating New Library in the Destination Site. " -f Yellow -NoNewline If(!(Get-PnPList -Identity $DestinationLibraryName -Connection $DestinationConn -ErrorAction SilentlyContinue)) < #Create the destination library $ListCreation = New-Object Microsoft.SharePoint.Client.ListCreationInformation $ListCreation.Title = $DestinationLibraryName $ListCreation.ListTemplate = $DestinationListTemplate $DestinationList = $DestinationCtx.Web.Lists.Add($ListCreation) $DestinationCtx.ExecuteQuery() Write-host "Library '$DestinationLibraryName' created successfully!" -f Green >Else < Write-host "Library '$DestinationLibraryName' already exists!" -f Yellow >Write-host "Copying Files and Folders from the Source to Destination Site. " -f Yellow $DestinationLibrary = Get-PnPList $DestinationLibraryName -Includes RootFolder -Connection $DestinationConn #Copy All Content from Source Library's Root Folder to the Destination Library If($SourceLibrary.ItemCount -gt 0) < #Get All Items from the Root Folder of the Library $global:counter = 0 $ListItems = Get-PnPListItem -List $SourceLibraryName -Connection $SourceConn -PageSize 500 -Fields ID -ScriptBlock $RootFolderItems = $ListItems | Where < ($_.FieldValues.FileRef.Substring(0,$_.FieldValues.FileRef.LastIndexOf($_.FieldValues.FileLeafRef)-1)) -eq $SourceLibrary.RootFolder.ServerRelativeUrl>Write-Progress -Activity "Completed Getting Items from Library $($SourceLibrary.Title)" -Completed #Copy Items to the Destination $RootFolderItems | ForEach-Object < $DestinationURL = $DestinationLibrary.RootFolder.ServerRelativeUrl Copy-PnPFile -SourceUrl $_.FieldValues.FileRef -TargetUrl $DestinationLibrary.RootFolder.ServerRelativeUrl -Force -OverwriteIfAlreadyExists -Connection $SourceConn Write-host "`tCopied $($_.FileSystemObjectType) '$($_.FieldValues.FileRef)' Successfully!" -f Green >> #Cleanup List Templates in source and destination sites $SourceListTemplate = Get-PnPFile -Url $SourceListTemplateURL -Connection $SourceConn $DestinationListTemplate = Get-PnPFile -Url $DestinationListTemplateURL -Connection $DestinationConn $SourceListTemplate.DeleteObject() $DestinationListTemplate.DeleteObject() $SourceCtx.ExecuteQuery() $DestinationCtx.ExecuteQuery() #Remove-PnPFile -ServerRelativeUrl $SourceListTemplateURL -Recycle -Force -Connection $SourceConn #Remove-PnPFile -ServerRelativeUrl $DestinationListTemplateURL -Recycle -Force -Connection $DestinationConn > Catch < write-host -f Red "Error:" $_.Exception.Message >> #Parameters $SourceSiteURL = "https://crescent.sharepoint.com/sites/Retail" $DestinationSiteURL = "https://crescent.sharepoint.com/sites/warehouse" $SourceLibraryName = "Invoices" $DestinationLibraryName = "Invoices V2" #Call the function to copy document library to another site Copy-PnPLibrary -SourceSiteURL $SourceSiteURL -DestinationSiteURL $DestinationSiteURL -SourceLibraryName $SourceLibraryName -DestinationLibraryName $DestinationLibraryName
You can also use this PowerShell method to move a document library to another site! Just add a step to delete the source document library (Which we call “Move”!). Ensure you have Site Collection administrator access to both the source and destination sites, and that the custom script is enabled before running this script!