0

I upload files from the local drive to sharepoint site using powershell

I have a list " Documents " , he contains a folder named " X "

My issue is : How to upload files to X folder

This my code :

$SiteURL = "domain/sites/testing/"
$libraryName="Documents/X"
$SPOnlineUserName="user@domain"

The script work fine when i upload to Documents ($libraryName variable is " Documents ")

But when $libraryName="Documents/X" folder , i get this error :

List 'Documents/X' does not exist at site with URL 'domain/sites/testing'

Any Idea to resolve this ?

[Edit]

I can access to "X" folder via browser.

Best.

1
  • Please try the modified code and if have any more detailed information, please post back. Commented Jul 3, 2019 at 1:32

1 Answer 1

2

Update for large file upload:

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"

$SiteURL="https://tenant.sharepoint.com/sites/dev"
$User = "[email protected]"  
$Password = '*********************' 
$Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($User,(ConvertTo-SecureString $Password -AsPlainText -Force))
$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$ctx.Credentials = $Credentials

$fileChunkSizeInMB = 9

# Each sliced upload requires a unique ID.
$UploadId = [GUID]::NewGuid()

# Get the name of the file.
$UniqueFileName = [System.IO.Path]::GetFileName("D:\\Yoyo.wmv")


# Get the folder to upload into. 
$Docs = $ctx.Web.Lists.GetByTitle("Documents")
$ctx.Load($Docs)
$ctx.Load($Docs.RootFolder)
$ctx.ExecuteQuery()

# Get the information about the folder that will hold the file.
$ServerRelativeUrlOfRootFolder = $Docs.RootFolder.ServerRelativeUrl

# File object.
[Microsoft.SharePoint.Client.File] $upload


# Calculate block size in bytes.
$BlockSize = $fileChunkSizeInMB * 1024 * 1024


# Get the size of the file.
$FileSize = (Get-Item $fileName).length

if ($FileSize -le $BlockSize)
{
    # Use regular approach.
    $FileStream = New-Object IO.FileStream($fileName,[System.IO.FileMode]::Open)
    $FileCreationInfo = New-Object Microsoft.SharePoint.Client.FileCreationInformation
    $FileCreationInfo.Overwrite = $true
    $FileCreationInfo.ContentStream = $FileStream
    $FileCreationInfo.URL = $UniqueFileName
    $Upload = $Docs.RootFolder.Files.Add($FileCreationInfo)
    $ctx.Load($Upload)
    $ctx.ExecuteQuery()
    return $Upload
}
else
{

    # Use large file upload approach.
    $BytesUploaded = $null

    $Fs = $null

    Try {

        $Fs = [System.IO.File]::Open($fileName, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite)

        $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.
                $fileInfo = New-Object Microsoft.SharePoint.Client.FileCreationInformation
                $fileInfo.ContentStream = $ContentStream
                $fileInfo.Url = $UniqueFileName
                $fileInfo.Overwrite = $true
                $Upload = $Docs.RootFolder.Files.Add($fileInfo)
                $ctx.Load($Upload)

                # Start upload by uploading the first slice.

                $s = [System.IO.MemoryStream]::new($buffer) 

                # Call the start upload method on the first slice.
                $BytesUploaded = $Upload.StartUpload($UploadId, $s)
                $ctx.ExecuteQuery()

                # fileoffset is the pointer where the next slice will be added.
                $fileoffset = $BytesUploaded.Value

                # You can only start the upload once.
                $first = $false

            }
            Else
            {
                # Get a reference to your file.
                $Upload = $ctx.Web.GetFileByServerRelativeUrl($Docs.RootFolder.ServerRelativeUrl + [System.IO.Path]::AltDirectorySeparatorChar + $UniqueFileName);

                If($last) {

                    # Is this the last slice of data?
                    $s = [System.IO.MemoryStream]::new($lastBuffer)


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


                    Write-Host "File upload complete"
                    # Return the file object for the uploaded file.
                    return $Upload

                }
                else {

                    $s = [System.IO.MemoryStream]::new($buffer)

                    # Continue sliced upload.
                    $BytesUploaded = $Upload.ContinueUpload($UploadId, $fileoffset, $s)
                    $ctx.ExecuteQuery()

                    # Update fileoffset for the next slice.
                    $fileoffset = $BytesUploaded.Value

                }
            }

        }
    }
    Catch 
    {
        Write-Host $_.Exception.Message -ForegroundColor Red
    }
    Finally 
    {

        if ($Fs -ne $null)
        {
            $Fs.Dispose()
        }

    }
}
Sign up to request clarification or add additional context in comments.

8 Comments

Thank you can you modify this script to input the username and password in the script
Which error you are meeting ? For username and password, will come from Get-Credential. If you want to embed hard code user name and password, I will changed it later, please check.
@KivenWanda, please also replace the tenantname, sitename in the url and the local file path, library subfolder relative url with yours in the script above
This script can upload large file ? (more of 2Gb) ?
FileCreationInformation not supported large file, if you want to upload large using csom powershell, please check this demo: social.technet.microsoft.com/wiki/contents/articles/… The code snippet in the post is a demo to how to upload file into a sub folder within the library based on the original question.
|

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.