SharePoint Online: Copy All Document Libraries to Another Site using PowerShell
Requirement: Copy All Document Libraries to another Site collection in SharePoint Online.
PowerShell to Copy Document Libraries from One Site to Another Site Collection:
Are you looking to migrate all of your SharePoint Online document libraries from one site to another? If so, you can use PowerShell to copy them all over easily. In a migration project, I have a requirement to copy all document libraries from one site collection to another. Here is the PowerShell script I’ve used to copy all libraries (just the library without its actual content) between site collections:
#Parameters
$SourceSiteURL = "https://crescent.sharepoint.com/sites/Neoma"
$DestinationSiteURL = "https://crescent.sharepoint.com/sites/Neoma-Copy"
#Connect to the source Site
Connect-PnPOnline -URL $SourceSiteURL -Interactive
#Get all document libraries
$SourceLibraries = Get-PnPList | Where {$_.BaseType -eq "DocumentLibrary" -and $_.Hidden -eq $False}
#Connect to the destination site
Connect-PnPOnline -URL $DestinationSiteURL -Interactive
#Get All Lists in the Destination
$Libraries = Get-PnPList
ForEach($Library in $SourceLibraries)
{
#Check if the library already exists in target
If(!($Libraries.Title -contains $Library.Title))
{
#Create a document library
New-PnPList -Title $Library.Title -Template DocumentLibrary
Write-host "Document Library '$($Library.Title)' created successfully!" -f Green
}
else
{
Write-host "Document Library '$($Library.Title)' exists already!" -f Yellow
}
}
SharePoint Online: PowerShell to Copy Libraries with its Content Between Sites
This time, let’s copy all document libraries along with their contents (Files, Folders, Sub-folders, etc.) of the document libraries to another site collection:
#Parameters
$SourceSiteURL = "https://crescent.sharepoint.com/sites/Marketing"
$DestinationSiteURL = "https://crescent.sharepoint.com/sites/Branding"
#Connect to the source Site
Connect-PnPOnline -URL $SourceSiteURL -Interactive
#Get all document libraries
$SourceLibraries = Get-PnPList -Includes RootFolder | Where {$_.BaseType -eq "DocumentLibrary" -and $_.Hidden -eq $False}
#Connect to the destination site
Connect-PnPOnline -URL $DestinationSiteURL -Interactive
#Get All Lists in the Destination site
$DestinationLibraries = Get-PnPList
ForEach($SourceLibrary in $SourceLibraries)
{
#Check if the library already exists in target
If(!($DestinationLibraries.Title -contains $SourceLibrary.Title))
{
#Create a document library
$NewLibrary = New-PnPList -Title $SourceLibrary.Title -Template DocumentLibrary
Write-host "Document Library '$($SourceLibrary.Title)' created successfully!" -f Green
}
else
{
Write-host "Document Library '$($SourceLibrary.Title)' already exists!" -f Yellow
}
#Get the Destination Library
$DestinationLibrary = Get-PnPList $SourceLibrary.Title -Includes RootFolder
$SourceLibraryURL = $SourceLibrary.RootFolder.ServerRelativeUrl
$DestinationLibraryURL = $DestinationLibrary.RootFolder.ServerRelativeUrl
#Copy All Content from Source Library to Destination library
Copy-PnPFile -SourceUrl $SourceLibraryURL -TargetUrl $DestinationLibraryURL -SkipSourceFolderName -Force -OverwriteIfAlreadyExists
Write-host "`tContent Copied from $SourceLibraryURL to $DestinationLibraryURL Successfully!" -f Green
}
The above script works perfectly fine with simple document libraries. However, What if your document library has custom metadata columns added to it? What if you want to copy document libraries along with their custom settings? Well, here is the PowerShell script that uses creating list template and list instances method to copy document library in SharePoint Online!
PowerShell to Copy Document Libraries Between Site Collections in SharePoint Online
This PowerShell script copies lists and their settings and metadata columns to the destination site.
#Function to Copy All libraries from One Site to another
Function Copy-PnPAllLibraries
{
param (
[parameter(Mandatory=$true, ValueFromPipeline=$true)][string]$SourceSiteURL,
[parameter(Mandatory=$true, ValueFromPipeline=$true)][string]$DestinationSiteURL
)
Try {
#Connect to the Source Site and Get the List Templates
$SourceConn = Connect-PnPOnline -URL $SourceSiteURL -Interactive -ReturnConnection
$SourceCtx = $SourceConn.Context
$SourceRootWeb = $SourceCtx.Site.RootWeb
$SourceListTemplates = $SourceCtx.Site.GetCustomListTemplates($SourceRootWeb)
$SourceCtx.Load($SourceRootWeb)
$SourceCtx.Load($SourceListTemplates)
$SourceCtx.ExecuteQuery()
#Connect to the Destination Site and Get the List Templates
$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()
#Exclude certain libraries
$ExcludedLibraries = @("Style Library","Preservation Hold Library", "Site Pages", "Site Assets","Form Templates", "Site Collection Images","Site Collection Documents")
#Get Libraries from Source site - Skip hidden and certain libraries
$SourceLibraries = Get-PnPList -Includes RootFolder -Connection $SourceConn | Where {$_.BaseType -eq "DocumentLibrary" -and $_.Hidden -eq $False -and $_.Title -notin $ExcludedLibraries}
#Iterate through each library in the source
ForEach($SourceLibrary in $SourceLibraries)
{
Write-host "Copying library:"$SourceLibrary.Title -f Green
#Remove the List template if exists
$SourceListTemplate = $SourceListTemplates | Where {$_.Name -eq $SourceLibrary.id.Guid}
$SourceListTemplateURL = $SourceRootWeb.ServerRelativeUrl+"/_catalogs/lt/"+$SourceLibrary.id.Guid+".stp"
If($SourceListTemplate)
{
Remove-PnPFile -ServerRelativeUrl $SourceListTemplateURL -Recycle -Force -Connection $SourceConn
}
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 {$_.Name -eq $SourceLibrary.id.Guid}
#Remove the List template if exists in destination
$DestinationListTemplate = $DestinationListTemplates | Where {$_.Name -eq $SourceLibrary.id.Guid}
$DestinationListTemplateURL = $DestinationRootWeb.ServerRelativeUrl+"/_catalogs/lt/"+$SourceLibrary.id.Guid+".stp"
If($DestinationListTemplate)
{
Remove-PnPFile -ServerRelativeUrl $DestinationListTemplateURL -Recycle -Force -Connection $DestinationConn
}
#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 $DestinationListTemplateURL -SkipSourceFolderName -Force -OverwriteIfAlreadyExists
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 {$_.Name -eq $SourceLibrary.id.Guid}
#Create the destination library from the list template
Write-host "Creating New Library in the Destination Site..." -f Yellow -NoNewline
If(!(Get-PnPList -Identity $SourceLibrary.Title -Connection $DestinationConn))
{
#Create the destination library
$ListCreation = New-Object Microsoft.SharePoint.Client.ListCreationInformation
$ListCreation.Title = $SourceLibrary.Title
$ListCreation.ListTemplate = $DestinationListTemplate
$DestinationList = $DestinationCtx.Web.Lists.Add($ListCreation)
$DestinationCtx.ExecuteQuery()
Write-host "Library '$($SourceLibrary.Title)' created successfully!" -f Green
}
Else
{
Write-host "Library '$($SourceLibrary.Title)' already exists!" -f Yellow
}
#Copy content from Source to destination library
$SourceLibraryURL = $SourceLibrary.RootFolder.ServerRelativeUrl
$DestinationLibrary = Get-PnPList $SourceLibrary.Title -Includes RootFolder -Connection $DestinationConn
$DestinationLibraryURL = $DestinationLibrary.RootFolder.ServerRelativeUrl
Write-host "`Copying Content from $SourceLibraryURL to $DestinationLibraryURL..." -f Yellow -NoNewline
#Copy All Content from Source Library to the Destination Library
Copy-PnPFile -SourceUrl $SourceLibraryURL -TargetUrl $DestinationLibraryURL -SkipSourceFolderName -Force -OverwriteIfAlreadyExists
Write-host "`tContent Copied Successfully!" -f Green
#Cleanup List Templates in source and destination sites
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/Marketing"
$DestinationSiteURL = "https://crescent.sharepoint.com/sites/HR"
#Call the function to copy libraries to another site
Copy-PnPAllLibraries -SourceSiteURL $SourceSiteURL -DestinationSiteURL $DestinationSiteURL
To copy a single document library to another site collection, use: How to copy a document library to another site in SharePoint Online using PowerShell?
Thanks
is it possible to set up a csv file with source folders and destination folders to copy multiple folders from one site to other sites?
I have to accommodate a full data restructure.
1. I need to copy libraries from one tenant to another as well as part of a migration. Currently looking at Sharegate but would like to do it using powershell for free if possible…
Is there any way to do this but among different tenants? I need to copy a specific set of files from different libraries from one tenant to another one, unfortunately copy-pnpfile cmdlet doesn’t support this 🙁 I hope you can shed some ideas here. Thanks in advance!