Skip to content

AngeliqueDawnbringer/sharepoint-folder-sync

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SharePoint Folder Sync

Sync a local Linux folder to a SharePoint Online document library using Microsoft Graph and certificate-based Entra ID app authentication.

Features

  • Uploads local files to SharePoint Online
  • Creates remote folders as needed
  • Supports nested folders
  • Uses certificate-based app authentication
  • Supports Docker or local Python execution
  • Can optionally delete remote files not present locally

Prerequisites

  • Linux
  • Git
  • Python 3 or Docker
  • OpenSSL
  • Microsoft Entra app registration
  • Microsoft Graph Sites.Selected
  • Write access granted to the approved SharePoint site

Clone

git clone <the repository>
cd sharepoint-folder-sync

Create certificate

mkdir -p ~/sharepoint-cert
cd ~/sharepoint-cert

openssl req -x509 -newkey rsa:4096 \
  -keyout sharepoint-sync.key.pem \
  -out sharepoint-sync.cert.pem \
  -days 365 \
  -nodes \
  -subj "/CN=sharepoint-folder-sync"

openssl x509 -outform der \
  -in sharepoint-sync.cert.pem \
  -out sharepoint-sync.cert.cer

cat sharepoint-sync.key.pem sharepoint-sync.cert.pem > sharepoint-sync.combined.pem

chmod 600 sharepoint-sync.key.pem sharepoint-sync.combined.pem
chmod 644 sharepoint-sync.cert.cer

Send only this file to the Microsoft 365 administrator:

sharepoint-sync.cert.cer

Never share:

sharepoint-sync.key.pem
sharepoint-sync.combined.pem

Required values

The Microsoft 365 administrator will provide:

AZURE_TENANT_ID="<tenant-id>"
AZURE_CLIENT_ID="<client-id>"
SHAREPOINT_SITE_URL="<sharepoint-site-url>"
SHAREPOINT_LIBRARY="<document-library>"
SHAREPOINT_REMOTE_FOLDER="<target-folder>"

Example:

export AZURE_TENANT_ID="00000000-0000-0000-0000-000000000000"
export AZURE_CLIENT_ID="11111111-1111-1111-1111-111111111111"
export AZURE_CLIENT_CERTIFICATE_PATH="$HOME/sharepoint-cert/sharepoint-sync.combined.pem"

export SHAREPOINT_SITE_URL="https://tenant.sharepoint.com/sites/site"
export SHAREPOINT_LIBRARY="Documents"
export SHAREPOINT_REMOTE_FOLDER="Incoming/LinuxUpload"

Run with Docker

Build:

docker build -t sharepoint-folder-sync:latest .

Run:

docker run --rm \
  --user "$(id -u):$(id -g)" \
  -e HOME="/tmp" \
  -e AZURE_TENANT_ID="$AZURE_TENANT_ID" \
  -e AZURE_CLIENT_ID="$AZURE_CLIENT_ID" \
  -e AZURE_CLIENT_CERTIFICATE_PATH="/certs/sharepoint-sync.combined.pem" \
  -v "$HOME/sharepoint-cert:/certs:ro" \
  -v "/path/to/local/folder:/data:rw" \
  sharepoint-folder-sync:latest \
  --site-url "$SHAREPOINT_SITE_URL" \
  --library "$SHAREPOINT_LIBRARY" \
  --local-folder "/data" \
  --remote-folder "$SHAREPOINT_REMOTE_FOLDER"

Run with local Python

python3 -m venv .venv
source .venv/bin/activate
pip install azure-identity requests
python3 sync_sharepoint_library.py \
  --site-url "$SHAREPOINT_SITE_URL" \
  --library "$SHAREPOINT_LIBRARY" \
  --local-folder "/path/to/local/folder" \
  --remote-folder "$SHAREPOINT_REMOTE_FOLDER"

Dry run

python3 sync_sharepoint_library.py \
  --site-url "$SHAREPOINT_SITE_URL" \
  --library "$SHAREPOINT_LIBRARY" \
  --local-folder "/path/to/local/folder" \
  --remote-folder "$SHAREPOINT_REMOTE_FOLDER" \
  --dry-run

Mirror mode

Deletes remote files under the target folder that no longer exist locally.

python3 sync_sharepoint_library.py \
  --site-url "$SHAREPOINT_SITE_URL" \
  --library "$SHAREPOINT_LIBRARY" \
  --local-folder "/path/to/local/folder" \
  --remote-folder "$SHAREPOINT_REMOTE_FOLDER" \
  --delete-remote-extra

Use with care.

Microsoft 365 admin setup

  1. Create an Entra app registration.
  2. Upload the public certificate.
  3. Add Microsoft Graph application permission:
Sites.Selected
  1. Grant admin consent.
  2. Grant the app Write access to the approved SharePoint site.

Example with PnP.PowerShell:

$siteUrl = "https://tenant.sharepoint.com/sites/site"
$appId = "<application-client-id>"

Connect-PnPOnline -Url $siteUrl -Interactive

Grant-PnPEntraIDAppSitePermission `
  -AppId $appId `
  -DisplayName "sharepoint-folder-sync" `
  -Site $siteUrl `
  -Permissions Write

If you never used PnP.PowerShell before, register it

Register-PnPEntraIDAppForInteractiveLogin `
   -ApplicationName "PnP PowerShell" `
   -SharePointDelegatePermissions "AllSites.FullControl" `
   -Tenant "<tenant-id>"

you can then login with

Connect-PnPOnline -Url https://<tenant>.sharepoint.com -ClientId  <client-id>

Notes

  • The private key stays on the Linux machine.
  • The app should use Sites.Selected, not tenant wide SharePoint permissions.
  • The script writes .spo_sync_manifest.json into the local folder to track uploaded files.
  • Docker runs should (often) include --user "$(id -u):$(id -g)" so the manifest can be written.

About

Sharepoint File Uploader using Ms Graph

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages