Download all files from SharePoint Online

Download all files from SharePoint Online


Update (2020-01-28):  I have updated this script to include the -Force parameter for Get-PnpFile, allowing you to willy-nilly overwrite destination files.

Yesterday, I came across a request for a script or method to download all files from SharePoint Online.

At first, I balked because CSOM isn’t my favorite and kind of finicky, but then remembered that we’d released the SharePoint PnP PowerShell cmdlets a while back. So, I decided to give those a peek and see what was in there, and was delighted to discover a few cmdlets–namely, Find-PnpFile and Get-PnpFile.

And thus my mini-project began.

After testing them for a while, I did find that they don’t have quite the flexibility for locating files.  In CSOM, we can use a CAML query (although I’ve had mixed results with it and generally perform some regular expression filtering/matching afterwards).  For example, perhaps I want to do something with all of the .MP3 files in a given site:

[regex]$Pattern = ‘\.mp3$’
= $ClientContextSource.Web.Lists.GetByTitle(“Documents”)
$CamlQuery = New-Object Microsoft.SharePoint.Client.CamlQuery
$CamlQuery.ViewXml = “<View Scope=’RecursiveAll’ />”
$AllItems = $Library.GetItems($camlQuery)
foreach ($obj in $allItems)
If ($obj[“FileRef”] -match $Pattern)
#write-host “File $($obj[“FileRef”]) matches.
$FilesToUpdate += $obj 

It’s like a ton of code to do something.

Find-PnpFile seems like it has much easier syntax:

Find-PnpFile -Match <string>

That’s it.  Unfortunately, string is literally just that–a single string (not a match in the regular expression kind of way).  So, we can’t do multiple file filters or anything with it, which makes it harder to include or exclude things.

That being said, I plowed on gave it the old college try.  I don’t know how it will scale for sites or document libraries with hundreds of thousands of files, but I guess that’s what the user community is for. 🙂

I pass the values submitted for ListFolder, and Match to Find-PnpFile.  The only one that’s required is Match, and if you don’t put anything in, the script assumes you want everything.  Everything will include all of the HTML, CSS, and everything else in the site.  Find-PnpFile also throws errors if you don’t have a matching folder or list (if you specify a name), and then seems to not honor the Match parameter values, so YMMV.

At any rate, go ahead and give it a whirl–let me know what you think!

Published by Aaron Guilmette

Helping companies conquer inferior technology since 1997. I spend my time developing and implementing technology solutions so people can spend less time with technology. Specialties: Active Directory and Exchange consulting and deployment, Virtualization, Disaster Recovery, Office 365, datacenter migration/consolidation, cheese.

Reader Comments

  1. Hey Aaron, thank you very much for this! I got this working but I did have to make some changes first:

    – On Line 25 it states “$Directory = ($filename.DirectoryName)[0]”. I had to remove the “[0]” as this stopped it from passing the full path to the $Directory variable, causing errors.

    – On Line 137 “Filename” is spelt wrong (you’ve got ‘Filname’) which caused another error.

    After I made these changes it worked perfectly though thank you very much!

  2. Hi Aaron, thank you very much for the script! It is the only one I could find that downloads all files from a given Site Collection for SPO. I am trying to use this script daily, and I want any updated files to replace the previous version, but it doesn’t seem to be doing that. Is there anywhere in the script you can point me to try and change that behavior?

Leave a Reply

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