Upload Files 2 SharePoint Online using GRAPH API

Sometimes it is needed to Upload Files to Sharepoint Online. One solution is to use the Graph API. Let me show how we can achive this goal.


There are 2 solutions with Graph API
  • Upload Files up to 4MB
  • Upload Files with a File Steram bigger than 4MB

First we will do the easy way and Upload a File smaller then 4MB

Preparation for both steps !

Now we have all Steps to get the access token.
Use following Script part to request the token and add it into the header.



$clientId = "ClientID of the created App"  
$clientSecret = "secret of the created App"  
$tenantName = "yourtenant.onmicrosoft.com"  
$resource = "https://graph.microsoft.com/"  

$tokenBody = @{

    Grant_Type    = 'client_credentials'  
    Scope         = 'https://graph.microsoft.com/.default'  
    Client_Id     = $clientId  
    Client_Secret = $clientSecret
      
}  

$tokenResponse = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$TenantName/oauth2/v2.0/token" -Method POST -Body $tokenBody -ErrorAction Stop


$headers = @{

    "Authorization" = "Bearer $($tokenResponse.access_token)"
    "Content-Type"  = "application/json"
}


We will user the header in the API Request for Authentication in both scenarios. 
Now we can start with the cool stuff 😉
 

Upload Files smaller then 4 MB

  • We need to declare 2 Variables
    • site object id
    • Filepath of the file we want to upload

To get the Site Object ID we now that if we create a Sharepoint Online Site there is also created a Group in Azure. So we navigate to the created Group and copy the Object ID of the Group.

  • Get the Subsite ID and the Document Drive ID

$site_objectid = "c1359d7b-07a0-47af-b0a5-2d5c7ed94ffe"
$Filepath = "C:\devtemp\upload2sharepoint.csv"

$URL = "https://graph.microsoft.com/v1.0/groups/$site_objectid/sites/root"
$subsite_ID = (Invoke-RestMethod -Headers $headers -Uri $URL -Method Get).ID

$URL = "https://graph.microsoft.com/v1.0/sites/$subsite_ID/drives"
$Drives = Invoke-RestMethod -Headers $headers -Uri $URL -Method Get

$Document_drive_ID = ($Drives.value | where { $_.name -eq 'Documents' }).id
  • Write the Content into a Variable
  • Declare the Filename for the Uploaded File

$Content = Get-Content -Path $Filepath
$Filename = (Get-Item -path $Filepath).Name
  • Now we can build the URL for Uploading the File (MS Upload Sharepoint Docu)
  • After that we will Invoke the Request and check if our File is Uploaded to Sharepoint

$puturl = "https://graph.microsoft.com/v1.0/drives/$Document_drive_ID/root:/Upload2Sharepoint/$($Filename):/content"


$upload_headers = @{

    "Authorization" = "Bearer $($tokenResponse.access_token)"
    "Content-Type"  = "text/plain"
}

Invoke-RestMethod -Headers $upload_headers -Uri $puturl -Body $Content -Method PUT
  • Now check if the File is Uploaded to Sharepoint
Looks like it was working. 
Now we will try to upload a File greather then 4MB

Upload Files with a File Steram bigger than 4MB

  • Declare
    • Site Object ID
    • Filepath of the File to Upload
  • Get
    • SubsiteID
    • Document Drive ID
  • Create an Upload Session

$site_objectid = "c1359d7b-07a0-47af-b0a5-2d5c7ed94ffe"
$Filepath = "C:\devtemp\11.12.2016_17-35-29.mp4"

$URL = "https://graph.microsoft.com/v1.0/groups/$site_objectid/sites/root"
$subsite_ID = (Invoke-RestMethod -Headers $headers -Uri $URL -Method Get).ID

$URL = "https://graph.microsoft.com/v1.0/sites/$subsite_ID/drives"
$Drives = Invoke-RestMethod -Headers $headers -Uri $URL -Method Get

$Document_drive_ID = ($Drives.value | where { $_.name -eq 'Documents' }).id
$Filename = (Get-Item -path $Filepath).Name

$upload_session = "https://graph.microsoft.com/v1.0/drives/$Document_drive_ID/root:/Upload2Sharepoint/$($Filename):/createUploadSession"

$upload_session_url = (Invoke-RestMethod -Uri $upload_session -Headers $headers -Method Post).uploadUrl


#--------------------------------------------------------------
Now we have created a Upload Session and can start to Upload the File. 

This Script part cuts the File literaly into 60MB pieces and upload it to teh Uploadstream we created before. 

The Logic for this part Upload i found in a Function on a Website. Unfortunately i can't found it anymore.As soon as i find it i will Link it under this part ! 

#--------------------------------------------------------------


$ChunkSize = 62259200
$file = New-Object System.IO.FileInfo($Filepath)
$reader = [System.IO.File]::OpenRead($Filepath)
$buffer = New-Object -TypeName Byte[] -ArgumentList $ChunkSize
$position = 0
$counter = 0

Write-Host "ChunkSize: $ChunkSize" -ForegroundColor Cyan
Write-Host "BufferSize: $($buffer.Length)" -ForegroundColor Cyan

$moreData = $true


While ($moreData) {
    #Read a chunk
    $bytesRead = $reader.Read($buffer, 0, $buffer.Length)
    $output = $buffer
    If ($bytesRead -ne $buffer.Length) {
        #no more data to be read
        $moreData = $false
        #shrink the output array to the number of bytes
        $output = New-Object -TypeName Byte[] -ArgumentList $bytesRead
        [Array]::Copy($buffer, $output, $bytesRead)
        Write-Host "no more data" -ForegroundColor Yellow
    }
    #Upload the chunk
    $Header = @{
        'Content-Length' = $($output.Length)
        'Content-Range'  = "bytes $position-$($position + $output.Length - 1)/$($file.Length)"
    }

    Write-Host "Content-Length = $($output.Length)" -ForegroundColor Cyan
    Write-Host "Content-Range  = bytes $position-$($position + $output.Length - 1)/$($file.Length)" -ForegroundColor Cyan
    #$position = $position + $output.Length - 1
    $position = $position + $output.Length
    Invoke-RestMethod -Method Put -Uri $upload_session_url -Body $output -Headers $Header -ContentType "application/octet-stream"
    #Increment counter
    $counter++
}
$reader.Close()

Now we can see the Uploaded Video on Sharepoint

One thought on “Upload Files 2 SharePoint Online using GRAPH API

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: