General IT,  IT,  Microsoft 365,  PowerShell,  Sharepoint

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

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.