How to upload files to SharePoint with MS Graph API and PowerShell

Uploading files to OneDrive or SharePoint through the Microsoft Graph API with PowerShell

In the tutorial below I explain how you can upload files to SharePoint sites including to child directories.

There is no way in the tutorial how to do this directly with the Microsoft Graph API URLs.
I have written a cmdlet in a module for you to use.

Do you want to know how you can do this without a module?
Then you can go to the last paragraph and consult the links of the official Microsoft Graph API docs.


Before we can start…

We need the following:


PowerShell module Optimized.Mga

I made the Optimized.Mga.SharePoint module myself. It’s a submodule for Optimized.Mga.

The module (for now) contains the cmdlets:

  • Get-MgaSharePointFiles
  • Download-MgaSharePointFiles
  • Upload-MgaSharePointFiles

    If you have feedback for me, you can leave a comment on this post, or on Github.

AzureAD registered application

Not sure how to get started with an AzureAD registered application for the Microsoft Graph API?

I wrote a page for this which you can find here:
How to start with Microsoft Graph in PowerShell by Bas Wijdenes

Microsoft also created a blog post about how to get started with an AzureAD registered application for the Microsoft Graph API.

You can find that here:
Manage app registration and API permission for Microsoft Graph notifications – Microsoft Graph | Microsoft Docs


Let’s get started with Optimized.Mga in PowerShell

Getting the Authorization token from Microsoft Graph API

Open Powershell!

To install the module & submodule you can use the following cmdlet:

Install-Module Optimized.Mga.SharePoint -Scope CurrentUser

Copy the below cmdlet.
Update the ApplicationID, ClientSecret & Tenant with the correct values.

By running the cmdlet you will create an Authorization token that other cmdlets (like Get-Mga) will automatically use in the backend.

$null = Connect-Mga -ClientSecret 'XXXX' -ApplicationID 'b5954443-ad10-4d1c-8cbc-dc05268a1858' -Tenant 'bwit.onmicrosoft.com'

If everything went well, you have received a message stating that you are logged in.


This time there is only one cmdlet we need: Upload-MgaSharePointFiles, to upload files..

With Upload-MgaSharePointFiles you can upload files to SharePoint sites and OneDrives. The cmdlet is embedded in the module.
It accepts the following parameter:

  • TenantName
  • Site
  • Item / ItemPath
  • ChildFolders

TenantName & Site speak for themselves. The TenantName is the ‘*.onmicrosoft.com’ address.
The Site parameter is the site name parameter where you want to upload a file.

The Item or ItemPath parameter is a bit different.
ItemPath will accept a path string to the item you want to upload to SharePoint.

When you Shift + Right click a file you can select ‘Copy as path’ as in the screenshot below. The copy as path will look like this: “C:\temp\blatemp.txt”.

How to upload files to SharePoint with MS Graph API and PowerShell
How to upload files to SharePoint with MS Graph API and PowerShell
Upload-MgaSharePointFiles -ItemPath "C:\temp\blatemp.txt" -TenantName 'm365x794103.onmicrosoft.com' -Site 'XXXX'

The parameter Item will accept an item of object [System.IO.FileSystemInfo]. Which means that you first use Get-Item -Path C:\temp\blatemp.txt before you start Upload-MgaSharePointFiles.

Upload-MgaSharePointFiles -Item (Get-Item "C:\temp\blatemp.txt") -TenantName 'm365x794103.onmicrosoft.com' -Site 'XXXX'

createdBy            : @{application=; user=}
createdDateTime      : 2021-12-15T17:03:27Z
eTag                 : "{1971E81D-639D-48AE-984D-36BDE03AAACF},7"
id                   : 01MIYRG5I55BYRTHLDVZEJQTJWXXQDVKWP
lastModifiedBy       : @{application=; user=}
lastModifiedDateTime : 2021-12-15T18:27:32Z
name                 : blatemp.txt

It really depends on how you want to use Upload-MgaSharePointFiles.
Do you want to bulk upload items?
I’d suggest using Get-Item / Get-ChildItem first and then use a foreach loop.

$Items = Get-ChildItem -Path 'C:\temp\'foreach ($item in $Items) {    Upload-MgaSharePointFiles -Item $item -TenantName 'XXXX' -Site 'XXXX' }

There is a ChildFolders parameter that is not mandatory.
If you do not provide ChildFolders, the root is automatically used.

The ChildFolder parameter accepts an array of subfolders.
So if you want to upload a file in a sub folder you can use the following command:

Upload-MgaSharePointFiles -Item (Get-Item "C:\temp\blatemp.txt") -TenantName 'XXXX' -Site 'XXXX' -ChildFolders 'XXXX','Personnel files','bas.wijdenes','Personal'

createdBy            : @{application=; user=}
createdDateTime      : 2021-12-15T17:03:27Z
eTag                 : "{1971E81D-639D-48AE-984D-36BDE03AAACF},7"
id                   : 01MIYRG5I55BYRTHLDVZEJQTJWXXQDVKWP
lastModifiedBy       : @{application=; user=}
lastModifiedDateTime : 2021-12-15T18:27:32Z
name                 : blatemp.txt

ChildFolders are directories in the root as in the screenshot below.

How to upload files to SharePoint with MS Graph API and PowerShell
How to upload files to SharePoint with MS Graph API and PowerShell

The official Microsoft Graph API docs

The following Microsoft Graph API docs are used in this tutorial:

Get a SharePoint site:
Get a SharePoint Site – Microsoft Graph beta | Microsoft Docs

Resumable file upload:
Resumable file upload – Microsoft Graph v1.0 | Microsoft Docs

Published by

Bas Wijdenes

My name is Bas Wijdenes and I work as a PowerShell DevOps Engineer. In my spare time I write about interesting stuff that I encounter during my work.

2 thoughts on “How to upload files to SharePoint with MS Graph API and PowerShell”

  1. I’m currently getting the below error when I try to use the module.
    —————–
    elseif : The term ‘elseif’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
    At C:\Users\USERNAME\Documents\WindowsPowerShell\Modules\Optimized.Mga\4.0.0\functions\Public\Methods\Add-Mga.ps1:66 char:13
    + elseif ($Uri -notlike ‘*/uploadSession*’) {
    + ~~~~~~
    + CategoryInfo : ObjectNotFound: (elseif:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

  2. Can you provide an example of the Site parameter? Is that the Site ID, a full URL or partial URL or something else?

Leave a Reply

Your email address will not be published. Required fields are marked *