SharePoint Online: PowerShell to Download All Files from a Document Library

Requirement: PowerShell to download all files from a SharePoint Online document library.

How to Download a Document Library in SharePoint Online?

Downloading multiple files at once from SharePoint Online is as easy as copying files using Windows Explorer. To download all files from a SharePoint Online document library,

  • Navigate to your SharePoint Online document library >> Select all Files and folders
  • Click on the “Download” button from the toolbar. This provides you a Zip file with all files and folders from the document library.
    sharepoint online powershell download document library

Please note, this feature is available only with modern SharePoint Online UI. Now, let’s download documents from the SharePoint Online document library using PowerShell.

You can also use OneDrive sync client to download a document library to your local machine! Just Go to the document library or folder you want to download >> Click on the sync button in the toolbar and follow the wizard!

SharePoint Online: Download All Files from a Library using PowerShell CSOM

We can use PowerShell to download a document library in SharePoint Online. But why PowerShell? Because Explorer view didn’t work! Here is the SharePoint Online PowerShell to download document library:

#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-FilesFromLibrary()
{ 
    param
    (
        [Parameter(Mandatory=$true)] [string] $SiteURL,
        [Parameter(Mandatory=$true)] [string] $LibraryName,
        [Parameter(Mandatory=$true)] [string] $TargetFolder
    )

    Try {
        #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 all files from the Library
        $List = $Ctx.Web.Lists.GetByTitle($LibraryName)
        $Ctx.Load($List)
        $Ctx.ExecuteQuery()
        
        #Get Files from the Folder
        $Folder = $List.RootFolder
        $FilesColl = $Folder.Files
        $Ctx.Load($FilesColl)
        $Ctx.ExecuteQuery()

        Foreach($File in $FilesColl)
        {
            $TargetFile = $TargetFolder+$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 "All Files from Library '$LibraryName' Downloaded to Folder '$TargetFolder' Successfully!" $_.Exception.Message
  }
    Catch {
        write-host -f Red "Error Downloading Files from Library!" $_.Exception.Message
    }
}

#Set parameter values
$SiteURL="https://crescent.sharepoint.com/sites/sales/"
$LibraryName="Documents"
$TargetFolder="C:\Documents\"

#Call the function to download file 
Download-FilesFromLibrary -SiteURL $SiteURL -LibraryName $LibraryName -TargetFolder $TargetFolder

This PowerShell script downloads all files from the library. What if your Library has Sub-Folders? Well, let’s change the PowerShell to download a library from SharePoint Online.

Download All Files including Sub-Folders from Library using PowerShell:

Let’s download files from the SharePoint Online document library using PowerShell, including all files from all sub-folders.

#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-AllFilesFromLibrary()
{ 
    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-AllFilesFromLibrary -SiteURL $SiteURL -SourceFolder $Folder -TargetFolder $TargetFolder
            }
        }
  }
    Catch {
        write-host -f Red "Error Downloading Files from Library!" $_.Exception.Message
    }
}

#Set parameter values
$SiteURL="https://crescent.sharepoint.com/sites/sales/"
$LibraryName="Documents"
$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 Library
$List = $Ctx.Web.Lists.GetByTitle($LibraryName)
$Ctx.Load($List)
$Ctx.Load($List.RootFolder)
$Ctx.ExecuteQuery()

#Call the function: sharepoint online download multiple files powershell
Download-AllFilesFromLibrary -SiteURL $SiteURL -SourceFolder $List.RootFolder -TargetFolder $TargetFolder

PnP PowerShell to Download a Document Library from SharePoint Online

This PowerShell script downloads all files and folders from the document library to the 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"
$LibraryURL = "/Shared Documents" #Site Relative URL
$DownloadPath ="C:\Temp\Docs\"

#Connect to PnP Online
Connect-PnPOnline -Url $SiteURL -Credentials (Get-Credential)  

#Get The Root folder of the Library
$Folder = Get-PnPFolder -Url $LibraryURL

#Call the function to download the document library
Download-SPOFolder $Folder $DownloadPath

Alternate Method: How to download a document library from SharePoint Online?

#Set Parameters
$TenantSiteURL = "https://crescent.sharepoint.com"
$SiteRelativeURL = "/sites/marketing"
$LibraryName = "Project Documents"
$DownloadPath ="C:\Temp\Docs"

#Connect to PnP Online as Virtual Drive "SPO:\"
Connect-PnPOnline -Url $TenantSiteURL -CreateDrive -Credentials (Get-Credential)

#Change the Path and navigate to the source site
Set-Location -Path SPO:\$SiteRelativeURL

#Download Document Library to Local Drive
Copy-PnpItemProxy -Recurse -Force $LibraryName $DownloadPath

Can I download all files from all libraries in a site? Sure, You can either iterate through all document libraries and call the function or use this method: How to Download All Files from SharePoint Online Site using PowerShell?

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!

6 thoughts on “SharePoint Online: PowerShell to Download All Files from a Document Library

  • October 8, 2021 at 8:05 PM

    Hey – thank you for this work.

    I had one question on, how do we get the COM 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”

    I get an error out of these.

    Thank you

    Reply
    • October 8, 2021 at 9:00 PM

      Install the SharePoint Online PowerShell Module, and then you don’t have to reference these assemblies (Because, CSOM is a subset of SharePoint Online PowerShell Module).

      Install-Module Microsoft.Online.SharePoint.PowerShell

      Reply
  • February 3, 2020 at 7:58 PM

    Thanks for sharing this script. We have sub folders under each Library. Is there any way I can download all Libraries and sub folders under it ? My main SPO site name is https://xyz.sharepoint.com/ and I have multiple Libraries on this site. Each Libraries have sub folder and files under neath. Please advice.

    Reply
  • February 19, 2019 at 9:29 PM

    Thank you! A Powershell newbie, I needed a script which would download all current files and their versions from SharePoint. Accessing the versions proved to be a challenge as various scripts I tried either came up with (404) Not Found or (403) Forbidden. I was able to piece together a function which I call from your script. Within your Foreach($File in $FilesColl) loop, I added GetFileVersions as the last statement. That calls the below function.

    Function GetFileVersions
    {
    #Get versions of specific document from library
    $fileVersions = $file.Versions;
    $ctx.Load($fileVersions);
    $ctx.ExecuteQuery();
    $vcount = $fileversions.count;

    If ($vcount -ne “0” ) {
    # Download all versions of specific file as individual docs
    $fname,$fext = $file.name.split(‘.’); # Separate filename and extension to different variables
    foreach ($fversion in $fileVersions) {
    $str = $fversion.OpenBinaryStream();
    $ctx.ExecuteQuery();
    $dtime = $fversion.created.ToString(“u”) -replace “:”,””; # Convert date/time created to formatted string and replace semicolons in the time with blank
    $filename =$localfolder + “” + $fname + “~” + $dtime + “.” + $fext ; # Compose the filename as the target folder, file name + ~+ datetime created.fileextension (i.e. book~2019-02-12 153659Z.xlsx)
    $fs = New-Object IO.FileStream $filename ,’Create’,’Write’,’Read’;
    $str.Value.CopyTo($fs);

    #To use the Write-Log function, see the script at https://gallery.technet.microsoft.com/scriptcenter/Write-Log-PowerShell-999c32d0
    #$vmessage = $filename + “*” + $fversion.versionlabel; # Message to write to the log file
    #Write-Log $vmessage;

    $fs.Close();
    }
    if ($fs.isdisposable) {$fs.Dispose();}
    }
    }

    Reply

Leave a Reply