I am trying to copy the Files and Folders with meta data from one library to another library,in SharePoint Online using powershell CSOM, i am getting this error
"Exception calling "ExecuteQuery" with "0" argument(s): "The operation has timed out."" It works more than half the time, but will often give me this error upon calling the ExecuteQuery() command:
this is my code
#Load SharePoint CSOM Assemblies
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
Function Copy-AllFilesWithMetadata
{
param
(
[Parameter(Mandatory=$true)] [Microsoft.SharePoint.Client.Folder] $SourceFolder,
[Parameter(Mandatory=$true)] [Microsoft.SharePoint.Client.Folder] $TargetFolder
)
Try {
#Get all Files from the source folder
$SourceFilesColl = $SourceFolder.Files
$SourceFolder.Context.Load($SourceFilesColl)
$SourceFolder.Context.ExecuteQuery()
#Iterate through each file and copy
Foreach($SourceFile in $SourceFilesColl)
{
#Get the source file
$FileInfo = [Microsoft.SharePoint.Client.File]::OpenBinaryDirect($SourceFolder.Context, $SourceFile.ServerRelativeUrl)
#Copy File to the Target location
$TargetFileURL = $TargetFolder.ServerRelativeUrl+"/"+$SourceFile.Name
[Microsoft.SharePoint.Client.File]::SaveBinaryDirect($TargetFolder.Context, $TargetFileURL, $FileInfo.Stream,$True)
#Copy Metadata field values
$SourceListItem = $SourceFile.ListItemAllFields
$SourceFolder.Context.Load($SourceListItem)
$SourceFolder.Context.ExecuteQuery()
#Get the new file created
$TargetFile = $TargetFolder.Context.Web.GetFileByServerRelativeUrl($TargetFileURL)
$TargetListItem = $TargetFile.ListItemAllFields
#Set Metadata values from the source
$Author =$TargetFolder.Context.web.EnsureUser($SourceListItem["Author"].Email)
$TargetListItem["Author"] = $Author
$Editor =$TargetFolder.Context.web.EnsureUser($SourceListItem["Editor"].Email)
$TargetListItem["Editor"] = $Editor
$TargetListItem["Created"] = $SourceListItem["Created"]
$TargetListItem["Modified"] = $SourceListItem["Modified"]
$TargetListItem.Update()
$TargetFolder.Context.ExecuteQuery()
Write-host -f Green "Copied File '$($SourceFile.ServerRelativeUrl)' to '$TargetFileURL'"
}
#Process Sub Folders
$SubFolders = $SourceFolder.Folders
$SourceFolder.Context.Load($SubFolders)
$SourceFolder.Context.ExecuteQuery()
Foreach($SubFolder in $SubFolders)
{
If($SubFolder.Name -ne "Forms")
{
#Prepare Target Folder
$TargetFolderURL = $SubFolder.ServerRelativeUrl -replace $SourceLibrary.RootFolder.ServerRelativeUrl, $TargetLibrary.RootFolder.ServerRelativeUrl
Try {
$Folder=$TargetFolder.Context.web.GetFolderByServerRelativeUrl($TargetFolderURL)
$TargetFolder.Context.load($Folder)
$TargetFolder.Context.ExecuteQuery()
}
catch {
#Create Folder
if(!$Folder.Exists)
{
$TargetFolderURL
$Folder=$TargetFolder.Context.web.Folders.Add($TargetFolderURL)
$TargetFolder.Context.Load($Folder)
$TargetFolder.Context.ExecuteQuery()
Write-host "Folder Added:"$SubFolder.Name -f Yellow
}
}
#Call the function recursively
Copy-AllFilesWithMetadata -SourceFolder $SubFolder -TargetFolder $Folder
}
}
}
Catch {
write-host -f Red "Error Copying File!" $_.Exception.Message
}
}
#Set Parameter values
$SourceSiteURL= Read-Host -Prompt 'Enter Source Site URL'
$TargetSiteURL= Read-Host -Prompt 'Enter Target Site URL'
$SourceLibraryName= Read-Host -Prompt 'Enter Source Library Name'
$TargetLibraryName= Read-Host -Prompt 'Enter Target Library Name'
#Setup Credentials to connect
$Cred= Get-Credential
$Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)
#Setup the contexts
$SourceCtx = New-Object Microsoft.SharePoint.Client.ClientContext($SourceSiteURL)
$SourceCtx.Credentials = $Credentials
$TargetCtx = New-Object Microsoft.SharePoint.Client.ClientContext($TargetSiteURL)
$TargetCtx.Credentials = $Credentials
#Get the source library and Target Libraries
$SourceLibrary = $SourceCtx.Web.Lists.GetByTitle($SourceLibraryName)
$SourceCtx.Load($SourceLibrary)
$SourceCtx.Load($SourceLibrary.RootFolder)
$TargetLibrary = $TargetCtx.Web.Lists.GetByTitle($TargetLibraryName)
$TargetCtx.Load($TargetLibrary)
$TargetCtx.Load($TargetLibrary.RootFolder)
$TargetCtx.ExecuteQuery()
#Call the function
Copy-AllFilesWithMetadata -SourceFolder $SourceLibrary.RootFolder -TargetFolder $TargetLibrary.RootFolder
Could anyone please help me?