OneDrive Document download using Powershell

The best way to downloading all documents from OneDrive is to sync on local machine using OneDrive Sync client. But there could be scenarios where you need to get all data of another user, you cannot connect multiple accounts OneDrive Sync client and, in that scenario, you can use PowerShell script to download all content for a user.

I have written a PowerShell script using PnP PowerShell cmdlets which is very helpful to download all documents for a user.

###########################################################################
#Author: Adnan Amin
#blog: Https://mstechtalk.com
#Downloading files from OneDrive to local machine
###########################################################################

$webUrl = "https://mstalk-my.sharepoint.com/personal/<user>_mstechtalk_com";
$listUrl = "Documents";
$destination = "F:\test"

#Connect-PnPOnline -Url $webUrl 
Connect-PnPOnline -Url $webUrl -UseWebLogin;
$web = Get-PnPWeb
$list = Get-PNPList -Identity $listUrl

function ProcessFolder($folderUrl, $destinationFolder) {

    $folder = Get-PnPFolder -RelativeUrl $folderUrl
    $tempfiles = Get-PnPProperty -ClientObject $folder -Property Files
   
    if (!(Test-Path -path $destinationfolder)) {
        $dest = New-Item $destinationfolder -type directory 
    }

    $total = $folder.Files.Count
    For ($i = 0; $i -lt $total; $i++) {
        $file = $folder.Files[$i]
        Write-Host "Copying file " $file.Name " at " $destinationfolder
        Get-PnPFile -ServerRelativeUrl $file.ServerRelativeUrl -Path $destinationfolder -FileName $file.Name -AsFile
    }
}

function ProcessSubFolders($folders, $currentPath) {
    foreach ($folder in $folders) {
        $tempurls = Get-PnPProperty -ClientObject $folder -Property ServerRelativeUrl    
        #Avoid Forms folders
        if ($folder.Name -ne "Forms") {
            $targetFolder = $currentPath +"\"+ $folder.Name;
            ProcessFolder $folder.ServerRelativeUrl.Substring($web.ServerRelativeUrl.Length) $targetFolder 
            $tempfolders = Get-PnPProperty -ClientObject $folder -Property Folders
            write-host "Processing folder: " $folder.Name " .. at " $currentPath
            ProcessSubFolders $tempfolders $targetFolder
        }
    }
}

ProcessFolder $listUrl $destination + "\" 
#Write-Host "listUrl: " $listUrl

#Download files in folders
$tempfolders = Get-PnPProperty -ClientObject $list.RootFolder -Property Folders
Write-Host "tempfolders: " $tempfolders
ProcessSubFolders $tempfolders $destination + "\"

Download could take time as it all depends upon the number of documents. If job get stuck or stopped due to some error, I would recommend you to download files in chunks by passing the URLs of OneDrive folders instead of full OneDrive path, you need to run the script multiple times but this will minimize the number of errors.

Adnan is two time SharePoint MVP (Most Valuable Professional) with over 12 years of extensive experience with major expertise on SharePoint Server, Office 365, .Net Platform and Microsoft BI. He is currently working SharePoint Architect at FMT Consultants. He is MCT Regional Lead for Pakistan Chapter since 2012. He is working on SharePoint for past nine years and worked on different intranet/intranet solutions for private & govt. sector majorly in Gulf region, which include OOB and customized solutions. He is a trainer, technology evangelist and also speaks in community forums.

Leave a Reply