---
name: sharepoint-graph-large-file-upload
description: Uploading files to SharePoint via Graph — simple PUT <4MB, chunked upload session >=4MB; verify counts via delta
metadata:
  type: reference
---

Pushing a folder tree into a SharePoint doc library via Microsoft Graph (app-only):

- **<4MB:** simple `PUT /drives/{drive}/root:/{path}:/content`.
- **>=4MB:** MUST use an **upload session** — `POST .../root:/{path}:/createUploadSession`
  then `PUT` the file in chunks (multiple of 320 KiB; 10 MB works) with a
  `Content-Range: bytes {start}-{end}/{total}` header. In PowerShell 5.1
  `Invoke-RestMethod -Headers @{ 'Content-Range'=... }` handles this fine. A naive script that
  only does <4MB PUTs will silently skip every large file and never reach the target count.
- **Long Windows paths (>260):** prefix the local path with `\\?\` for `[IO.File]` reads.
- **Idempotent sync:** existence-check each file (`GET root:/{path}?$select=size`) and skip if
  size matches — this also catches/repairs partial-upload residue from earlier failed runs.
- **Throughput:** a single sequential upload stream to SharePoint Online plateaus ~40 Mbps
  regardless of link speed (per-session SPO throttle + PS5.1 HTTP stack + Expect100Continue).
  For speed use parallel file streams + larger chunks + `Expect100Continue=$false`.
- **Verify total file count** with the Graph **delta** endpoint
  (`/drives/{drive}/root/delta`) — whole-drive enumeration in a few paged calls, far cheaper
  than recursive `/children`.

Proven end-to-end on Birth Biologic Quality Systems (3,768 files, 301 >=4MB, ~29.7 GB;
largest 3.94 GB). Dispatched via GuruRMM — see [[gururmm-command-timeout-seconds]].
