SharePoint 2013 Powershell - 将文件从一个网站集复制到另一个

SharePoint 2013 Powershell - Copy File From One Site Collection To Another

有人可以协助解决上述问题吗?

我想将一个文件从 Sharepoint 网站集中的特定文件夹复制到另一个 Sharepoint 网站集中(但仍在同一 Web 应用程序中)的另一个库(同名)。 我的 Powershell 经验很少,并且尝试了多次 Google 搜索,但似乎找不到任何有用的东西。

下面是我尝试做的事情的一个例子(大量的 Write-Host 试图弄清楚发生了什么),底部有错误消息。

Add-PSSnapIn "Microsoft.SharePoint.PowerShell"

## 
#Set Static Variables 
## 

$SourceWebURL = "http://WebAppURL/sites/Area/Master" 
$SourceLibraryTitle = "Web" 
$DestinationWebURL = "http://WebAppURL/sites/OtherSiteName" 
$DestinationLibraryTitle = "Web"
$FileName = "Resources.aspx"

## 
#Begin Script 
## 

$sWeb = Get-SPWeb $SourceWebURL 
$sList = $sWeb.Lists | ? {$_.Title -eq $SourceLibraryTitle} 
$dWeb = Get-SPWeb $DestinationWebURL 
$dList = $dWeb.Lists | ? {$_.title -like $DestinationLibraryTitle} 

$DestFolder = $dList.Files

$RootFolder = $sList.RootFolder
Write-Host " line 25 -- " $RootFolder  
$collfiles1 = $RootFolder.Files
Write-Host " line 27 -- "$collfiles1
Write-Host " line 28 -- "$DestFolder

Write-Host " line 30 -- "$str = $DestinationWebURL"/"$DestinationLibraryTitle"/"$FileName 
Write-Host  " line 31 -- "$collfiles1.Count
for($i = 0 ; $i -lt $collfiles1.Count ; $i++)
{
    Write-Host " line 34 -- "$collfiles1[$i].Name
    ##Write-Host $FileName
    if($collfiles1[$i].Name -eq $FileName)
    {
    ##  $str = $DestinationWebURL.Url + $DestinationLibraryTitle + "/" + $FileName
        $str = $DestinationWebURL+"/" +$DestinationLibraryTitle+"/"
        Write-Host " line 40 -- "$str
        Write-Host " line 41 -- "$collfiles1[$i]
        $FiletoCopy = $collfiles1[$i].Name
        Write-Host " line 43 -- " $FiletoCopy
        $FiletoCopy.CopyTo($str,$true)
    }
}
Write-Host "Script Completed"

下面的例子给出了错误

Cannot find an overload for "CopyTo" and the argument count: "2".
At line:44 char:3
+         $FiletoCopy.CopyTo($str,$true)
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodCountCouldNotFindBest

如果有人能指出正确的方向,那将非常有帮助。

提前致谢, 伊恩.

以下PowerShell供您参考,将文件从网站集中的一个库复制到另一个网站集中的另一个库,带字段。

Add-PSSnapIn "Microsoft.SharePoint.PowerShell"

## 
#Set Static Variables 
## 

$SourceWebURL = "http://WebAppURL/sites/Area/Master" 
$SourceLibraryTitle = "Web" 
$DestinationWebURL = "http://WebAppURL/sites/OtherSiteName" 
$DestinationLibraryTitle = "Web"
$FileName = "Resources.aspx"

## 
#Begin Script 
## 

$sWeb = Get-SPWeb $SourceWebURL 
#$sList = $sWeb.Lists | ? {$_.Title -eq $SourceLibraryTitle} 
$dWeb = Get-SPWeb $DestinationWebURL 
#$dList = $dWeb.Lists | ? {$_.title -like $DestinationLibraryTitle} 

$SourceFile=$sWeb.GetFile($SourceWebURL+"/"+$SourceLibraryTitle+"/"+$FileName)
$TargetFolder = $dWeb.GetFolder($DestinationLibraryTitle)
#Copy File from the Source
$NewFile = $TargetFolder.Files.Add($SourceFile.Name, $SourceFile.OpenBinary(),$True)

#Copy Meta-Data from Source
Foreach($Field in $SourceFile.Item.Fields)
{
    If(!$Field.ReadOnlyField)
    {
        if($NewFile.Item.Fields.ContainsField($Field.InternalName))
        {
            $NewFile.Item[$Field.InternalName] = $SourceFile.Item[$Field.InternalName]
        }
    }
}
#Update
$NewFile.Item.UpdateOverwriteVersion()

Write-host "Copied File:"$SourceFile.Name

参考:Copy Files Between Document Libraries in SharePoint using PowerShell

所以对于文件大小大于 50MB 的大文件。 @LZ_MSFT 提到的这个脚本可能永远无法复制该文件。在这方面,您需要将文件分块成小 pieces.Here 是 PS 如果文件大小大于 50MB,则使用分块从源复制到目标。这个脚本的优点是,它使用客户端,因此它可以与 SP 在线和 on-prem.

一起使用
   Add-Type –Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\ISAPI\Microsoft.SharePoint.Client.dll"
   Add-Type –Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
    Function UploadFileInSlice ($DestinationCtx, $SourceCtx, $SourceFileUrl, $DestinationFolderUrl, $fileName, $fileChunkSizeInMB) {
    
    # Each sliced upload requires a unique ID.
    $UploadId = [GUID]::NewGuid()

    # Get File by Server Relative URL
    $File = $SourceCtx.Web.GetFileByServerRelativeUrl($SourceFileUrl)
    $SourceCtx.Load($File)

    # Get file Steam with OpenBinarySteam
    $StreamToUpload = $File.OpenBinaryStream() 
    $SourceCtx.ExecuteQuery()

    # File size in bytes
    $FileSize = ($File).length  

    # Get Destination Folder by Server Relative URL
    $DestinationFolder = 
    $DestinationContext.Web.GetFolderByServerRelativeUrl($DestinationFolderUrl)
    $DestinationCtx.Load($DestinationFolder)
    $DestinationCtx.ExecuteQuery()

    # Set Complete Destination URL with Destination Folder + FileName
    $destUrl = $DestinationFolderUrl + "/" + $fileName
    # File object.
    [Microsoft.SharePoint.Client.File] $upload

    # Calculate block size in bytes.
    $BlockSize = $fileChunkSizeInMB * 1000 * 1000 
    Write-Host "File Size is: $FileSize bytes and Chunking Size is:$BlockSize bytes"

    if ($FileSize -le $BlockSize)
    {
        # Use regular approach if file size less than BlockSize
        Write-Host "File uploading with out chunking"
        $upload =[Microsoft.SharePoint.Client.File]::SaveBinaryDirect($DestinationCtx, $destUrl, $StreamToUpload.Value, $true)
        return $upload
    }
    else
    {
        # Use large file upload approach.
        $BytesUploaded = $null
        $Fs = $null
        
        Try {
            $br = New-Object System.IO.BinaryReader($StreamToUpload.Value)
            
            #$br = New-Object System.IO.BinaryReader($Fs)
            $buffer = New-Object System.Byte[]($BlockSize)
            $lastBuffer = $null
            $fileoffset = 0
            $totalBytesRead = 0
            $bytesRead
            $first = $true
            $last = $false
            # Read data from file system in blocks. 
            while(($bytesRead = $br.Read($buffer, 0, $buffer.Length)) -gt 0) {
                $totalBytesRead = $totalBytesRead + $bytesRead
                # You've reached the end of the file.
                if($totalBytesRead -eq $FileSize) {
                    $last = $true
                    # Copy to a new buffer that has the correct size.
                    $lastBuffer = New-Object System.Byte[]($bytesRead)
                    [array]::Copy($buffer, 0, $lastBuffer, 0, $bytesRead)
                }

                If($first)
                {
                    $ContentStream = New-Object System.IO.MemoryStream
                    # Add an empty file.
                    $fileCreationInfo = New-Object Microsoft.SharePoint.Client.FileCreationInformation
                    $fileCreationInfo.ContentStream = $ContentStream
                    $fileCreationInfo.Url = $fileName
                    $fileCreationInfo.Overwrite = $true
                    #Add file to Destination Folder with file creation info
                    $Upload = $DestinationFolder.Files.Add($fileCreationInfo)
                    $DestinationCtx.Load($Upload)

                    # Start upload by uploading the first slice.
                    $s = New-Object System.IO.MemoryStream(,$Buffer)
                    Write-Host "Uploading id is:"+$UploadId
                    # Call the start upload method on the first slice.
                    $BytesUploaded = $Upload.StartUpload($UploadId, $s)
                    $DestinationCtx.ExecuteQuery()

                    # fileoffset is the pointer where the next slice will be added.
                    $fileoffset = $BytesUploaded.Value
                    Write-Host "First patch of file with bytes"+ $fileoffset 
                    # You can only start the upload once.
                    $first = $false
                }
                Else
                {
                    # Get a reference to your file.
                    $Upload = $DestinationCtx.Web.GetFileByServerRelativeUrl($destUrl);
                    If($last) {
                        # Is this the last slice of data?
                        $s = New-Object System.IO.MemoryStream(,$lastBuffer)

                        # End sliced upload by calling FinishUpload.
                        $Upload = $Upload.FinishUpload($UploadId, $fileoffset, $s)
                        $DestinationCtx.ExecuteQuery()

                        Write-Host "File Upload Completed Successfully!"
                        # Return the file object for the uploaded file.
                        return $Upload
                    }
                    else {
                        $s = New-Object System.IO.MemoryStream(,$buffer)
                        # Continue sliced upload.
                        $BytesUploaded = $Upload.ContinueUpload($UploadId, $fileoffset, $s)
                        $DestinationCtx.ExecuteQuery()

                        # Update fileoffset for the next slice.
                        $fileoffset = $BytesUploaded.Value
                        Write-Host "File uploading is in progress with bytes: "+ $fileoffset 
                    }
                }

            }  #// while ((bytesRead = br.Read(buffer, 0, buffer.Length)) > 0)
        }
        Catch {
            Write-Host $_.Exception.Message -ForegroundColor Red
        }
        Finally {
            if ($Fs -ne $null)
            {
                $Fs.Dispose()
            }
        }
    }
    return $null
   }

   #URL to Configure, in this case Destination is SP Online site URL
   #Adding up credentials hard-code, you can use Get-Credentails PS command too

   $DestnationSiteUrl = "https://your-domain.sharepoint.com/sites/xyz"
   $DestinationRelativeURL = "/sites/xyz/TestLibrary" #server relative URL here with library Name and Folder name
   $DestinationUserName = "xyz@your-domain.com"
   $DestinationPassword = Read-Host "Enter Password for Destination User: 
  $DestinationUserName" -AsSecureString

#URL to Configure, in this case Source is On-Prem site URL
#Adding up credentials hard-code, you can use Get-Credentails PS command too
$SourceSiteUrl = "http://intranet/sites/xyz"
$SourceRelativeURL = "/sites/xyz/TestLibrary/myfile.pptx" #server relative URL here with library Name and file name with extension
$SourceUsername = "domain\xyz"
$SourcePassword = Read-Host "Enter Password for Source User: $SourceUsername" -AsSecureString
#Set a file name with extension
$FileNameWithExt = "myfile.pptx"

#Get Source Client Context with credentials 
$SourceContext = New-Object Microsoft.SharePoint.Client.ClientContext($SourceSiteUrl) 
#Using NetworkCredentials in case of On-Prem
$SourceCtxcredentials = New-Object System.Net.NetworkCredential($SourceUsername, $SourcePassword)
$SourceContext.RequestTimeout = [System.Threading.Timeout]::Infinite
$SourceContext.ExecuteQuery();

#Get Destination Client Context with credentials 
$DestinationContext = New-Object Microsoft.SharePoint.Client.ClientContext($DestnationSiteUrl) 
#Using SharePointOnlineCredentials in case of SP-Online
$DestinationContext.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($DestinationUserName, $DestinationPassword)
$DestinationContext.RequestTimeout = [System.Threading.Timeout]::Infinite
$DestinationContext.ExecuteQuery();

#All Set up, now just call the UploadFileInSlice with parameters
$UpFile = UploadFileInSlice -DestinationCtx $DestinationContext -SourceCtx $SourceContext -DestinationFolderUrl $DestinationRelativeURL -SourceFileUrl $SourceRelativeURL -fileName $FileNameWithExt -fileChunkSizeInMB 10