Getting error "File not found" while trying to copy file to target location using command Copy-PnPFile.
File specified in parameter SourceUrl should be succesfully copied to target location specified in parameter TargetUrl.
Note. This command was working earlier.
Command throws errors like this:
Copy-PnPFile : File Not Found.
at run.ps1: line 253
+ Copy-PnPFile
+ ____________
+ CategoryInfo : WriteError: (:) [Copy-PnPFile], ServerException
+ FullyQualifiedErrorId : EXCEPTION,SharePointPnP.PowerShell.Commands.Files.CopyFile
Connect-PnPOnline command;Copy-PnPFile. Specify server relative URL of file as parameter -SourceUrl. Specify server relative URL of destination folder as parameter TargetUrl. Example:copy-pnpfile -SourceUrl "/sites/a1/Shared Documents/Document 1.docx" -TargetUrl "/sites/a1/Shared Documents/dest"
Note. This error is thrown when copying to different sites/site collections ALSO.
(you can retrieve this by executing Get-Module -Name *pnppowershell* -ListAvailable)
Thank you for reporting this issue. We will be triaging your incoming issue as soon as possible.
After debugging code in master branch I have identified possible cause of the problem in file CopyFile.cs file. Lines: 117-118
File file = _sourceContext.Web.GetFileByServerRelativeUrl(SourceUrl);
Folder folder = _sourceContext.Web.GetFolderByServerRelativeUrl(SourceUrl);
Error is thrown when trying to get folder using URL of the file. Possible that this code was working earlier and now SharePoint API behavior has changed.
I have the same issue since updated to May 2019 Intermediate Release 3.
Same here. I have a script using Copy-PnPFile that was working on Friday (05/24/2019) and didn't work anymore on Sunday (05/26/2019).
Didn't do any update of PnP PowerShell, was on version 3.9.1905.2. Update to version 3.9.1905.3 didn't make any difference.
I guess something changed on SharePoint side. See also https://twitter.com/HeSteIT/status/1132689593411751941
We have multiple satellite location and facing similar issue in only one location. The code was working and all of a sudden it stopped working on one tenant.
We have multiple satellite location and facing similar issue in only one location. The code was working and all of a sudden it stopped working on one tenant.
That suggests an API change for some tenants instead of a problem with the cmdlet itself.
I鈥檝e encountered this as well with our provisioning scripts. However, when I used the Copy-PnPFile line in isolation yesterday, it worked.
Just tested Copy-PnPFile in isolation, worked again for me too.
Will test my script later today.
Yes seems to work again, so probably a temporary issue from the API.
Yes seems to work again, so probably a temporary issue from the API.
We have been seeing this issue for more than a week, is there any way to check/fix that API change you suggest?
We are having the same issue. Unable to copy files with the same error message.
Same error here on 3.10.1906.0. Unable to copy files also they are found prior to confirm.
We had the same issue. When we copy directories works but with a file dosen't work.
exactly same thing... copy directories works but with a file doesn't work.
Same issue as mention from other postings - using 3.10.1906.0 - 2 days ago it stopped working - prior to that it worked as expected
Same issue on two different tenants.
Started 3 days ago on the first tenant, then yesterday on second.
Have attempted different permutations of argument -SourceUrl, to no effect.
Same issue here as well (using 3.10.1906.0). Copying a whole directory works, although it also tries to copy the views etc. Copying a single file from A to B doesn't work anymore, while it sure did work before.
So we are getting several persons with the same issue. Now I want to add myself in that row.
I want to copy a file from the current web to another site.
Copy-PnPFile -SourceUrl "SiteAssets/MultipleDownloadFiles/js/libs/filesaverjs/FileSaver.min.js" -TargetUrl "/sites/Bau13/SiteAssets/FileSaver.min.js" -OverwriteIfAlreadyExists -Force -Verbose
I get the error that the file is not found. However when I use Find-PnPFile the file was found.
Find-PnPFile -Match FileSaver.min.js

Has anybody an idea about a solution?
In Matthew chapter 21, vers 28 to 30, there's an account of a man that asks his two sons to go work in the wineyard. The one says yes, but doesn't go. The other one says no, but regrets and gets the job done.
Now, I'm not trying to teach you about the Bible, but I found a crazy work around that reminded me on the story.
Here's what I found: If you use the file objects CopyTo function it silently fails and doesn't do the job.
But if you after that uses Copy-PnPFile it too fails verbally with the File not found error, BUT now it does the job. Don't ask me why.
Sample script:
$files = Get-PnPFolderItem -FolderSiteRelativeUrl $sourceFolder -ItemType File
foreach ($file in $files) {
$fileURL = $sourceFolder + "/" + $file.Name
$targetFileUrl = $newFolderPath + "/" + $file.Name
#Crazy workaround to get files copied into a library/folder structure
$file.CopyTo($targetFileUrl, $true)
#Says Yes (gives no error), but doesn't do the job
try {
Copy-PnPFile -SourceUrl $fileURL -TargetUrl $targetFileUrl -Force -OverwriteIfAlreadyExists -ErrorAction SilentlyContinue
#Says No (gives error) but somehow gets it done anyway
}
catch {
$Error.Clear()
}
}
Adding the '-ErrorAction SilentlyContinue' will keep Copy-PnPFile happy and your script will run.
Now another observation I made is that if you use Move-PnPFile with a single file it works as expected, copies the file, but obviously deletes the source.
If any PnP/Microsoft persons want's some further details to track down this error you are welcome to contact me. The sooner the better.
@JesperGSimonsen I did some additional testing with your script:
I think, that you did miss to trigger Invoke-PnPQuery so that the CSOM changes get transferred to the server. In your case, Copy-PnPFile replaces the missing .ExecuteQuery() method call.
As soon as the Copy-PnPFile cmdlet is called, there will be a .ExecuteQueryRetry() triggered:
https://github.com/SharePoint/PnP-PowerShell/blob/4617f78076b6d59b2241e50bf394bc1f24171f19/Commands/Files/CopyFile.cs#L119
which will resolve in this call of .ExecuteQuery():
https://github.com/SharePoint/PnP-Sites-Core/blob/ca8da63616f5d01aa6cbc67dae4096d4c9f0afa9/Core/OfficeDevPnP.Core/Extensions/ClientObjectExtensions.cs#L114
Please find attached a version of your workaround, that works repeatedly on my end:
Connect-PnPOnline -Url https://<Tenant>/sites/<SiteCollection>/
# source library
$sourceFolder = "Shared Documents"
# target library
$newFolderPath = "Target"
$files = Get-PnPFolderItem -FolderSiteRelativeUrl $sourceFolder -ItemType File
# Adding some context information
$currentTime = Get-Date
Write-Host "This run is named with $($currentTime.Ticks)"
foreach ($file in $files) {
$fileURL = $sourceFolder + "/" + $file.Name
$targetFileUrl = "$($newFolderPath)/$($currentTime.Ticks)$($file.Name)"
$file.CopyTo($targetFileUrl, $true)
Write-Host $targetFileUrl
}
Invoke-PnPQuery
This doesn't solve the original problem. It's only meant as a work-around.
I'm experiencing the same issue as well. I'm reusing a script that worked just weeks ago.
The $file.CopyTo method doesn't seem to work for me, potentially because I'm copying from one Web to another Web within the same Site Collection. No error messages are reported but the copy does not happen.
I tried running the ExecuteQuery using the shared site collection root context ($ctxRoot), the source context ($ctxSource), and the target context ($ctxTarget) and none of them seemed to make a difference. Any suggestions would be appreciated.
For a copy across sites you would need to open the file as file stream (.OpenBinaryStream()) and create a new file in your target directory via CSOM.
The whole issue seems to be caused by this line of code - as already mentioned by @NerijusV
Using SourceUrl in this line will result in an error. I did several tests with valid paths for files and folders and come to the conclusion, this method only works with a valid folder path.
Same applies if the source is only a folder. Then the error would be triggered in line 117.
@andikrueger
Your script works fine if I copy a file within a site collection. Nevertheless I need to copy it between two site collections.
I tried something like this but without success.
$ConnectionSource = Connect-PnPOnline -Url https://<Tenant>/sites/<Source> -Credentials $creds -ReturnConnection
$ConnectionTarget = Connect-PnPOnline -Url https://<Tenant>/sites/<Target> -Credentials $creds -ReturnConnection
$destFolder = Get-PnPFolder -Url "DocTemplates" -Connection $ConnectionTarget
Returns only one file in my case:
$file = Get-PnPFolderItem -FolderSiteRelativeUrl "DocTemplates" -ItemType File -Connection $ConnectionSource
Tried several things:
$destFolder.Files.Add($($file.Name), $($file.OpenBinaryStream())
$destFolder.Files.Add("doc.docx",$($file.OpenBinaryStream()))
$stream = $file.OpenBinaryStream()
$destFolder.Files.Add("DocTemplates/doc.docx",$stream)
I am not sure whether the C# source is implemented completely but if so this should work I guess. I get the following error:

Error message in English: There is no overload for "Add" with arguments number "2".
You need to run ExecuteQuery on your source context. Otherwise your Stream will be empty.
That's another mistake I made.
I guess I found my inital mistake, The method is implemented different in CSOM than in SSOM.
I need to create a FileCreationInformation.

There I can place a ContentStream with type: System.IO.Stream. But the type of the stream of the file is another.

When I search for a converting method I only found the option to "iterate through the stream" and copy it into another. That can't be a solution...
This one here doesn't work for me although it sounds great: https://blogs.technet.microsoft.com/fromthefield/2014/02/19/office-365-powershell-script-to-upload-files-to-a-document-library-using-csom/
UPDATE
Finally got a solution. Going to post it in a few minutes...
My solution to copy files between site collections. Of course there is space for improvement...
$ConnectionSource = Connect-PnPOnline -Url <Tenant>/sites/source -Credentials $creds -ReturnConnection
$ConnectionTarget = Connect-PnPOnline -Url <Tenant>/sites/target -Credentials $creds -ReturnConnection
$targetFolder = Get-PnPFolder -Url "DocTemplates" -Connection $ConnectionTarget
$file = Get-PnPFolderItem -ItemType File -FolderSiteRelativeUrl "DocTemplates" -Connection $ConnectionSource
$ContextTarget = $ConnectionTarget.Context
$stream = $file.OpenBinaryStream()
$file.Context.ExecuteQuery()
$tmpStream = New-Object System.IO.MemoryStream
$stream.Value.CopyTo($tmpStream)
$tmpStream.Seek(0,"Begin")
$creationInfo = New-Object Microsoft.SharePoint.Client.FileCreationInformation
$creationInfo.Overwrite = $true
$creationInfo.ContentStream = $tmpStream
$creationInfo.Url = "Doc.docx"
$ContextTarget.Load($targetFolder.Files)
$ContextTarget.ExecuteQuery()
$upload = $targetFolder.Files.Add($creationInfo)
$ContextTarget.Load($upload)
$ContextTarget.ExecuteQuery()
@hekr09
My solution to copy files between site collections. Of course there is space for improvement...
$ConnectionSource = Connect-PnPOnline -Url <Tenant>/sites/source -Credentials $creds -ReturnConnection $ConnectionTarget = Connect-PnPOnline -Url <Tenant>/sites/target -Credentials $creds -ReturnConnection $targetFolder = Get-PnPFolder -Url "DocTemplates" -Connection $ConnectionTarget $file = Get-PnPFolderItem -ItemType File -FolderSiteRelativeUrl "DocTemplates" -Connection $ConnectionSource $ContextTarget = $ConnectionTarget.Context $stream = $file.OpenBinaryStream() $file.Context.ExecuteQuery() $tmpStream = New-Object System.IO.MemoryStream $stream.Value.CopyTo($tmpStream) $tmpStream.Seek(0,"Begin") $creationInfo = New-Object Microsoft.SharePoint.Client.FileCreationInformation $creationInfo.Overwrite = $true $creationInfo.ContentStream = $tmpStream $creationInfo.Url = "Doc.docx" $ContextTarget.Load($targetFolder.Files) $ContextTarget.ExecuteQuery() $upload = $targetFolder.Files.Add($creationInfo) $ContextTarget.Load($upload) $ContextTarget.ExecuteQuery()
This doesn't seem to work on Azure Automation script. Fails on upload. Works like a charm on my machine though.
I will look into fixing this issue. Hope I鈥檒l get it done soon.
It was working again for me and then it doesn't work again.
...when will this be merged? :-)
Thank you Andi for fixing!
Same issue with me... File not found when copying from a site to another site. The script worked in the past. 3.9.1905.3
Thank you Andi for fixing! Waiting for PR to be merged! :)
I am able to write the file returned from Get-PnPFile to disk using Set-Content, and then use Add-PnPFile to grab that local file and push it to a SharePoint site.
Just FYI the workaround from @HeKr09 worked in Azure Automation for me.
I will look into fixing this issue. Hope I鈥檒l get it done soon.
Hi Andy
Is this merged into..I am still getting "File not Found error" while using it from SharePoint Online PowerShell
It鈥檚 not merged yet. @wobba @erwinvanhunen Any chance you could merge this PR?
I'll review the PR and get on it.
@wobba Is this merged?
Yes, 15 days ago.
@wobba , i have updated to 3.12.1908.1 but still getting error. can you share the version no?
Should be in the august release which was released 2 days ago. 3.12.1908.1
Somehow it is not working for me. Is it working for anyone else?
Working for me.
Have you cleared out all other instances of PnP PowerShell to be on the safe side?
Yes i have reinstalled and restart my instance of pnp powershell.
I did a quick test and it works fine.
$source = "/sites/dev/Shared Documents/test.docx"
$target = "/sites/dev/Shared Documents/test_copy.docx"
Copy-PnPFile -SourceUrl $source -TargetUrl $target
For SharePoint Online:
Please do not replace whitespaces with %20. Copy-PnPFile uses the new Microsoft.SharePoint.Client.ResourcePath class. For more information see:
Supporting % and # in files and folders with the ResourcePath API
I am trying to copy data from user's one drive data to sharepoint site. Now i am getting "Copy-PnPFile : Cannot open file". Any idea on it.
@anmolsinghchauhan can you provide a sample command with full paths?
@wobba you can refer below link.
https://gcits.com/knowledge-base/transfer-users-onedrive-files-another-user-via-powershell/
Just in destination it is sharepoint site instead of specific destination user.
@anmolsinghchauhan Could you just run the following command, to see, if there are several PnP PowerShell Versions on your system?
PS C:\> Get-Module SharePointPnPPowerShellOnline -ListAvailable
Verzeichnis: C:\Program Files\WindowsPowerShell\Modules
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Binary 3.12.19... SharePointPnPPowerShellOnline {Add-PnPAlert, Add-PnPApp, Add-PnPClientSidePage, Add-PnPC...
Using the new version with the fix (as @andikrueger mention) is working fine for copying files
But copy (empty folders) that worked with e.g. the June 2019 version is failing (with the exact same code as previously) Error message: Copy-PnPFile : The directory is not a subdirectory of the root directory - haven't been digging deep in the source code yet - but anyone with the same issue ?
@frisla would be great if you could log this as a new issue.
@wobba done :)
Is this still an issue?
.I am still getting "File not Found error" while using it from SharePoint Online PowerShell
SharePoint Online PowerShell and PnPPowerShell are different modules.
Please download the latest PnPPowerShell and give it a try.
Thank you. Upgradring the PnP make the copy-pnpFile command to work.
is it possible to say since when the previous(3.8.1904.0) version had this issue?
Most helpful comment
I will look into fixing this issue. Hope I鈥檒l get it done soon.