1

I'm trying to copy documents from a document library in staging environment to a document library in the preproduction environment using PowerShell CSOM. The code I've tested is as follows:

$loadInfo1 = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client")
$loadInfo2 = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime")
$loadInfo3 = [System.Reflection.Assembly]::LoadWithPartialName("System.IO")

Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll" 
Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"

# Paramètres du script
$orgSiteUrl = "http://site1/"
$destSiteUrl = "http://site2/"
$orgLibrary = "Documents"
$destLibrary = "Documents"
$srcLibrary = $web.Lists["Documents"] 
$destLibrary = $destWeb.Lists["Documents"] 

$orgClientContext = $null
$destClientContext = $null

function MoveFiles(
    [string]$orgSiteUrl,
    [string]$destSiteUrl,
    [string]$orgLibrary,
    [string]$destLibrary
)
{

    $UserName = 'someDomain\someUser'
    $SecurePassword = "somePassword" | ConvertTo-SecureString -AsPlainText -Force

    Write-Host "Script running with following account : "$UserName -ForegroundColor Yellow

    # Get the Client Context and Bind the Site Collection
    $ClientContext = New-Object Microsoft.SharePoint.Client.ClientContext($orgSiteUrl)
    $destClientContext = New-Object Microsoft.SharePoint.Client.ClientContext($destSiteUrl)

    # Connect to source site
    $credentials = New-Object System.Net.NetworkCredential($UserName, $SecurePassword)
    $ClientContext.Credentials = $credentials
    $web = $ClientContext.Web
    $ClientContext.Load($web)
    $ClientContext.ExecuteQuery()

    # Connect to destination site
    $credentials = New-Object System.Net.NetworkCredential($UserName, $SecurePassword)
    $destClientContext.Credentials = $credentials
    $destWeb = $destClientContext.Web
    $destClientContext.Load($destWeb)
    $destClientContext.ExecuteQuery()

    # Get List and List Items
    $List = $web.Lists.GetByTitle($orgLibrary)
    $ListItems = $List.GetItems([Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery())
    $ClientContext.Load($List)
    $ClientContext.Load($ListItems)
    $ClientContext.ExecuteQuery()

    # Get List and List Items
    $destList = $destWeb.Lists.GetByTitle($destLibrary)
    $destClientContext.Load($destList)
    $destClientContext.ExecuteQuery()

    For ($j=0; $j -lt $ListItems.Count; $j++){

        $item = $ListItems[$j]
        $ClientContext.Load($item) 
        $file = $item.File       
        $ClientContext.Load($file)
        $binaryStream = $file.OpenBinaryStream()
        $ClientContext.ExecuteQuery()

        $FileCreationInfo = New-Object Microsoft.SharePoint.Client.FileCreationInformation
        $FileCreationInfo.Overwrite = $true
        $FileCreationInfo.ContentStream = $binaryStream
        $FileCreationInfo.URL = $destList.RootFolder.ServerRelativeUrl + "/" + $item.File.Name
        $Upload = $destList.RootFolder.Files.Add($FileCreationInfo)
        $destClientContext.Load($Upload)
        $destClientContext.ExecuteQuery()   

    }

}

MoveFiles -orgSiteUrl $orgSiteUrl -destSiteUrl $destSiteUrl -orgLibrary $orgLibrary -destLibrary $destLibrary -UserName $UserName -SecurePassword $SecurePassword

The problem appears when the script is trying to add the binary stream to the FileInfoCreation object in the following line :

$FileCreationInfo.ContentStream = $binaryStream

The error is as follows :

Exception setting "ContentStream": "Cannot convert the 
"Microsoft.SharePoint.Client.ClientResult`1[System.IO.Stream]" value of type 
"Microsoft.SharePoint.Client.ClientResult`1[[System.IO.Stream, mscorlib, Version=4.0.0.0, 
Culture=neutral, PublicKeyToken=b77a5c561934e089]]" to type "System.IO.Stream"."
At D:\Users\Rteetnous-int-setup\Desktop\MoveFileCSOM.ps1:77 char:9
+         $FileCreationInfo.ContentStream = $binaryStream
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], SetValueInvocationException
    + FullyQualifiedErrorId : ExceptionWhenSetting

Exception calling "ExecuteQuery" with "0" argument(s): "parameters.Content, 
parameters.ContentStream
Nom du paramètre: La valeur spécifiée n'est pas prise en charge pour le paramètre 
parameters.Content, parameters.ContentStream."
At D:\Users\Rteetnous-int-setup\Desktop\MoveFileCSOM.ps1:81 char:9
+         $destClientContext.ExecuteQuery()
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ServerException

It's obvious that it's a cast error, but I searched and googled for hours and found nothing.

Can anyone help me figure out how to do this or suggest another solution using client side scripting ?

Thanks.

  • Another way that I found is to download the document and upload it into the target library, but the same issue appears when it's about dealing with object type, but this could be a solution to the problem. – KhalilG Feb 21 '17 at 16:05
1

I tried it myself, just use:

$FileCreationInfo.ContentStream = $binaryStream.Value

1

I recommend that you use the native file.copyto method. It is straight forward to use but let me know if you need an example.

Yeah I can't read. I changed your script a bit:

Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll" 
Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"

$orgSiteUrl = "http://sitea"
$destSiteUrl = "http://siteb"
$orgLibrary = "Documents"
$destLibrary = "More Documents"

function Move-Files{
[cmdletBinding()]
    param (
        [string]$orgSiteUrl,
        [string]$destSiteUrl,
        [string]$orgLibrary,
        [string]$destLibrary,
        [string]$userName,
        [string]$password
    )
    $securePassword = $password | ConvertTo-SecureString -AsPlainText -Force
    Write-Warning "Script running with following account: $userName"
    # Get the Client Context and Bind the Site Collection
    $sctx = New-Object Microsoft.SharePoint.Client.ClientContext($orgSiteUrl)
    $dctx = New-Object Microsoft.SharePoint.Client.ClientContext($destSiteUrl)
    # Connect to source site
    $credentials = New-Object System.Net.NetworkCredential($userName, $securePassword)
    $sctx.Credentials = $credentials
    $srcList = $sctx.Web.Lists.GetByTitle($orgLibrary)
    $srcItems = $srcList.GetItems([Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery())
    $sctx.Load($srcList)
    $sctx.Load($srcItems)
    $sctx.ExecuteQuery()
    # Connect to destination site
    $credentials = New-Object System.Net.NetworkCredential($UserName, $SecurePassword)
    $dctx.Credentials = $credentials
    $destList = $dctx.Web.Lists.GetByTitle($destLibrary)
    $rootFolder = $destList.RootFolder
    $destItems = $destlist.GetItems([Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery())
    $dctx.Load($rootFolder)
    $dctx.Load($destList)
    $dctx.Load($destItems)
    $dctx.ExecuteQuery()
    For ($j=0; $j -lt $srcItems.Count; $j++){
        $item = $srcItems[$j]
        $sctx.Load($item) 
        $file = $item.File       
        $sctx.Load($file)
        $sctx.ExecuteQuery()
        $fileInfo = [Microsoft.SharePoint.Client.File]::OpenBinaryDirect($sctx, $item.File.ServerRelativeUrl)
        $destUrl = $destList.RootFolder.ServerRelativeUrl + "/" + $item.File.Name
        Write-Verbose "Adding $destUrl"
        [Microsoft.SharePoint.Client.File]::SaveBinaryDirect($dctx, $destUrl, $fileinfo.Stream, $true) | Out-Null
    }
}
Move-Files -orgSiteUrl $orgSiteUrl -destSiteUrl $destSiteUrl -orgLibrary $orgLibrary -destLibrary $destLibrary -userName "domain\user" -password "Password" -Verbose
  • I don't think that it will work for 2 different SharePoint farms. Did you tried it ? – KhalilG Mar 30 '17 at 13:02
  • See my edit for updated details. – Bunzab Mar 30 '17 at 14:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.