Download-AllSPOFiles.ps1
<#PSScriptInfo .VERSION 1.1 .GUID c47dd6e0-14bb-4a8c-b536-18d86f1ea113 .AUTHOR Aaron Guilmette .COMPANYNAME Microsoft .COPYRIGHT 2020 .TAGS .LICENSEURI .PROJECTURI https://www.undocumented-features.com/2019/07/12/download-all-files-from-sharepoint-online/ .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES .DESCRIPTION Download all files from a given SharePoint Online site. .PRIVATEDATA #> <# .SYNOPSIS Download all files from a given SharePoint Online site. .PARAMETER Credential Just your standard, everyday PSCredential object. .PARAMETER Folder SharePoint PnP Folder parameter. .PARAMETER Force Force overwrite in destination. .PARAMETER List SharePoint PnP list parameter. .PARAMETER Match SharePoint PnP match parameter. .PARAMETER OutputPath Output path for downloaded files. Default path is current directory. .PARAMETER Sites One or more source SharePoint Online sites. Default is all sites. .PARAMETER Tenant SharePoint Online or Office 365 tenant name (such as contoso.onmicrosoft.com) .LINK https://www.undocumented-features.com/2019/07/12/download-all-files-from-sharepoint-online/ .NOTES 2020-01-28 Added -Force parameter to overwrite destination files. 2019-07-12 Initial release. #> param ( $Credential, $OutputPath = ".", [string]$Match, $List, $Folder, [switch]$Force, [array]$Sites, [Parameter(Mandatory=$true)]$Tenant ) $WarningPreference = 'SilentlyContinue' function LoadSharePointLibraries { Write-Progress -Activity "Locating SharePoint Server Client Components installation..." -Id 1 If (Test-Path 'c:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll') { Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll" Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll" Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Taxonomy.dll" Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.UserProfiles.dll" } ElseIf ($filename = (Get-ChildItem 'C:\Program Files' -Recurse -ea silentlycontinue | where { $_.name -eq 'Microsoft.SharePoint.Client.DocumentManagement.dll' })[0]) { $Directory = ($filename.DirectoryName)[0] Write-Host -ForegroundColor Green "Found SharePoint Server Client Components at $Directory." Add-Type -Path "$Directory\Microsoft.SharePoint.Client.dll" Add-Type -Path "$Directory\Microsoft.SharePoint.Client.Runtime.dll" Add-Type -Path "$Directory\Microsoft.SharePoint.Client.Taxonomy.dll" Add-Type -Path "$Directory\Microsoft.SharePoint.Client.UserProfiles.dll" } ElseIf (!(Test-Path 'C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll')) { Write-Host -ForegroundColor Yellow "This script requires the SharePoint Server Client Components. Attempting to download and install." wget 'https://download.microsoft.com/download/E/1/9/E1987F6C-4D0A-4918-AEFE-12105B59FF6A/sharepointclientcomponents_15-4711-1001_x64_en-us.msi' -OutFile ./SharePointClientComponents_15.msi wget 'https://download.microsoft.com/download/F/A/3/FA3B7088-624A-49A6-826E-5EF2CE9095DA/sharepointclientcomponents_16-4351-1000_x64_en-us.msi' -OutFile ./SharePointClientComponents_16.msi msiexec /i SharePointClientComponents_15.msi /qb msiexec /i SharePointClientComponents_16.msi /qb Sleep 60 If (Test-Path 'c:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll') { Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll" Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll" Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Taxonomy.dll" Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.UserProfiles.dll" } Else { Write-Host -NoNewLine -ForegroundColor Red "Please download the SharePoint Server Client Components from " Write-Host -NoNewLine -ForegroundColor Red "https://download.microsoft.com/download/F/A/3/FA3B7088-624A-49A6-826E-5EF2CE9095DA/sharepointclientcomponents_16-4351-1000_x64_en-us.msi " Write-Host -ForegroundColor Red "and try again." Break } } If (!(Get-Module -ListAvailable "*online.sharepoint*")) { Write-Host -ForegroundColor Yellow "This script requires the SharePoint Online Management Shell. Attempting to download and install." wget 'https://download.microsoft.com/download/0/2/E/02E7E5BA-2190-44A8-B407-BC73CA0D6B87/SharePointOnlineManagementShell_6802-1200_x64_en-us.msi' -OutFile ./SharePointOnlineManagementShell.msi msiexec /i SharePointOnlineManagementShell.msi /qb Write-Host -ForegroundColor Yellow "Please close and reopen the Windows Azure PowerShell module and re-run this script." } If (!(Get-Module -ListAvailable SharePointPnPPowerShellOnline | ? { $_.Version -ge '3.4.1812.1' })) { Install-Module SharePointPnPPowerShellOnline -Force } } function ConnectToSPO { If ($tenant -like "*.onmicrosoft.com") { $tenant = $tenant.split(".")[0] } $AdminURL = "https://$tenant-admin.sharepoint.com" Connect-SpoService -Credential $Credential -Url $AdminURL Import-Module SharePointPnPPowerShellOnline } If ($OutputPath) { $OutputPath = $OutputPath.TrimEnd("\") } LoadSharePointLibraries ConnectToSPO If (!($Sites)) { $Sites = Get-SPOSite | Select -Expand Url } $s = 0 Foreach ($Site in $Sites) { Write-Progress -Activity "Connecting to site $($Site)" -Percent (($s/$Sites.Count) * 100) -Id 1 $cmd = "Connect-PnpOnline -Url $($Site) -credentials `$Credential" Invoke-Expression $cmd Write-Progress -Activity "Gathering list of files in site $($Site)" -Percent (($s/$Sites.Count) * 100) -Id 1 $FindParams = @{ } If ($Match) { #"Match is specified as $($Match)." $FindParams.Add("Match", $Match) } else { #"Match not specified"; $FindParams.Add("Match", "*") } If ($List) { $FindParams.Add("List", $List) } If ($Folder) { $FindParams.Add("Folder",$Folder)} try { $global:files = Find-PnpFile @FindParams -ea stop} catch { $Message = $_.Exception.Message If ($Message -like "*object reference not set*") { Write-Output "Looks like the List $($List) or Folder $($Folder) isn't found in site $($Site)." } Else { Write-Output $Message } $s++ continue # go to next folder } $f = 1 $s++ Write-Progress -Activity "Downloading files from site $($Site)" -Percent (($s/$Sites.Count) * 100) -Id 1 if ($files) { foreach ($file in $files) { #$fullpath = $file.ServerRelativeUrl.ToString() $fullpath = "/" + ($file[0].Path.Identity -split (":file:/"))[1] Write-Progress -Activity "Downloading" -status "File: $($fullpath)" -perc (($f/$files.Count) * 100) -parent 1 -Id 2 try { $newdir = New-Item -Type Directory -Path "$($OutputPath)$($fullpath.ToString().Substring(0, (($fullpath.lastindexof("/") + 1))))".Replace("/", "\") -Force } catch { } $GetPnpFileParams = @{ } $GetPnpFileParams.Add('Url', $file.ServerRelativeUrl) $GetPnpFileParams.Add('Path', "$($OutputPath)$($fullpath.ToString().Substring(0, (($fullpath.lastindexof("/") + 1))))".Replace("/", "\")) $GetPnpFileParams.Add('Filname', $fullpath.Substring((($fullpath.lastindexof("/") + 1)))) $GetPnpFileParams.Add('AsFile', $true) If ($Force) { $GetPnpFileParams.Add('Force',$true)} Get-PnpFile @GetPnpFileParams $f++ } Write-Progress -Activity "Downloading" -id 2 -Completed } } |