Copying SharePoint Sites using PnP PowerShell

Loading

Copying a SharePoint site involves duplicating its structure, lists, libraries, permissions, and content to a new destination. PnP PowerShell helps automate this process efficiently.

What You’ll Learn

Exporting a SharePoint site’s structure
Creating a new SharePoint site as a copy
Copying lists, libraries, and their data
Transferring permissions and site settings


Step 1: Install & Connect to SharePoint Online

Ensure you have PnP PowerShell installed:

Install-Module -Name PnP.PowerShell -Scope CurrentUser -Force

Connect to the source SharePoint site:

$SourceSite = "https://yourtenant.sharepoint.com/sites/SourceSite"
Connect-PnPOnline -Url $SourceSite -Interactive

Successfully connected to the source site!


Step 2: Export the SharePoint Site Structure

We start by exporting the structure (lists, libraries, and settings).

Save the Site Template as an XML File

$TemplatePath = "C:\Migration\SiteTemplate.xml"

# Export the site structure
Get-PnPSiteTemplate -Out $TemplatePath -Handlers Lists,Fields,ContentTypes,Security,Features

Write-Host "✅ Site structure exported to $TemplatePath"

The site structure is now saved!


Step 3: Create a New SharePoint Site (Destination)

Now, create a new site where the content will be copied.

Create a SharePoint Site:

$NewSiteUrl = "https://yourtenant.sharepoint.com/sites/DestinationSite"
$NewSiteTitle = "Destination Site"

# Create a new Communication site
New-PnPSite -Type CommunicationSite -Title $NewSiteTitle -Url $NewSiteUrl -Owner "admin@yourtenant.onmicrosoft.com"

Write-Host "✅ New site created: $NewSiteUrl"

The new SharePoint site is ready!


Step 4: Apply the Exported Template to the New Site

Now, apply the exported XML template to the new site.

Apply the Site Template:

Connect-PnPOnline -Url $NewSiteUrl -Interactive

Apply-PnPSiteTemplate -Path $TemplatePath

Write-Host "✅ Site template applied successfully!"

The new site now matches the old one’s structure!


Step 5: Copy Lists and Libraries with Data

After applying the template, we need to copy the list and document library contents.

Copy All Lists

$Lists = Get-PnPList | Where-Object { $_.Hidden -eq $false }

foreach ($List in $Lists) {
$ListTitle = $List.Title
$Items = Get-PnPListItem -List $ListTitle

foreach ($Item in $Items) {
Add-PnPListItem -List $ListTitle -Values $Item.FieldValues
}

Write-Host "✅ Copied list: $ListTitle"
}

All lists and their data are copied!


Copy Document Libraries

$Libraries = Get-PnPList | Where-Object { $_.BaseType -eq "DocumentLibrary" -and $_.Hidden -eq $false }

foreach ($Library in $Libraries) {
$Files = Get-PnPFile -List $Library.Title -AsListItem

foreach ($File in $Files) {
$FileUrl = $File["FileRef"]
$FileName = $File["FileLeafRef"]

# Download file from source
Get-PnPFile -Url $FileUrl -Path "C:\Migration\Files" -Filename $FileName -AsFile -Force

# Upload to destination
Add-PnPFile -Path "C:\Migration\Files\$FileName" -Folder $Library.Title
}

Write-Host "✅ Copied library: $($Library.Title)"
}

All document libraries and files are copied!


Step 6: Copy Permissions

To ensure users retain the same access levels, copy the site permissions.

Export Permissions from the Source Site

$PermissionsPath = "C:\Migration\SitePermissions.csv"

$Groups = Get-PnPGroup

$Permissions = @()
foreach ($Group in $Groups) {
$Roles = Get-PnPGroupPermissions -Identity $Group.Id
$Permissions += [PSCustomObject]@{
GroupName = $Group.Title
Permissions = ($Roles | ForEach-Object { $_.Name }) -join ", "
}
}

$Permissions | Export-Csv -Path $PermissionsPath -NoTypeInformation
Write-Host "✅ Site permissions exported!"

Import Permissions to the Destination Site

$Permissions = Import-Csv -Path $PermissionsPath

foreach ($Permission in $Permissions) {
$GroupName = $Permission.GroupName
$Roles = $Permission.Permissions -split ", "

# Create the group if not exists
$ExistingGroup = Get-PnPGroup | Where-Object { $_.Title -eq $GroupName }
if (-not $ExistingGroup) {
New-PnPGroup -Title $GroupName -Owner "admin@yourtenant.onmicrosoft.com"
Write-Host "✅ Created group: $GroupName"
}

# Assign permissions
foreach ($Role in $Roles) {
Set-PnPGroupPermissions -Identity $GroupName -AddRole $Role
}

Write-Host "✅ Assigned permissions to: $GroupName"
}

Permissions are successfully transferred!


Step 7: Automate the Process (Optional)

To schedule automatic site copying, use Windows Task Scheduler:

1️⃣ Open Task Scheduler
2️⃣ Create a New Task
3️⃣ Set Trigger to run at a fixed time
4️⃣ Use the following PowerShell command:

powershell.exe -ExecutionPolicy Bypass -File "C:\Migration\CopySite.ps1"

Your site copy process is now automated!

Leave a Reply

Your email address will not be published. Required fields are marked *