SOLVED

SharePoint Online - Upload document using PowerShell / CSOM

Copper Contributor

I am trying to upload document to SharePoint Online using PowerShell / CSOM.
Issue is that I don't have file on local drive. I have URL of a file which I download as
$wc = New-Object System.Net.WebClient
$ByteArray = $wc.downloaddata(Document URL)

 

$ByteArray is a Byte array

 

 

When I try to user following code, it generates error

 

#Specify tenant admin and site URL and including DLL

$User = "XXXXX@XXXXXXX"
$SiteURL = "XXXXXXXXXXX"
$DocLibName = "Documents"
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"
$Password = 'XXXXXX' | ConvertTo-SecureString -AsPlainText -Force

 

#Bind to site collection

$Context = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$Creds = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($User,$Password)
$Context.Credentials = $Creds
Retrieve list

$List = $Context.Web.Lists.GetByTitle($DocLibName)
$Context.Load($List)
$Context.ExecuteQuery()

 

#Upload File

$Upload = $List.RootFolder.Files.Add('abc.pdf',$ByteArray,$true)
$Context.Load($Upload)
$Context.ExecuteQuery()

 

Add doesn't work and not sure how to upload a byte array. I have tried with different arguments.

 

Error is

 

Cannot find an overload for "Add" and the argument count: "3".

 

Any help?

12 Replies

i think it can not find your library but not sure are you using the default documents library?(aka Shared Documents)?

Check the below sample.

https://gist.github.com/asadrefai/ecfb32db81acaa80282d

 

The number of arguments for the Add is 1, also I think can't add the byte stream in one go.

I have tried with file on local drive and it seems to be working.

Issue seems to be for Add method

You mean a local file to SharePoint or just a basic file to another folder local?

Yes.
File from computer drive to SharePoint Online is working fine.

Instead of the 3 parameters you are currently passing you have to provide a single parameter of type FileCreationInformation to List.RootFolder.Files.Add

 

More Info:

https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.client.filecreationinformation.aspx 

This is the issue.
I don't have file on local computer or on shared drive.
I have a URL from where I download file in the form of Byte Array.

One possible way is to save byte array on local drive and then upload but this is last resort

The FileCreationInformation object that you need to pass contains a property "Content" to which you can assign this Byte[] (which you already have right?)

best response confirmed by farhan faiz (Copper Contributor)
Solution

Please check the below modified script, which generates the byte array from the given URL and upload it to the SPO.

 

 

$wc = New-Object System.Net.WebClient
# update with correct path 
$ByteArray = $wc.downloaddata("http://downloads.microsoft.com/download/file.exe")

#Specify tenant admin and site URL and including DLL
$User = "XXXXX@XXXXXXX"
$Password = 'XXXXXX' | ConvertTo-SecureString -AsPlainText -Force
$SiteURL = "XXXXXXXXXXX"
$DocLibName = "Documents"
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"


#Bind to site collection
$Context = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$Creds = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($User,$Password)
$Context.Credentials = $Creds

$List = $Context.Web.Lists.GetByTitle($DocLibName)
$Context.Load($List)
$Context.ExecuteQuery()

#Upload File
$s =[System.IO.MemoryStream]($ByteArray)
$FileCreationInfo = New-Object Microsoft.SharePoint.Client.FileCreationInformation
$FileCreationInfo.Overwrite = $true
$FileCreationInfo.ContentStream = $s
$FileCreationInfo.URL = $UniqueFileName
$Upload = $List.RootFolder.Files.Add($FileCreationInfo)
$Context.Load($Upload)
$Context.ExecuteQuery() 

 

Have you tried to use PnP PowerShell commands? there's an AddFile command that can take a Stream as a parameter:
https://github.com/SharePoint/PnP-PowerShell/blob/master/Documentation/AddPnPFile.md
Thanks. Casting worked.
For those looking help on uploading files via PowerShell. I was able to do that using the information from the link below: The approach reads files from a drive and uploads them to the site using Invoke-WebRequest. This is a different from the original question, but I hope it helps.

#upload the file to the server using default credentials from the
#current session
$result = Invoke-WebRequest -Uri $url -InFile $filePath -Method PUT
-UseDefaultCredentials

http://www.ozkary.com/2017/09/powershell-upload-multiple-files-sharepoint.html
1 best response

Accepted Solutions
best response confirmed by farhan faiz (Copper Contributor)
Solution

Please check the below modified script, which generates the byte array from the given URL and upload it to the SPO.

 

 

$wc = New-Object System.Net.WebClient
# update with correct path 
$ByteArray = $wc.downloaddata("http://downloads.microsoft.com/download/file.exe")

#Specify tenant admin and site URL and including DLL
$User = "XXXXX@XXXXXXX"
$Password = 'XXXXXX' | ConvertTo-SecureString -AsPlainText -Force
$SiteURL = "XXXXXXXXXXX"
$DocLibName = "Documents"
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"


#Bind to site collection
$Context = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$Creds = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($User,$Password)
$Context.Credentials = $Creds

$List = $Context.Web.Lists.GetByTitle($DocLibName)
$Context.Load($List)
$Context.ExecuteQuery()

#Upload File
$s =[System.IO.MemoryStream]($ByteArray)
$FileCreationInfo = New-Object Microsoft.SharePoint.Client.FileCreationInformation
$FileCreationInfo.Overwrite = $true
$FileCreationInfo.ContentStream = $s
$FileCreationInfo.URL = $UniqueFileName
$Upload = $List.RootFolder.Files.Add($FileCreationInfo)
$Context.Load($Upload)
$Context.ExecuteQuery() 

 

View solution in original post