How to Download a Folder from SharePoint Online using PowerShell?

Requirement: Download folder from SharePoint Online

How to Download a Folder from SharePoint Online?

To download a folder in SharePoint online, follow these steps:

  • Login to your SharePoint Online Site, Navigate to the Folder you want to download.
  • Right-click on the Folder  >> Choose “Download” from the context menu. You can also use the “Download” button from the toolbar.
  • This brings you a Zip file with the Selected folder and its Sub-Folders and its files.
    powershell download folder from sharepoint online

    Quite simple, huh? Let’s see how to download a SharePoint Online folder using PowerShell.

SharePoint Online: Download Folder using PowerShell

Now, when we need to download a folder repeatedly, or automatically on a scheduled basis, we can utilize PowerShell. Here is my PowerShell to download a folder from SharePoint Online.  

#Load SharePoint CSOM Assemblies
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"
 
Function Download-SPOFolder()
{ 
    param
    (
        [Parameter(Mandatory=$true)] [string] $SiteURL,
        [Parameter(Mandatory=$true)] [Microsoft.SharePoint.Client.Folder] $SourceFolder,
        [Parameter(Mandatory=$true)] [string] $TargetFolder
    )
    Try {
         
        #Create Local Folder, if it doesn't exist
        $FolderName = ($SourceFolder.ServerRelativeURL) -replace "/","\"
        $LocalFolder = $TargetFolder + $FolderName
        If (!(Test-Path -Path $LocalFolder)) {
                New-Item -ItemType Directory -Path $LocalFolder | Out-Null
        }
         
        #Get all Files from the folder
        $FilesColl = $SourceFolder.Files
        $Ctx.Load($FilesColl)
        $Ctx.ExecuteQuery()
 
        #Iterate through each file and download
        Foreach($File in $FilesColl)
        {
            $TargetFile = $LocalFolder+"\"+$File.Name
            #Download the file
            $FileInfo = [Microsoft.SharePoint.Client.File]::OpenBinaryDirect($Ctx,$File.ServerRelativeURL)
            $WriteStream = [System.IO.File]::Open($TargetFile,[System.IO.FileMode]::Create)
            $FileInfo.Stream.CopyTo($WriteStream)
            $WriteStream.Close()
            write-host -f Green "Downloaded File:"$TargetFile
        }
         
        #Process Sub Folders
        $SubFolders = $SourceFolder.Folders
        $Ctx.Load($SubFolders)
        $Ctx.ExecuteQuery()
        Foreach($Folder in $SubFolders)
        {
            If($Folder.Name -ne "Forms")
            {
                #Call the function recursively
                Download-SPOFolder -SiteURL $SiteURL -SourceFolder $Folder -TargetFolder $TargetFolder
            }
        }
     }
    Catch {
        write-host -f Red "Error Downloading Folder!" $_.Exception.Message
    }
}
 
#Set parameter values
$SiteURL="https://crescent.sharepoint.com"
$FolderRelativeUrl ="Shared Documents/Reports"
$TargetFolder="C:\Docs"
 
#Setup Credentials to connect
$Cred= Get-Credential
$Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)
 
#Setup the context
$Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$Ctx.Credentials = $Credentials

#Get the Web
$Web = $Ctx.Web
$Ctx.Load($Web)
$Ctx.ExecuteQuery()
$Web.ServerRelativeUrl+$FolderRelativeUrl
      
#Get the Folder
$SourceFolder = $Web.GetFolderByServerRelativeUrl($Web.ServerRelativeUrl+$FolderRelativeUrl)
$Ctx.Load($SourceFolder)
$Ctx.ExecuteQuery()

#Call the function to download Folder 
Download-SPOFolder -SiteURL $SiteURL -SourceFolder $SourceFolder -TargetFolder $TargetFolder 

PnP PowerShell to Download a Folder from SharePoint Online

This PowerShell script downloads all files and sub-folders from Folder from SharePoint Online document library to local directory

#Function to Download All Files from a SharePoint Online Folder - Recursively  
Function Download-SPOFolder([Microsoft.SharePoint.Client.Folder]$Folder, $DestinationFolder)
{  
    #Get the Folder's Site Relative URL
    $FolderURL = $Folder.ServerRelativeUrl.Substring($Folder.Context.Web.ServerRelativeUrl.Length)
    $LocalFolder = $DestinationFolder + ($FolderURL -replace "/","\")
    #Create Local Folder, if it doesn't exist
    If (!(Test-Path -Path $LocalFolder)) {
            New-Item -ItemType Directory -Path $LocalFolder | Out-Null
            Write-host -f Yellow "Created a New Folder '$LocalFolder'"
    }
           
    #Get all Files from the folder
    $FilesColl = Get-PnPFolderItem -FolderSiteRelativeUrl $FolderURL -ItemType File 
    #Iterate through each file and download
    Foreach($File in $FilesColl)
    {
        Get-PnPFile -ServerRelativeUrl $File.ServerRelativeUrl -Path $LocalFolder -FileName $File.Name -AsFile -force
        Write-host -f Green "`tDownloaded File from '$($File.ServerRelativeUrl)'"
    }
    #Get Subfolders of the Folder and call the function recursively
    $SubFolders = Get-PnPFolderItem -FolderSiteRelativeUrl $FolderURL -ItemType Folder
    Foreach ($Folder in $SubFolders | Where {$_.Name -ne "Forms"})
    {
        Download-SPOFolder $Folder $DestinationFolder
    }
}  
 
#Set Parameters
$SiteURL = "https://crescent.sharepoint.com/sites/marketing"
$FolderSiteRelativeURL = "/Team Documents/2018"
$DownloadPath ="C:\Docs"
 
#Connect to PnP Online
Connect-PnPOnline -Url $SiteURL -UseWebLogin
 
#Get the folder to download
$Folder = Get-PnPFolder -Url $FolderSiteRelativeURL
 
#Call the function to download the folder
Download-SPOFolder $Folder $DownloadPath

Salaudeen Rajack

Salaudeen Rajack is a SharePoint Architect with Two decades of SharePoint Experience. He loves sharing his knowledge and experiences with the SharePoint community, through his real-world articles!

2 thoughts on “How to Download a Folder from SharePoint Online using PowerShell?

  • October 15, 2021 at 5:07 AM

    Download-SPOFolder : Cannot process argument transformation on parameter ‘Folder’. Cannot convert the “Microsoft.SharePoint.Client.Folder” value of type “Microsoft.SharePoint.Client.Folder” to type “Microsoft.SharePoint.Client.Folder”.
    At line:1 char:20
    + Download-SPOFolder $Folder $DownloadPath
    + ~~~~~~~
    + CategoryInfo : InvalidData: (:) [Download-SPOFolder], ParameterBindingArgumentTransformationException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,Download-SPOFolder

    Reply
  • May 25, 2021 at 5:59 PM

    This script is almost perfect for me, but I have a large list and it fails on a folder that exceeds the threshold. Is there anyway to batch up the download of the files in a large folder?

    Reply

Leave a Reply