Uploading files to SharePoint is a common use case, when we are integrating 3rd party systems with SharePoint. In my previous articles, I have been explaining how you can upload files to SharePoint using PNP module. In this article, I want to show you how you can achieve upload files to SharePoint using Graph API.
Note: This method works for files, where the size is maximum 4 MB.
In the beginning, we will create an Azure Enterprise Application in Azure Active Directory. Then we will grant the created Enterprise Application the permission to interact with selected sites. At the end, I will share a PowerShell script to upload files to the SharePoint using Graph API.
Table of Contents
What do I need to upload files to SharePoint using Graph API?
To upload a file to SharePoint using Graph API, you need the following prerequisites fulfilled:
- You need your global administrator in your organization to grant the sites.selected permission for an Azure Enterprise Application
- You need to install PNP PowerShell module, to grant the Enterprise Application the permission to upload files to the specific SharePoint Site
How to create the Enterprise Application to upload Files to SharePoint?
In the beginning it is import to understand, which permission the Enterprise Application needs so that we can upload files to SharePoint using Graph API.
- Browse to Azure Active Directory Portal
- Create an App Registration with Sites.Selected permissions
- Create and note down credentials for the App Registration
I will explain how to do it step-by-step.
Browse to Azure Active Directory Portal
Open https://portal.azure.com/#view/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade in your browser.
If you have the global admin rights, I recommend authenticating with that account, so that you can directly grant your enterprise application the permission. Otherwise, you need to reauthenticate or ask your administrator to grant your enterprise application the permissions.
Create an App Registration with Sites.Selected permissions
Browse to the App Registration blade
Click on new registration
Define for the App a meaningful name, which follows your organization standards (Different admins should recognize what the purpose for this app is) and register it.
Browse to API permissions to grant your app registration the permission to upload files to SharePoint using Graph API.
Click on Add a permission
Now choose Microsoft Graph
If you want your application to work in the background (Without any user authentication), you need to choose Application permission. As my intention is to show you how to automate the process, I am sharing with you the application permission way.
Now search for Sites.Selected and click on add permissions.
If you are signed in with a user account with global administrator privileges, you can grant administrator admin consent for your tenant. In other case, you either need to sign in with the global administrator account or you have to ask your administrator to grant your app registration the permission.
Create Secret for the App Registration
To authenticate with your enterprise application, you need to either upload a certificate or create a secret for your enterprise application. In this case I am creating a secret.
Browse to Certificates & secrets
For the description, I think it makes sense to define which application is going to use your client secret. For the duration, I would go with the recommendation of Microsoft, as you might have lost this application out of sight in 24 months, which is the maximum duration for a client secret.
Now note down, what you see under value, you can only see it now.
With that last step, your Enterprise application has the right permissions on Azure Active Directory. In the next step you need to grant your enterprise Application the permission to write into the specific SharePoint site.
How to grant the App Registration Write Permissions for a Selected SharePoint Site?
In order to grant the app registration the permission, you need to ensure that PNP Module is installed on your client and that you are allowed to use it.
If you have not yet installed it, check the following documentation:
Connect to SharePoint with PowerShell | SharePoint Online (sposcripts.com)
If both conditions are applying, you can use this code to grant your App registration right permission to write in the site.
You can get your App ID by browsing to the overview page of your app registration.
Import-Module PnP.PowerShell $AppID = "e0b8aefa-cb52-4bda-93a0-7d87120bcdbb" $AppRegistrationName = "SP_Sites.Selected_SalesandMarketing" $DisplayNameofSitePermission = "Enterprise Application $AppRegistrationName" $SiteURL = "https://m365x323732.sharepoint.com/sites/SalesAndMarketing" Connect-PnPOnline -Url $SiteURL -Interactive Grant-PnPAzureADAppSitePermission -AppId $AppID -DisplayName $DisplayNameofSitePermission -Site $SiteURL -Permissions Write
You will be asked to authenticate.
At the end, your app registration has write permissions.
How to Upload Files to SharePoint using Graph API?
As we have created an app registration and gave it the permission to write to a selected site, we can use to upload files to SharePoint using Graph API. In my example, I want to upload a picture to the SharePoint Library Shared Documents. Make sure, that you have adjusted the parameters and have the client secret handy, which we have created in the previous steps.
When you run the code, you will be asked to provide the client secret for your app registration.
Param ( $Tenant = "m365x323732", $AppID = "e0b8aefa-cb52-4bda-93a0-7d87120bcdbb", $SiteID = "e35cee33-6d10-4e2c-a83b-496a26062ad3", $LibraryURL = "https://m365x323732.sharepoint.com/sites/SalesAndMarketing/Shared%20Documents", $Path = "C:\Users\Serkar\Desktop\security.png" ) $AppCredential = Get-Credential($AppID) #region authorize $Scope = "https://graph.microsoft.com/.default" $Body = @{ client_id = $AppCredential.UserName client_secret = $AppCredential.GetNetworkCredential().password scope = $Scope grant_type = 'client_credentials' } $GraphUrl = "https://login.microsoftonline.com/$($Tenant).onmicrosoft.com/oauth2/v2.0/token" $AuthorizationRequest = Invoke-RestMethod -Uri $GraphUrl -Method "Post" -Body $Body $Access_token = $AuthorizationRequest.Access_token $Header = @{ Authorization = $AuthorizationRequest.access_token "Content-Type"= "application/json" } #endregion #region get drives $GraphUrl = "https://graph.microsoft.com/v1.0/sites/$SiteID/drives" $BodyJSON = $Body | ConvertTo-Json -Compress $Result = Invoke-RestMethod -Uri $GraphUrl -Method 'GET' -Headers $Header -ContentType "application/json" $DriveID = $Result.value| Where-Object {$_.webURL -eq $LibraryURL } | Select-Object id -ExpandProperty id If ($DriveID -eq $null){ Throw "SharePoint Library under $LibraryURL could not be found." } #endregion #region upload file $FileName = $Path.Split("\")[-1] $Url = "https://graph.microsoft.com/v1.0/drives/$DriveID/items/root:/$($FileName):/content" Invoke-RestMethod -Uri $Url -Headers $Header -Method Put -InFile $Path -ContentType 'multipart/form-data' -Verbose #endregion
At the end you will receive the following response as example
VERBOSE: PUT with -1-byte payload VERBOSE: received -1-byte response of content type application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8 @odata.context : https://graph.microsoft.com/v1.0/$metadata#drives('b%21M-5c4xBtLE6oO0lqJgYq04f6JqJ_iTlEhBdXmkuqxRI4cWqlVo8-QKlAJO6KoBgT')/items/$entity @microsoft.graph.downloadUrl : https://m365x323732.sharepoint.com/sites/SalesAndMarketing/_layouts/15/download.aspx?UniqueId=9f900d6c-d023-41cc-8839-61f079916c03&Translate=fals e&tempauth=eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJhdWQiOiIwMDAwMDAwMy0wMDAwLTBmZjEtY2UwMC0wMDAwMDAwMDAwMDAvbTM2NXgzMjM3MzIuc2hhcmVwb2ludC5jb21AOG I5Y2ZmMzQtNjg4YS00YTkzLThhZDMtMjNjYTQ3ZWU2ZTcyIiwiaXNzIjoiMDAwMDAwMDMtMDAwMC0wZmYxLWNlMDAtMDAwMDAwMDAwMDAwIiwibmJmIjoiMTY3MjgyMjg4MSIsImV4cCI6IjE 2NzI4MjY0ODEiLCJlbmRwb2ludHVybCI6IjYrUUtpd1NldjBJdksyUFkwS2wyV0YveWNLSnYxQkdPc1RFb1pWclRyems9IiwiZW5kcG9pbnR1cmxMZW5ndGgiOiIxNDYiLCJpc2xvb3BiYWNr IjoiVHJ1ZSIsImNpZCI6IlpUSTFaakE0WTJJdE5XUTRPUzAwTldRd0xXSmtPVEV0WlRnMFpEUmhZVFJrTW1VMyIsInZlciI6Imhhc2hlZHByb29mdG9rZW4iLCJzaXRlaWQiOiJaVE0xWTJWb E16TXRObVF4TUMwMFpUSmpMV0U0TTJJdE5EazJZVEkyTURZeVlXUXoiLCJhcHBfZGlzcGxheW5hbWUiOiJTUF9TaXRlcy5TZWxlY3RlZF9TYWxlc2FuZE1hcmtldGluZyIsIm5hbWVpZCI6Im UwYjhhZWZhLWNiNTItNGJkYS05M2EwLTdkODcxMjBiY2RiYkA4YjljZmYzNC02ODhhLTRhOTMtOGFkMy0yM2NhNDdlZTZlNzIiLCJyb2xlcyI6InNlbGVjdGVkc2l0ZXMiLCJ0dCI6IjEiLCJ 1c2VQZXJzaXN0ZW50Q29va2llIjpudWxsLCJpcGFkZHIiOiIyMC4xOTAuMTkwLjEwMSJ9.c0kydmY4eUFWS2lvWmJkTG1yTjJGbmV0SkVHVHRtdjNZWHppbm1SKytTRT0&ApiVersion=2.0 createdDateTime : 2023-01-04T09:01:21Z eTag : "{9F900D6C-D023-41CC-8839-61F079916C03},1" id : 01P5GC6MTMBWIJ6I6QZRAYQOLB6B4ZC3AD lastModifiedDateTime : 2023-01-04T09:01:21Z name : security.png webUrl : https://m365x323732.sharepoint.com/sites/SalesAndMarketing/Shared%20Documents/security.png cTag : "c:{9F900D6C-D023-41CC-8839-61F079916C03},2" size : 129678 createdBy : @{application=; user=} lastModifiedBy : @{application=; user=} parentReference : @{driveType=documentLibrary; driveId=b!M-5c4xBtLE6oO0lqJgYq04f6JqJ_iTlEhBdXmkuqxRI4cWqlVo8-QKlAJO6KoBgT; id=01P5GC6MV6Y2GOVW7725BZO354PWSELRRZ; path=/drives/b!M-5c4xBtLE6oO0lqJgYq04f6JqJ_iTlEhBdXmkuqxRI4cWqlVo8-QKlAJO6KoBgT/root:} file : @{mimeType=image/png; hashes=} fileSystemInfo : @{createdDateTime=2023-01-04T09:01:21Z; lastModifiedDateTime=2023-01-04T09:01:21Z} image : shared : @{scope=users}
As you can see, the file was uploaded successfully to the SharePoint Library
How to Upload Files to a Folder in SharePoint using Graph API?
In order to upload files to folders, you just need to make sure that your URI contains the folder structure after root:/.
In my example below, I uploaded apicture to the Subfolder folder.
$Url = "https://graph.microsoft.com/v1.0/drives/$DriveID/items/root:/General/Subfolder/$($FileName):/content"
Param ( $Tenant = "m365x04995906", $AppID = "3669592a-9085-4f09-8c03-2b2223aa002c", $SiteID = "0a749590-8778-4779-808a-3bbb9bc1a5e1", $LibraryURL = "https://m365x04995906.sharepoint.com/sites/Remoteliving/Shared%20Documents", $Path = "C:\Users\Serka\OneDrive\Desktop\pngs\00003.jpg", $Folder = "General/Subfolder" ) #$AppCredential = Get-Credential($AppID) #region authorize $Scope = "https://graph.microsoft.com/.default" $Body = @{ client_id = $AppCredential.UserName client_secret = $AppCredential.GetNetworkCredential().password scope = $Scope grant_type = 'client_credentials' } $GraphUrl = "https://login.microsoftonline.com/$($Tenant).onmicrosoft.com/oauth2/v2.0/token" $AuthorizationRequest = Invoke-RestMethod -Uri $GraphUrl -Method "Post" -Body $Body $Access_token = $AuthorizationRequest.Access_token $Header = @{ Authorization = $AuthorizationRequest.access_token "Content-Type"= "application/json" } #endregion #region get drives $GraphUrl = "https://graph.microsoft.com/v1.0/sites/$SiteID/drives" $BodyJSON = $Body | ConvertTo-Json -Compress $Result = Invoke-RestMethod -Uri $GraphUrl -Method 'GET' -Headers $Header -ContentType "application/json" $DriveID = $Result.value| Where-Object {$_.webURL -eq $LibraryURL } | Select-Object id -ExpandProperty id If ($DriveID -eq $null){ Throw "SharePoint Library under $LibraryURL could not be found." } #endregion #region upload file $FileName = $Path.Split("\")[-1] $Url = "https://graph.microsoft.com/v1.0/drives/$DriveID/items/root:/$Folder/$($FileName):/content" Invoke-RestMethod -Uri $Url -Headers $Header -Method Put -InFile $Path -ContentType 'multipart/form-data' -Verbose #endregion
Once executed, you’ll get back following response:
VERBOSE: HTTP/1.1 PUT with 232877-byte payload VERBOSE: received -byte response of content type application/json VERBOSE: Content encoding: utf-8 @odata.context : https://graph.microsoft.com/v1.0/$metadata#drives('b%21kJV0CniHeUeAiju7m8Gl4ZmfCOoRAXJNrYB9wjbkfZ-Vmuw3EELGQ7bZlNIfSaf4')/items/$entity @microsoft.graph.downloadUrl : https://m365x04995906.sharepoint.com/sites/Remoteliving/_layouts/15/download.aspx?UniqueId=2c3c2e98-5be4-4ce2-8a81-2c0d4bab00b4&Translate=false&tempauth=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiIwMDAwMDAwMy0wMDAwLTBmZjEtY2UwMC0wMDAwMDAwMDAwMDAvbTM2NXgwNDk5NTkwNi5zaGFyZXBvaW50LmNv bUAxZjc5NWU5NS1jMDZiLTQxMDktOTI0ZS0zNTY5ZmRkZjQ5OWYiLCJpc3MiOiIwMDAwMDAwMy0wMDAwLTBmZjEtY2UwMC0wMDAwMDAwMDAwMDAiLCJuYmYiOiIxNjk3NDQ0MDk5IiwiZXhwIjoiMTY5NzQ0NzY5OSIsImVuZHBvaW50dXJsIjoiWjA4ZkI5NTdNQklCckgzRUg4VHp1N0RuT3lTWVhCMHQ4VE5zZTNvNmMvMD0iLCJlbmRwb2ludHVybExlbmd0aCI6IjE0MyIsImlzbG 9vcGJhY2siOiJUcnVlIiwiY2lkIjoiWktRTFZjNHhUMEt2RlF2YSsxMjZJZz09IiwidmVyIjoiaGFzaGVkcHJvb2Z0b2tlbiIsInNpdGVpZCI6Ik1HRTNORGsxT1RBdE9EYzNPQzAwTnpjNUxUZ3dPR0V0TTJKaVlqbGlZekZoTldVeCIsImFwcF9kaXNwbGF5bmFtZSI6IlNQU2l0ZXNfUmVhZFdyaXRlQWxsIiwibmFtZWlkIjoiMzY2OTU5MmEtOTA4NS00ZjA5LThjMDMtMmIyMjIz YWEwMDJjQDFmNzk1ZTk1LWMwNmItNDEwOS05MjRlLTM1NjlmZGRmNDk5ZiIsInJvbGVzIjoiYWxsc2l0ZXMud3JpdGUiLCJ0dCI6IjEiLCJpcGFkZHIiOiIyMC4xOTAuMTkwLjk5In0.2EMXEM184-nAFJnbOJy_PM8q5YKvOK66IoqggTX0g_E&ApiVersion=2.0 createdDateTime : 16.10.2023 08:14:59 eTag : "{2C3C2E98-5BE4-4CE2-8A81-2C0D4BAB00B4},1" id : 01NLC4VWMYFY6CZZC34JGIVAJMBVF2WAFU lastModifiedDateTime : 16.10.2023 08:14:59 name : 00003.jpg webUrl : https://m365x04995906.sharepoint.com/sites/Remoteliving/Shared%20Documents/General/Subfolder/00003.jpg cTag : "c:{2C3C2E98-5BE4-4CE2-8A81-2C0D4BAB00B4},2" size : 232877 createdBy : @{application=; user=} lastModifiedBy : @{application=; user=} parentReference : @{driveType=documentLibrary; driveId=b!kJV0CniHeUeAiju7m8Gl4ZmfCOoRAXJNrYB9wjbkfZ-Vmuw3EELGQ7bZlNIfSaf4; id=01NLC4VWOFX4E7TTHLCNB256DE3BDS7OML; name=Subfolder; path=/drives/b!kJV0CniHeUeAiju7m8Gl4ZmfCOoRAXJNrYB9wjbkfZ-Vmuw3EELGQ7bZlNIfSaf4/root:/General/Subfolder; siteId=0a749590-8778-4779-808a-3bbb9bc1a5e1} file : @{mimeType=image/jpeg; hashes=} fileSystemInfo : @{createdDateTime=16.10.2023 08:14:59; lastModifiedDateTime=16.10.2023 08:14:59} image : shared : @{scope=users}
Further Reference
You might be also interested in following articles, which are related to MS Graph API:
Security of app registration in Azure Active Directory | SPO Scripts
Create SharePoint list items using Graph API (PowerShell) (sposcripts.com)
How to get SharePoint List Items with Graph API (PowerShell) | SPO Scripts
Pingback: Upload documents to SharePoint with PowerShell solution
Pingback: نحوه آپلود فایل ها در شیرپوینت با استفاده از Graph API (PowerShell) - word-amade