Last active
January 28, 2024 00:35
-
-
Save RylandDeGregory/f911cf0c37fdf0b5932d4b32c0c7b008 to your computer and use it in GitHub Desktop.
Recursively download all files from a SharePoint Document Library folder using the Microsoft Graph PowerShell SDK.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.SYNOPSIS | |
This script will download all files from a specified SharePoint Document Library path. | |
.EXAMPLE | |
$ScriptParams = @{ | |
SharePointTenant = 'mycompany.sharepoint.com' | |
SiteName = 'mysite/my subsite' | |
DocumentLibraryName = 'Documents' | |
DocumentLibraryPath = 'my directory/my subdirectory' | |
LastModifiedDate = (Get-Date '2024-01-01') | |
} | |
Start-MgSPOLibraryDownload @ScriptParams | |
#> | |
[CmdletBinding()] | |
param ( | |
[Parameter(Mandatory)] | |
[string]$SharePointTenant, | |
[Parameter(Mandatory)] | |
[string]$SiteName, | |
[Parameter(Mandatory)] | |
[string]$DocumentLibraryName, | |
[Parameter(Mandatory)] | |
[string]$DocumentLibraryPath, | |
# Only process files modified after this date | |
[Parameter()] | |
[datetime]$LastModifiedDate | |
) | |
#region Init | |
$ErrorActionPreference = 'Stop' | |
# Define the base URL for Microsoft Graph API | |
$GraphEndpoint = 'https://graph.microsoft.com/v1.0' | |
# Define SharePoint details | |
$DocumentLibraryFullPath = "$SiteName/$DocumentLibraryName/$DocumentLibraryPath" | |
#endregion Init | |
#region Login | |
try { | |
# Connect to Microsoft Graph with the required API Scope | |
Write-Output 'Connect to Microsoft Graph' | |
Connect-MgGraph -Scopes 'Sites.Read.All' -NoWelcome | |
} catch { | |
Write-Error "Failed to connect to Microsoft Graph: $_" | |
} | |
#endregion Login | |
# region Functions | |
function Get-SPODriveItemsRecursively { | |
param( | |
[Parameter(Mandatory)] | |
[string] $GraphEndpoint, | |
[Parameter(Mandatory)] | |
[string]$FolderId, | |
[Parameter(Mandatory)] | |
[string]$DriveId | |
) | |
try { | |
# Get the child items of the specified folder | |
Write-Verbose "Getting child items of folder [$FolderId]" | |
$DriveItems = Invoke-MgGraphRequest -Method GET -Uri "$GraphEndpoint/drives/$DriveId/items/$FolderId/children" | |
} catch { | |
Write-Error "Failed to get child items in folder [$FolderId]: $_" | |
} | |
foreach ($Item in $DriveItems.value) { | |
if ($Item.folder) { | |
# Recursively get the children of the folder | |
Get-SPODriveItemsRecursively -GraphEndpoint $GraphEndpoint -FolderId $Item.id -DriveId $DriveId | |
} else { | |
$Item | |
} | |
} | |
} | |
#endregion Functions | |
#region GetDriveId | |
try { | |
# Get SharePoint site details | |
Write-Output "Get SharePoint site [$SharePointTenant/$SiteName] details" | |
$Site = Invoke-MgGraphRequest -Method GET -Uri "$GraphEndpoint/sites/$SharePointTenant`:/sites/$SiteName" | |
} catch { | |
Write-Error "Failed to get SharePoint site [$SharePointTenant/$SiteName] details using Microsoft Graph: $_" | |
} | |
# Extract the Site ID and SubSite ID from the Site details | |
$SiteId = $Site.id.Split(',')[1] | |
$SubSiteId = $Site.id.Split(',')[2] | |
try { | |
# Get the Drives (Document Libraries) in the Site | |
Write-Output "Get a list of Document Libraries in SharePoint site [$SiteName]" | |
$SiteDrives = Invoke-MgGraphRequest -Method GET -Uri "$GraphEndpoint/sites/$SiteId/sites/$SubSiteId/drives" | |
} catch { | |
Write-Error "Failed to get a list of Document Libraries in SharePoint site [$SiteName]: $_" | |
} | |
# Find the Drive ID of the specified Document Library | |
$DriveId = $SiteDrives.value | Where-Object { $_.name -eq $DocumentLibraryName } | Select-Object -ExpandProperty Id | |
#endregion GetDriveId | |
#region GetSharePointItems | |
try { | |
# Get the details of the specified path in the Document Library | |
Write-Output "Get the Item ID of the Document Library path [$DocumentLibraryFullPath]" | |
$DocumentLibraryPathId = Invoke-MgGraphRequest -Method GET -Uri "$GraphEndpoint/drives/$DriveId/root:/$DocumentLibraryPath" | Select-Object -ExpandProperty Id | |
} catch { | |
Write-Error "Failed to get the Item ID of the Document Library path [$DocumentLibraryFullPath]: $_" | |
} | |
# Recursively get all items in the specified Document Library path | |
Write-Output "Recursively retrieve all items in the SharePoint Document Library path [$DocumentLibraryFullPath]" | |
$DocumentLibraryPathItems = Get-SPODriveItemsRecursively -GraphEndpoint $GraphEndpoint -FolderId $DocumentLibraryPathId -DriveId $DriveId | |
# Filter folders out of the list of items to process | |
$DocumentLibraryFiles = $DocumentLibraryPathItems | Where-Object { $_.file } | |
# Filter files based on LastModifiedDateTime if a cutoff date is provided | |
if ($LastModifiedDate) { | |
$DocumentLibraryFiles = $DocumentLibraryFiles | Where-Object { $_.lastModifiedDateTime -gt $LastModifiedDate } | |
} | |
Write-Output "Processing [$($DocumentLibraryFiles.Count)] files in the SharePoint Document Library path [$DocumentLibraryFullPath]" | |
#endregion GetSharePointItems | |
#region DownloadFiles | |
$CompletedFiles = 0 | |
foreach ($DocumentLibraryFile in $DocumentLibraryFiles) { | |
# Parse SharePoint Document Library path | |
$SharePointFilePath = $DocumentLibraryFile.parentReference.path.split('/root:/')[1] | |
# Define local path for the file | |
$LocalPath = "$($env:TEMP)\$($DocumentLibraryFile.id)_$($DocumentLibraryFile.name)" | |
Write-Output "Processing [$([math]::Round($DocumentLibraryFile.Size / 1kb, 2)) KB] file [$($DocumentLibraryFile.name) ($($DocumentLibraryFile.id))]" | |
try { | |
# Download file from SharePoint | |
Invoke-RestMethod -Uri $DocumentLibraryFile.'@microsoft.graph.downloadUrl' -OutFile $LocalPath -ProgressAction SilentlyContinue | |
$CompletedFiles++ | |
} catch { | |
Write-Warning "Failed to download file [$SharePointFilePath/$($DocumentLibraryFile.name) ($($DocumentLibraryFile.id))] from SharePoint Online: $_" | |
} | |
} | |
#endregion DownloadFiles | |
Write-Output "Complete. Downloaded [$CompletedFiles] files from SharePoint Online." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment