Copy SharePoint files to local drive
There are a number of ways of copying or syncing files from SharePoint to your local drive or folder.
- OneDrive Sync
- WebDAV download
- REST API
- Microsoft Graph API
The OneDrive sync is pretty straightforward and there are lots of info online.
My goal is to automate this process without having to be logged in when it happens.
The following suggestions are from Copilot.
The WebDAV method
# Define source and destination paths
$sourcePath = "\\sharepointsite@SSL\DavWWWRoot\sites\YourSite\Shared Documents\FolderName"
$destinationPath = "C:\Local\BackupFolder"
# Create destination folder if it doesn't exist
if (!(Test-Path -Path $destinationPath)) {
New-Item -ItemType Directory -Path $destinationPath
}
# Copy files
try {
Copy-Item -Path "$sourcePath\*" -Destination $destinationPath -Recurse -Force
Write-Host "Files copied successfully from SharePoint to local drive."
} catch {
Write-Error "Error copying files: $_"
}
The REST API method
This method requires the PnP.PowerShell module for PowerShell.
Install-Module -Name PnP.PowerShell -Force
After installing the module you are ready to run this script.
# Connect to SharePoint Online
$siteUrl = "https://yourtenant.sharepoint.com/sites/yoursite"
Connect-PnPOnline -Url $siteUrl -Interactive
# Define the SharePoint folder and local destination
$sharePointFolder = "/Shared Documents/FolderName"
$localDestination = "C:\Local\BackupFolder"
# Create local folder if it doesn't exist
if (!(Test-Path -Path $localDestination)) {
New-Item -ItemType Directory -Path $localDestination
}
# Get files from the SharePoint folder
$files = Get-PnPFolderItem -FolderSiteRelativeUrl $sharePointFolder -ItemType File
# Download each file
foreach ($file in $files) {
$fileName = $file.Name
$serverRelativeUrl = $file.ServerRelativeUrl
$localPath = Join-Path -Path $localDestination -ChildPath $fileName
Get-PnPFile -Url $serverRelativeUrl -Path $localDestination -FileName $fileName -AsFile -Force
Write-Host "Downloaded: $fileName"
}
Write-Host "All files downloaded successfully."
The MS Graph API method
Using Microsoft Graph API to copy files from a SharePoint folder to a local drive via PowerShell is a powerful and flexible method, especially for modern SharePoint Online environments. Here's a step-by-step guide to help you set it up.
Prerequisites
Azure AD App Registration with delegated or application permissions:
Files.Read.All
Sites.Read.All
User.Read
Admin consent granted for the app. Client ID, Tenant ID, and Client Secret (or use device code flow for interactive login).
PowerShell modules:
Microsoft.Graph
Microsoft.Graph.Authentication
Install them if needed:
Install-Module Microsoft.Graph -Scope CurrentUser
To install the module for all users, change scope to AllUsers
Authentication (Device Code Flow)
Connect-MgGraph -Scopes "Files.Read.All", "Sites.Read.All"
Script to Download Files from SharePoint Folder
Here’s a simplified version that:
- Connects to Microsoft Graph
- Lists files in a SharePoint folder
- Downloads them to a local path
This is some sample code:
# Connect to Microsoft Graph
Connect-MgGraph -Scopes "Files.Read.All", "Sites.Read.All"
# Define variables
$siteName = "YourSiteName"
$siteDomain = "yourtenant.sharepoint.com"
$driveName = "Documents" # Usually "Documents" for default doc library
$folderPath = "FolderName" # Relative path inside the document library
$localPath = "C:\Local\BackupFolder"
# Create local folder if it doesn't exist
if (!(Test-Path -Path $localPath)) {
New-Item -ItemType Directory -Path $localPath
}
# Get the site ID
$site = Get-MgSite -Hostname $siteDomain -SiteCollectionPath "/sites/$siteName"
# Get the drive ID (document library)
$drive = Get-MgSiteDrive -SiteId $site.Id | Where-Object { $_.Name -eq $driveName }
# Get items in the folder
$items = Get-MgDriveItemChild -DriveId $drive.Id -ItemId "root:/$folderPath"
# Download each file
foreach ($item in $items) {
if ($item.File) {
$downloadUrl = $item.AdditionalProperties["@microsoft.graph.downloadUrl"]
$filePath = Join-Path -Path $localPath -ChildPath $item.Name
Invoke-WebRequest -Uri $downloadUrl -OutFile $filePath
Write-Host "Downloaded: $item.Name"
}
}
Notes
- This script uses Microsoft Graph SDK for PowerShell.
- You can also use client credentials flow for unattended scripts (requires secret or certificate).
- The @microsoft.graph.downloadUrl is a temporary URL to directly download the file.
Setup Azure AD app registration
To use Microsoft Graph API with client credentials flow in PowerShell, you'll need to set up an Azure AD app registration and use its credentials to authenticate without user interaction. This is ideal for automated scripts or background services.
Step-by-Step Setup
-
Register an Azure AD App Go to Azure Portal → Azure Active Directory → App registrations → New registration.
Name: e.g., GraphFileDownloader Supported account types: Choose Single tenant or Multitenant depending on your org. Redirect URI: Leave blank for client credentials flow. -
Create a Client Secret
Go to Certificates & secrets → New client secret Save the value securely (you’ll use it in your script)
-
Assign API Permissions
Go to API permissions → Add a permission → Microsoft Graph
Choose Application permissions Add:
Sites.Read.All Files.Read.AllClick Grant admin consent.
PowerShell Script Using Client Credentials
Install required module:
Install-Module Microsoft.Graph -Scope CurrentUser
Then use this script:
# Define credentials
$tenantId = "your-tenant-id"
$clientId = "your-client-id"
$clientSecret = "your-client-secret"
# Get token
$body = @{
grant_type = "client_credentials"
scope = "https://graph.microsoft.com/.default"
client_id = $clientId
client_secret = $clientSecret
}
$tokenResponse = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" -Method POST -Body $body
$accessToken = $tokenResponse.access_token
# Define SharePoint site and folder
$siteUrl = "https://yourtenant.sharepoint.com/sites/yoursite"
$headers = @{ Authorization = "Bearer $accessToken" }
# Get site ID
$siteInfo = Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/sites/yourtenant.sharepoint.com:/sites/yoursite" -Headers $headers
$siteId = $siteInfo.id
# Get drive ID (usually "Documents")
$driveInfo = Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/sites/$siteId/drives" -Headers $headers
$driveId = ($driveInfo.value | Where-Object { $_.name -eq "Documents" }).id
# Get files in folder
$folderPath = "FolderName"
$items = Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/drives/$driveId/root:/$folderPath:/children" -Headers $headers
# Download files
$localPath = "C:\Local\BackupFolder"
if (!(Test-Path -Path $localPath)) {
New-Item -ItemType Directory -Path $localPath
}
foreach ($item in $items.value) {
if ($item.file) {
$downloadUrl = $item."@microsoft.graph.downloadUrl"
$filePath = Join-Path -Path $localPath -ChildPath $item.name
Invoke-WebRequest -Uri $downloadUrl -OutFile $filePath
Write-Host "Downloaded: $($item.name)"
}
}
Summary
This script:
- Authenticates using client credentials
- Queries SharePoint via Graph API
- Downloads files to a local folder
You can find the tenant-id by:
- Go to Azure Portal
- Navigate to Azure Active Directory
- Under Overview, look for: Tenant ID (also called Directory ID)
You can find the client-id by:
-
In the Azure Portal, go to Azure Active Directory
-
Click on App registrations
-
Select your registered app (e.g., GraphFileDownloader) Under Overview, you'll see:
Application (client) ID → This is your Client ID
Optional: Find Client Secret
If you've already created a client secret:
Go to your app → Certificates & secrets Under Client secrets, copy the Value (not the Secret ID)
Note: You can only copy the secret value when it's first created. If you lost it, you'll need to generate a new one.