SharePoint Online: Copy Site Pages from One Site to Another using PowerShell

Requirement: Copy site pages to another site in SharePoint Online.

SharePoint Online: How to Copy a Page to Another Site Collection?

Do you need to copy a page from one SharePoint Online site collection to another? Maybe you want to duplicate a page for testing purposes or create a similar page in another site collection. This article will show you how to copy pages in SharePoint Online using PowerShell.

We wanted to copy a modern page from one site to another site in SharePoint Online. The “Copy to” option doesn’t support copying site pages from one site to another.

sharepoint online copy page to another site collection

Luckily we’ve PnP PowerShell available to copy a modern page to another site:

#Parameters
$SourceSiteURL = "https://crescent.sharepoint.com/sites/marketing"
$DestinationSiteURL = "https://crescent.sharepoint.com/sites/branding"
$PageName =  "About.aspx"

#Connect to Source Site
Connect-PnPOnline -Url $SourceSiteURL -Interactive

#Export the Source page
$TempFile = [System.IO.Path]::GetTempFileName()
Export-PnPPage -Force -Identity $PageName -Out $TempFile

#Import the page to the destination site
Connect-PnPOnline -Url $DestinationSiteURL -Interactive
Invoke-PnPSiteTemplate -Path $TempFile

This PowerShell script exports and imports a given page and all its web parts, contents, etc. How about copying all pages from one site to another?

PowerShell to Copy All Site Pages to Another Site in SharePoint Online

To copy all pages to another site collection, use this PowerShell script.

#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

#Export all pages from the source
$TempFile = [System.IO.Path]::GetTempFileName()
Get-PnPSiteTemplate -Out $TempFile -Handlers PageContents -IncludeAllClientSidePages -Force

#Import the page to the destination site
Connect-PnPOnline -Url $DestinationSiteURL -Interactive
Invoke-PnPSiteTemplate -Path $TempFile

This will backup all pages in the “Site Pages” library to an XML file with all the artifacts from pages and import them to the given destination site. We can use this method to backup-restore site pages within the same tenant or between different tenants in SharePoint Online.

Salaudeen Rajack

Salaudeen Rajack - Information Technology Expert with Two-decades of hands-on experience, specializing in SharePoint, PowerShell, Microsoft 365, and related products. He has held various positions including SharePoint Architect, Administrator, Developer and consultant, has helped many organizations to implement and optimize SharePoint solutions. Known for his deep technical expertise, He's passionate about sharing the knowledge and insights to help others, through the real-world articles!

31 thoughts on “SharePoint Online: Copy Site Pages from One Site to Another using PowerShell

  • Hi, thanks again for this script.
    I am experiencing an issue:
    “Invoke-PnPSiteTemplate : The JSON value could not be converted to System.Int32. Path: $.position.sectionIndex | LineNumber: 0 | BytePositionInLine: 107.”

    Can you help me please ?
    Thank you again.

    Reply
  • Hi,

    I’m getting an ‘Export-PnPPage: The remote server returned an error: (404) Not Found.’ error after the Export-PnPPage line; the page definitely exists; any idea what might cause this?
    Thanks

    Reply
    • The identity should be just the page name like “about.aspx” instead of any path “sitepages/about.aspx”.

      Reply
  • Is there an SPO PowerShell equivalent to this script?

    Reply
  • Hi,

    Is this applicable to exporting SharePoint online site pages to another SharePoint Site’s tenant?

    Regards,

    Reply
  • The script works fine on all Site Pages, but is there a way to copy only the News Pages and retain the Users and Date creation

    Reply
  • Does this work between tenants as well or is this even possible?

    Reply
    • I can’t see how using a script like this since it won’t handle changing authentication to a different account, let alone tenant, mid-way through. You’re best bet would be a 3rd party tool like ShareGate.

      Reply
    • Yes this works fine for me across tenants.

      Reply
      • Hi, Are you using pnp powershell? If so, what version?

        Reply
  • This is amazing! Works great other than any way to also copy over Site Assets? Images don’t appear and I have to move over the page Site Assets folder over manually. Extra issue there is that folder doesn’t always have all the images to begin with (say if the page is a copy of another page, etc). Heck often I’m not even sure which folder is the right one, if the page was ever renamed (often the case). So I’m first digging through all the Site asset folders to find the right one, copying it over, and then manually download any missing images and then reupload them on the new site and then edit each page. Takes ages. So would be awesome if there is some commands to also just download and copy over the assets/images off each page and copy over. Or just including the Site Assets folder would at least help a bit.

    Reply
    • Hi Jeremy, I just used this process and had the same issue you describe for images. Were you ever able to resolve this?

      Reply
  • Still working! Awesome

    Reply
  • PSVersion 5.1.19041.1682
    BuildVersion 10.0.19041.1682

    Running the script with the sample script on my sharepoint online domain
    I’m getting a prompt that the parameter -Interactive is not recognised:
    Neither does it run if I’d leave out the-Interactive parameter
    What am I doing wrong?

    Connect-PnPOnline : A parameter cannot be found that matches parameter name ‘Interactive’.
    At line:6 char:39
    + Connect-PnPOnline -Url $SourceSiteURL -Interactive
    + ~~~~~~~~~~~~
    + CategoryInfo : InvalidArgument: (:) [Connect-PnPOnline], ParameterBindingExc
    eption
    + FullyQualifiedErrorId : NamedParameterNotFound,PnP.PowerShell.Commands.Base.ConnectOn
    line

    Get-PnPSiteTemplate : The term ‘Get-PnPSiteTemplate’ is not recognized as the name of a cmdl
    et, function, script file, or operable program. Check the spelling of the name, or if a path
    was included, verify that the path is correct and try again.
    At line:10 char:1
    + Get-PnPSiteTemplate -Out $TempFile -Handlers PageContents -IncludeAll …
    + ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : ObjectNotFound: (Get-PnPSiteTemplate:String) [], CommandNotFo
    undException
    + FullyQualifiedErrorId : CommandNotFoundException

    Connect-PnPOnline : A parameter cannot be found that matches parameter name ‘Interactive’.
    At line:13 char:44
    + Connect-PnPOnline -Url $DestinationSiteURL -Interactive
    + ~~~~~~~~~~~~
    + CategoryInfo : InvalidArgument: (:) [Connect-PnPOnline], ParameterBindingExc
    eption
    + FullyQualifiedErrorId : NamedParameterNotFound,PnP.PowerShell.Commands.Base.ConnectOn
    line

    Invoke-PnPSiteTemplate : The term ‘Invoke-PnPSiteTemplate’ is not recognized as the name of
    a cmdlet, function, script file, or operable program. Check the spelling of the name, or if
    a path was included, verify that the path is correct and try again.
    At line:14 char:1
    + Invoke-PnPSiteTemplate -Path $TempFile
    + ~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : ObjectNotFound: (Invoke-PnPSiteTemplate:String) [], CommandNo
    tFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

    Reply
  • This is no longer working. Please update script

    Reply
      • I’m also finding this doesn’t work anymore. I keep getting a ‘Method not found’ error. If I replace ‘PageContents’ with ‘Pages’ it runs without any errors, however it doesn’t copy any pages over to the new site.
        Not sure if something has changed in SharePoint or PnP, however I’ve gone back as far as version 1.5 and I’m still seeing the error. Any help would be appreciated!

        Reply
        • Are you running this in VSCode? If so, try PowerShell ISE or PowerShell. I ran into the same method error with PageContents in VSCode. It might be similar to this issue:
          https://github.com/microsoft/vscode/issues/120026

          Reply
      • Hi,

        thanks for this great article! In the first step, I had a problem too, with this script.

        Was trying to copy pages that were not present in the destination site collection. But the process was always failing with an “404 file not found”.
        I took a closer look at the exported template and noticed that there is an ‘override’ parameter for each ClientSidePage element, which was set to ‘true’ for me.
        I have changed the parameter to ‘false’ by manually editing the file. After that the pages were indeed created without errors!
        It seems, that the cmdlet is expecting the exported page as present, when the ‘override’ parameter is set to ‘true’.

        I don’t know if this is a bug or something. Anyways, I was able make it working 🙂

        By the way, I am using version 1.12.0 of the PnP.PowerShell

        Reply
      • I’m not in front of my laptop to test this, but you might be able to store each tenant’s creds by assigning variables to two Connect-PnPOnline statements. Use the -ReturnConnection parameter in those statements, and you might also need to use -DeviveLogin instead of -Interactive. When executing Connect-PnPOnline with -DeviceLogin, it’ll prompt you to go to a Microsoft page to authenticate the connections. If you’re at work and your Edge browser SSO’s with an account you don’t want to use on the other tenant (ex Tenant B), open Chrome and login to Tenant B first, then perform the authentication. Similarly, use another browser logged into Tenant A to perform the authentication for that tenant. After that, add the variables you assigned to the Connect-PnPOnline’s in the -Connection parameter of any commandlets you want to execute on the tenants.

        Reply
  • I’ve got version 1.10.0 of Pnp.Powershell installed and am getting the following error when I run a script which I am attempting to get details of a customised modern SharePoint Teams Site Home Page to use as a template for the creation of other Sites’ Home Pages.

    Export-PnPPage : Object reference not set to an instance of an object
    At C:\Users\SteveWedge\OneDrive\Powershell\SharePoint\CopyITTeamSiteHomePage.ps1:11 char:1
    + Export-PnPPage -Force -Identity $PageName -Out $TempFile -PersistBran …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [Export-PnPPage], NullReferenceException
    + FullyQualifiedErrorId : System.NullReferenceException,PnP.PowerShell.Commands.Provisioning.Tenant.ExportPage

    The script I am running is not complex and at one point today did complete execution and produce some output, although the file which was created did not actually include the full definition of the page, webparts, etc. (see attached) so wasn’t very helpful.

    Since that 1 successful execution of the Export-PnPPage cmdlet, every subsequent attempt has failed. I’d rather not have to build out the other 10 Site Home pages manually, so am hoping you can shed some light on what’s wrong with this, or suggest an alternative approach.

    $SourceSiteURL = “https://companyname.sharepoint.com/teams/XYZ-GLBL-IT-Infrastructure-Operations”
    $DestinationSiteURL = “https://companyname.sharepoint.com/teams/XYZ-GLBL-IT-Infrastructure-EMEA”
    $PageName = “Home.aspx”
    #Connect to Source Site
    Connect-PnPOnline -Url $SourceSiteURL -Interactive
    #Export the Source page
    $TempFile = [System.IO.Path]::GetTempFileName()
    Export-PnPPage -Force -Identity $PageName -Out $TempFile -PersistBrandingFiles
    #Import the page to the destination site
    [tmp2AA9.txt](https://github.com/pnp/powershell/files/8622395/tmp2AA9.txt)

    Connect-PnPOnline -Url $DestinationSiteURL -Interactive
    Invoke-PnPSiteTemplate -Path $TempFile

    Reply
  • WARNING: Please use ‘Export-PnPPage’. The alias ‘Export-PnPPage’ will be removed in the 1.5.0 release

    Reply
  • script work great. However, can you include all the version history?

    Reply
  • Hi there,

    sorry to say but this page needs to be updated.
    Get-PnPProvisioningTemplate is not existing anymore in PnP.Powershell

    Kind regards,
    Dave

    Reply
    • Yes! If you have upgraded to New PnP PowerShell module, PnP.PowerShell, Get-PnPProvisioningTemplate cmdlet is replaced with “Get-PnPSiteTemplate” and “Apply-PnPProvisioningTemplate” is replaced with “Invoke-PnPSiteTemplate”.

      Reply
  • These are great, thanks for putting in the time to share!

    Reply
  • Hi,
    thanks for your work.

    Is it posible that I export sides by the last modification date?
    E.g.: I would like to export all sides modified in the time between 21.12. – 27.12.

    best regards
    Raphael

    Reply

Leave a Reply

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