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.

1
  • 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, 2017 at 16:05

2 Answers 2

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
2
  • I don't think that it will work for 2 different SharePoint farms. Did you tried it ?
    – KhalilG
    Mar 30, 2017 at 13:02
  • See my edit for updated details.
    – Bunzab
    Mar 30, 2017 at 14:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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