Powershell Script to Copy Files from a Microsoft 365 Sharepoint location to a local drive
I need to move a large folder of images from Sharepoint Online to a local server for a customer as the online location is not working for their business needs.
I tried to use the SharePoint download feature but the zip file reports that it is invalid.
I decided to look into PowerShell and see if that could be used to export the files and folders.
Here is the code I ended up with. Feel free to copy and paste the following into Powershell, update the variables and save it.
# Copyright by Kettlewell.IT. Free to use and distribute with recognition
# Description of Variables to update in code below::
# $UserName: Your SharePoint 365 username (e.g., user@yourtenant.onmicrosoft.com)
# $Password: Your SharePoint 365 password
# $SiteURL: The URL of your SharePoint 365 site
# $SourceFolderURL: The server-relative URL of the folder you want to copy from (e.g., /Shared%20Documents/FolderName)
# $DestinationFolder: The local server folder where you want to copy the files to (e.g., C:\DestinationFolder)
#Set Variables
$UserName = "YourUserName@YourTenant.onmicrosoft.com"
$Password = ConvertTo-SecureString "YourPassword" -AsPlainText -Force
$SiteURL = "https://YourTenant.sharepoint.com/sites/YourSiteName/"
$SourceFolderURL = "/Shared%20Documents/FolderName"
$DestinationFolder = "C:\DestinationFolder"
#-------------DO NOT EDIT BELOW THIS LINE---------------------------
#Connect to SharePoint Online
$Credential = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $Password)
$Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$Ctx.Credentials = $Credential
#Function to copy files
function Copy-SPFiles ($SourceFolder, $DestinationFolder) {
#Download all files from Source Folder
$Files = $SourceFolder.Files
$Ctx.Load($Files)
$Ctx.ExecuteQuery()
#Loop through each file and download
Foreach ($File in $Files)
{
$FileStream = New-Object IO.FileStream($DestinationFolder + "\" + $File.Name), [System.IO.FileMode]::Create)
$FileInformation = [Microsoft.SharePoint.Client.File]::OpenBinaryDirect($Ctx, $File.ServerRelativeUrl)
$FileInformation.Stream.CopyTo($FileStream)
$FileStream.Close()
}
#Get all subfolders and loop through them recursively
$SubFolders = $SourceFolder.Folders
$Ctx.Load($SubFolders)
$Ctx.ExecuteQuery()
Foreach ($SubFolder in $SubFolders) {
$NewDestinationFolder = $DestinationFolder + "\" + $SubFolder.Name
If (!(Test-Path -Path $NewDestinationFolder -PathType Container)) {
New-Item -ItemType Directory -Force -Path $NewDestinationFolder
}
Copy-SPFiles $SubFolder $NewDestinationFolder
}
}
#Get the Source Folder from SharePoint Online
$SourceFolder = $Ctx.Web.GetFolderByServerRelativeUrl($SourceFolderURL)
$Ctx.Load($SourceFolder)
$Ctx.ExecuteQuery()
#Copy all files and subfolders recursively
Copy-SPFiles $SourceFolder $DestinationFolder
Write-Host "Files copied successfully!"
This script is provided as an example and I am not responsible for any problems you may get or any errors.
Let me know in the comments if this helps you out,
Thanks
Ian