Copy documents in SharePoint with PowerShell (Copy-PnPFile)

PnP PowerShell provides a comprehensive set of PowerShell commands to help manage SharePoint Online. Recently I needed to remap a lot of content from an old library structure into a new structure as part of a SharePoint modernisation project. Using a migration tool would have required a lot of labour intensive content remapping, so a different approach was needed.

This PowerShell script moves files between folders in a source folder into a destination. It uses a CSV file as an input, allowing the content mapping to be done before running the script to copy the source content to a destination.

Script Description:

  • Read the input CSV file
  • For each line in the CSV file – get the files in the folder (Get-PnPFileInFolder)
  • For each file in the folder – copy the file to the destination (Copy-PnPFile)
#Read CSV file
# The file needs two columns separated by a comma:  source, destination
# The source and destination are folder path (don't include a filename)
#
#Authenticate
connect-PnPOnline -url https://yourtenant.sharepoint.com/sites/sourcesite -useweblogin
#
#Read CSV data file
$folders = Import-CSV C:\temp\filecopy.csv -Header SourceFolder, DestinationFolder
# Copy folders 
foreach($folder in $folders)
{
  $SourceURL = $folder.SourceFolder
  $DestinationURL =  $folder.DestinationFolder
  write-host $SourceURL
  write-host $DestinationURL
  #Get Files in Source Folder and Copy to Destination. Include metadata values.
  $Files = Get-PnPFileInFolder -Identity $SourceURL -Includes TimeLastModified, ModifiedBy
# **** Authenticate destination site here if it is different to the source
# connect-PnPOnline -url https://yourtenant.sharepoint.com/sites/destinationsitename -useweblogin
  foreach($File in $Files)
   {
	 $SourceFileURL + "/" + $File.name
	 write-host "copying file:" $SourceFileURL
	 Copy-PnPFile -SourceUrl $SourceFileURL -TargetUrl $DestinationURL -Overwrite -Force
    }
}

In the mapping CSV file, you can include site URL and paths including folders. In this example script I copy all files in the source folder into a destination folder, excluding any subfolders. This means you can remap source folders into new destination folders.

In my example above, I use a two column CSV file. Column A = Source Folder and Column B is the destination folder path in the destination library. In my case I am copying all files from the source folder into the destination. The script could be modified to use the full path if needed.

If you destination Library is in a different site to the source Library, then you need to authenticate the destination site, otherwise Copy-PnPFile will give an error. PowerShell won’t prompt for credentials if the site is already authenticated.

It is also possible to update the metadata associated with the file using Set-PnPListItem. If you want to retain the source files modified and modified by values, add this line after the file has copied.

I notice that the Copy-PnPFile command updates the ID of the item in the library but it can take 2-3 seconds to get the new value with Get-PnPFile. If you see the previous ID of the document, you can put a small delay in the script to give time for the value to update.

#Note that $File = the source file. See code above
#Get metadata from the Destination file - we need to get the ID value
$DestinationFileName = $DestinationURL + "/" + $File.name
$NewFile = Get-PnPFile -Url $DestinationFileName -AsListItem 

#Update the metadata on the new file with the modified and modified by source values
#Note the metadata columns must be included in the Get-PnPFileInFolder commandlet. 

Set-PnPListItem -List "LibraryName" -Identity $NewFile.ID -Values @{"Modified" = $File.TimeLastModified; "Editor" = $File.ModifiedBy.Email}   

Depending on the file size and number of versions. This script will copy files at a rate of 3000-5000 per hour.

This script can be modified to exclude versions by adding the ” -IgnoreVersionHistory” parameter on the Copy-PnPFile command.

Learn more about PnP PowerShell.


Discover more from SharePoint Moments

Subscribe to get the latest posts sent to your email.

3 comments

Leave a reply to gregsoc Cancel reply