How to upload large files to OneDrive by Rest API via Powershell

Introduction

This sample demonstrates how to upload large files to OneDrive by Rest API via Powershell. The script needs users to locally input absolute file path and the target file path on OneDrive. After the authentication has been done, the script will automatically upload the file without any size limit.

Scenarios

Users need to locally upload files to OneDrive without installing OneDrive client for politic reason in a company. Although OneDrive provides a simple rest API for users to upload files easily, but it has a size limit. Files that are greater than 100MB can be uploaded to OneDrive using the simple item upload rest api. If your files are all smaller than that size, you can refer to the API reference here https://dev.onedrive.com/items/upload_put.htm .

 

In this sample script, we provide a function to help you handle the messy stuff to authenticate and call upload large file Rest API of OneDrive.

Prerequisites

• Powershell version is 3.0 or above

• .NET framework version is 4.5.2 or above

Script

The script folder contains several items

• libs\ReadPartialFile.dll – C# assistant DLL used by script to read part of file

• OneDriveAuthentication.psm1 – The authentication module helps to complete authentication issue

• UploadFileToOneDrive.ps1 – The core script contains main logic for uploading file

 

Register OneDrive Application

• Please follow this sample https://gallery.technet.microsoft.com/How-to-use-OneDrive-Rest-5b31cf78 The following steps will help you to register the OneDrive Application

• Get the Client Id, Secret Key and Redirect Url of your application

 

Follow the steps below to run the script

• Open the UploadFileToOneDrive.ps1

• Change $ClientId, $SecretKey, $RedirectURI, $FilePath, $OneDriveFilePath according to your application and file


• Run Powershell as administrator under the folder which contains the script

• Call UploadFileToOneDrive.ps1 in Powershell

• After all the steps above has been finished, you will see the similar console output in screenshot below


 

The script will output the uploading block of the file one by one. After all has been completed, it will print the file id, name and url information of the file in OneDrive.

 

Here are some code snippets for your reference.

 

PowerShell
Edit|Remove
Function Send-File 
{ 
    [CmdletBinding()] 
    Param 
    ( 
        [Parameter(Mandatory=$true)][String]$ClientId, 
        [Parameter(Mandatory=$true)][String]$SecretKey, 
        [Parameter(Mandatory=$true)][String]$RedirectURI, 
        [Parameter(Mandatory=$true)][String]$LocalFilePath, 
        [Parameter(Mandatory=$true)][String]$OneDriveTargetPath, 
        [Parameter(Mandatory=$false)][Int]$UploadBulkCount = 1024 * 1024 * 50 
    ) 
 
    # test the local file exists or not 
    If (-Not (Test-Path $LocalFilePath)) 
    { 
        Throw '"$LocalFilePath" does not exists!' 
    } 
     
    # load authentication module to ease the authentication process 
    Import-Module "$PSScriptRoot\OneDriveAuthentication.psm1" 
     
    # get token 
    $Token = New-AccessTokenAndRefreshToken -ClientId $ClientId -RedirectURI $RedirectURI -SecretKey $SecretKey 
 
    # you can store the token somewhere for the later usage, however the token will expired 
    # if the token is expired, please call Update-AccessTokenAndRefreshToken to update token 
    # e.g. 
    # $RefreshedToken = Update-AccessTokenAndRefreshToken -ClientId $ClientId -RedirectURI $RedirectURI -RefreshToken $Token.RefreshToken -SecretKey $SecretKey 
     
    # construct authentication header 
    $Header = Get-AuthenticateHeader -AccessToken $Token.AccessToken 
 
    # api root 
    $ApiRootUrl = "https://api.onedrive.com/v1.0" 
 
    # 1. Create an upload session 
    $uploadSession = Invoke-RestMethod -Headers $Header -Method Post -Uri "$ApiRootUrl/drive/root:/${OneDriveTargetPath}:/upload.createSession" 
 
    # 2. import the read file partial dll 
    Add-Type -Path "$PSScriptRoot\libs\ReadPartialFile.dll" 
 
    # 3. get file info 
    $fileInfo = Get-Item $LocalFilePath 
 
    # 4. Upload fragments 
    $filePos = 0 
 
    Do { 
        $filePartlyBytes = [ReadPartialFile.Reader]::ReadFile($FilePath$filePos$UploadBulkCount); 
 
        If ($filePartlyBytes -eq $Null) { 
            Break 
        } 
 
        If ($filePartlyBytes.GetType() -eq [Byte]) { 
            $uploadCount = 1 
        } Else { 
            $uploadCount = $filePartlyBytes.Length 
        } 
 
        $Header["Content-Length"] = $uploadCount 
        $Header["Content-Range"] = "bytes $filePos-$($filePos + $uploadCount - 1)/$($fileInfo.Length)" 
 
        # print progress 
        Write-Host "Uploading block [$filePos - $($filePos + $uploadCount)] among total $($fileInfo.Length)" 
 
        # call upload api 
        $uploadResult = Invoke-RestMethod -Headers $Header -Method Put -Uri $uploadSession.uploadUrl -Body $filePartlyBytes 
 
        # proceed to next postion 
        $filePos +$UploadBulkCount 
 
    } While ($filePartlyBytes.GetType() -eq [Byte[]] -and $filePartlyBytes.Length -eq $UploadBulkCount) 
 
    Write-Host "Upload finished" 
    Write-Host "" 
 
    RETURN $uploadResult 
}
Additional Resources

• OneDrive API about upload large file: https://dev.onedrive.com/items/upload_large_files.htm#request-upload-status

• Technet sample about how to register OneDrive application: https://gallery.technet.microsoft.com/How-to-use-OneDrive-Rest-5b31cf78

 

Microsoft All-In-One Script Framework is an automation script sample library for IT Professionals. The key value that All-In-One Script Framework is trying to deliver is Scenario-Focused Script Samples driven by IT Pros' real-world pains and needs. The team is monitoring all TechNet forums, IT Pros' support calls to Microsoft, and script requests submitted to TechNet Script Repository. We collect frequently asked IT scenarios, and create script samples to automate the tasks and save some time for IT Pros. The team of All-In-One Script Framework sincerely hope that these customer-driven automation script samples can help our IT community in this script-centric move.