Copy a SharePoint Online list from one tenant to another

Copy a SharePoint Online list from one tenant to another

Have you ever heard this question from a client or one of your colleagues:

I have a SharePoint List with Data on "Tenant A" and I need to move it to "Tenant B". Do you know how to move that quickly?

Just a simple list of Data someone wants to move from One Site to another. For such simple request the solution has, historically, always been anything but simple.

However, with the PowerShell cmdlets from PnP-Powershell this request is anything but difficult ;-).

Prerequisites

Aside from the obvious set of SharePoint lists, Source- and Target-Tenant information and the right Admin-Role in each tenant, the only real prerequisite is to make sure you have PnP.PowerShell installed.

In this article, I am using the latest PnP.PowerShell-Module. To get started with your machine, you can either quickly follow the instructions here or use the following command in PowerShell:

Install-Module -Name PnP.PowerShell

How to do it

Let's assume, you created a SharePoint List which has a multiple lookup-column. You also want to copy the SharePoint Lists which provide the data for the look-up columns. The solution is pretty straightforward. We’re basically going to create a PnP site template, add our list data to it, and then apply that template to our target site.

Step 1 - Connect to the source site

First thing we need to do is connect to the source-site. Simply replace the following two parts of the command with your information:

  • sourcetenant --> Name of the tenant which contains the relevant SharePoint site
  • sourcesite --> Name of the SharePoint site which contains the lists
## Step 1: Connect to Source Site
Connect-PnPOnline -Url https://sourcetenant.sharepoint.com/sites/sourcesite/ -Interactive

Step 2 - Create the PnP template

Once connected, we need to provide the names of the SharePoint lists we want to copy. A template for the lists will be generated and stored in an XML-File at the path you specified (by not providing a path, the xml-file will be stored in the current path of your powershell-session).

## Step 2: Create the Template (Due to a lookup-field in the main list, we have to export all dependent lists too. (4 in Total)) 
Get-PnPSiteTemplate -Out Lists.xml -ListsToExtract “LIST_1”, “LIST_2”, "LIST_3", "LIST_n" -Handlers Lists

Step 3 - Get the data from the list

To get the data we will populate our list instances with actual list items. The following command needs to be executed for each list. Please ensure you use the same file path as in step 2 ;-)

## Step 3: Get the List Data for each list 
Add-PnPDataRowsToSiteTemplate -Path Lists.xml -List “LIST_1”
Add-PnPDataRowsToSiteTemplate -Path Lists.xml -List “LIST_2”
Add-PnPDataRowsToSiteTemplate -Path Lists.xml -List “LIST_3”
Add-PnPDataRowsToSiteTemplate -Path Lists.xml -List “LIST_n”

Step 4 - Connect to target site

If you followed the previous steps, you should now have all the required information to copy your SharePoint lists in a file named "Lists.xml". Now let's connect to the target location. As under Step 1, please replace the following two parts of the command with your information:

  • sourcetenant --> Name of the tenant which will contains the target-site
  • sourcesite --> Name of the SharePoint site which will get the lists
## Step 4: Connect to Target Site
Connect-PnPOnline -Url https://targettenant.sharepoint.com/sites/targetsite/ -Interactive

Step 5 - Apply the extracted PnP Template

We stored the template in the xml-file "Lists.xml". By using the following command, we will apply the template to the target-site we connected in "step 4".

## Step 5 Apply the Template
Invoke-PnPSiteTemplate -Path Lists.xml

Conclusion

Wasn't that easy? :-) Ok, open cards... the scenario was not a difficult one. But does it always have to be tricky? ;-) I use the commands above often when moving LogicApps or PowerAutomate flows from one tenant to another (since in many cases SharePoint Lists are used to store data... I know, Dataverse is actually the way to go). But since there is no out-of-the-box function in the GUI, using PnP.PowerShell is pretty neat.

Did you find this article valuable?

Support Mirco Ing{enito.ch} by becoming a sponsor. Any amount is appreciated!