SharePoint Online: Copy All Document Libraries to Another Site using PowerShell

Requirement: Copy All Document Libraries to another Site collection in SharePoint Online.
sharepoint online copy document library to another site powershell

PowerShell to Copy Document Libraries from One Site to Another Site Collection in SharePoint Online:
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 -UseWebLogin 

#Get all document libraries
$SourceLibraries =  Get-PnPList | Where {$_.BaseType -eq "DocumentLibrary" -and $_.Hidden -eq $False}

#Connect to the destination site
Connect-PnPOnline -URL $DestinationSiteURL -UseWebLogin

#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 its 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 -UseWebLogin 

#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 -UseWebLogin

#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 its 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 along with their settings and metadata columns to destination site.
Make sure you have enabled custom script in SharePoint Online prior running this script! Otherwise, you'll end up in error "Access denied. You do not have permission to perform this action or access this resource." How to Enable Custom Script in SharePoint Online?
#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 -UseWebLogin -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 -UseWebLogin -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, "", $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?

No comments:

Please Login and comment to get your questions answered!

Powered by Blogger.