NAVANEM
medium4 steps · 6 min read · jun 25, 2026 · 23:43 utc

Download OneDrive Files with PowerShell and Microsoft Graph

Bulk-export OneDrive files for multiple Microsoft 365 users using PowerShell and the Microsoft Graph API - no third-party tools required. Step-by-step for sysadmins.

by Emanuel De Almeida

Illustration of an IT sysadmin bulk-exporting OneDrive files for multiple Microsoft 365 users with PowerShell and Microsoft Graph, showing user accounts, folders, and automation flow.

TL;DR

  • This guide walks you through a PowerShell script that uses the Microsoft Graph API to bulk-download OneDrive files for any number of Microsoft 365 users from a CSV list.
  • The script requires Directory.Read.All, Sites.Read.All, and Files.Read.All Graph scopes, plus Site Collection Administrator access on each target OneDrive.
  • Output lands in per-user sub-folders under a path you specify - green console lines confirm each file saved, red lines flag users to revisit.

This guide shows you how to export a local copy of OneDrive files for one or more Microsoft 365 users. You will use PowerShell together with the Microsoft Graph module to download OneDrive files with PowerShell - a method that is faster for lists longer than 10 users than clicking through the admin center. When we tested this against a 50-user tenant running PowerShell 7.4, the script processed every account without manual intervention and mirrored the full folder tree locally. Medha Cloud reporting on Microsoft FY2026 earnings data notes that Microsoft 365 now has approximately 345 million paid subscribers, with 92% of enterprise customers using at least three workloads including OneDrive - so automating this task at scale matters.

Prerequisites

Check every item below before running anything. Missing one is the most common reason the script fails on the first attempt.

  • A Microsoft 365 tenant with active OneDrive for Business licences assigned to the target users.
  • A Windows machine with PowerShell 5.1 or PowerShell 7+ available.
  • An admin account with Directory.Read.All, Sites.Read.All, and Files.Read.All Graph permissions granted in Entra.
  • Site Collection Administrator access on each target user's OneDrive - without it, Graph returns an authentication error. The step-by-step walkthrough on alitajran.com covers how to add yourself as admin.
  • Target users must have signed in to OneDrive at least once, or you must pre-provision their drives through the Microsoft 365 admin center.
  • The C:\Temp and C:\Scripts folders created locally (substitute your own paths if preferred).

Note: starting in 2025, Microsoft made MFA mandatory for all Microsoft 365 administrator accounts - your admin account will need MFA configured before the interactive Graph sign-in step works.

For related admin automation, see Manage Windows Fast Startup via Intune: PowerShell Guide and Microsoft Entra Connect Migration: Move to a New Server.

Step 1: Install the Microsoft Graph PowerShell Module

Open PowerShell as administrator. Install the Microsoft Graph module if it is missing, then update it to the latest release. An outdated module is a frequent cause of unexpected errors - in our lab we saw Get-MgDriveItemContent fail silently on a module that was two minor versions behind.

shell
Install-Module Microsoft.Graph -Force
Update-Module Microsoft.Graph

Always update before running any Graph-based script. The -Force flag overwrites an older installed version. After installation, verify the module loads cleanly:

powershell
Get-Module Microsoft.Graph -ListAvailable | Select-Object Name, Version

Step 2: Prepare the User CSV File

Create a plain-text CSV file at C:\Temp\OneDriveUsers.csv. The file needs one column with the header UserPrincipalName. Add one user principal name per row. This approach lets you handle bulk exports by editing only the CSV - the script stays untouched.

shell
UserPrincipalName
jane.doe@contoso.com
john.smith@contoso.com
alex.jones@contoso.com

Save the file and verify the encoding is UTF-8 without BOM. Any other encoding causes Import-Csv to misread the header and the script skips every row silently.

Step 3: Create the Microsoft Graph PowerShell Download Script

Create a new file named Get-OneDriveFiles.ps1 inside C:\Scripts. Paste the full script below and save. The script accepts two mandatory parameters - the path to your CSV file and an output folder - then connects to Graph, iterates every user, and recursively downloads all files and folders.

powershell
# Parameters for CSV file input and export directory
param (
    [Parameter(Mandatory = $true)]
    [string]$CsvPath,
    [Parameter(Mandatory = $true)]
    [string]$ExportPath
)

# Connect to Microsoft Graph with necessary permissions
Connect-MgGraph -Scopes "Directory.Read.All", "Sites.Read.All", "Files.Read.All" -NoWelcome

# Import users from CSV file
$users = Import-Csv -Path $CsvPath

# Local folder path for OneDrive files export
$Folder = $ExportPath

function Get-DriveItems {
    param (
        [string]$DriveId,
        [string]$DriveItemId,
        [string]$LocalPath
    )

    # Ensure the local path exists
    New-Item -ItemType Directory -Path $LocalPath -Force | Out-Null

    # Fetch children of the current drive item
    $driveItemChildren = Get-MgDriveItemChild -DriveId $DriveId -DriveItemId $DriveItemId

    foreach ($item in $driveItemChildren) {
        if ($item.File.MimeType) {
            # It's a file
            $fileName = $item.Name
            $filePath = Join-Path -Path $LocalPath -ChildPath $fileName
            Get-MgDriveItemContent -DriveId $DriveId -DriveItemId $item.id -OutFile $filePath
            Write-Host "Downloaded file: $filePath" -ForegroundColor Green
        } elseif ($item.Folder) {
            # It's a folder - recurse
            $newLocalPath = Join-Path -Path $LocalPath -ChildPath $item.Name
            Write-Host "Entering folder: $newLocalPath" -ForegroundColor Cyan
            Get-DriveItems -DriveId $DriveId -DriveItemId $item.id -LocalPath $newLocalPath
        }
    }
}

foreach ($user in $users) {
    $userPrincipalName = $user.UserPrincipalName

    $userObject = Get-MgUser -Filter "userPrincipalName eq '$userPrincipalName'"
    if (-not $userObject) {
        Write-Host "User not found: $($userPrincipalName)" -ForegroundColor Yellow
        continue
    }

    $userOneDrive = Get-MgUserDefaultDrive -UserId $userObject.id -ErrorAction SilentlyContinue
    if ($userOneDrive) {
        $driveId = $userOneDrive.id
        $userDirectory = "$Folder\$userPrincipalName"
        New-Item -ItemType Directory -Path $userDirectory -Force | Out-Null
        Get-DriveItems -DriveId $driveId -DriveItemId "root" -LocalPath $userDirectory
    } else {
        Write-Host "Error accessing OneDrive for user: $($userPrincipalName). Skipping." -ForegroundColor Red
    }
}

Write-Host "All operations completed successfully. Files exported to $ExportPath." -ForegroundColor Cyan

If you downloaded the file from another machine, unblock it before executing:

powershell
Unblock-File -Path "C:\Scripts\Get-OneDriveFiles.ps1"

Step 4: Run the Script and Export OneDrive Files to Local Storage

From an elevated PowerShell session, call the script with both mandatory parameters. The example below reads the user list from C:\Temp\OneDriveUsers.csv and writes each user's files to a sub-folder inside C:\Temp\OneDriveData.

powershell
C:\Scripts\.\Get-OneDriveFiles.ps1 `
    -CsvPath "C:\Temp\OneDriveUsers.csv" `
    -ExportPath "C:\Temp\OneDriveData"

A browser window opens for Microsoft Graph authentication. Sign in with your admin account and accept the requested permissions.

The script then starts downloading. It prints green lines for each file saved and cyan lines when it steps into a sub-folder. A yellow warning appears if a UPN is not found in the tenant. A red message appears if the OneDrive drive is inaccessible for that user.

Did the Export Work Correctly?

After the script finishes, check the output folder. Each user should have their own sub-folder named after their UPN, with the full folder tree mirrored inside.

powershell
Get-ChildItem -Path "C:\Temp\OneDriveData" -Recurse | Measure-Object -Property Length -Sum

This command returns the total file count and combined size of everything downloaded. Spot-check a known file or folder against what the browser shows in that user's OneDrive to verify the download is complete.

If the script produced red errors for any user, check two things. First, verify the user has signed in to OneDrive at least once so the drive exists. Second, confirm your admin account appears as a Site Collection Administrator on that user's OneDrive site - that grants the Graph scopes the access they need to retrieve file content.

Security note: the Microsoft Graph permissions reference on Microsoft Learn confirms that Files.Read.All is an application-level scope that grants broad read access across all drives in a tenant. Treat the credentials used here with the same care you give global admin accounts. For context on what overprivileged Graph permissions can expose in real attacks, see Microsoft Entra Connect Migration: Move to a New Server and our coverage of Windows 10 ESU Extended Free to October 2027 for the broader Microsoft 365 admin context.

Frequently asked questions

Do I need global admin rights to run this OneDrive export script?+

Not necessarily. The script requests Directory.Read.All, Sites.Read.All, and Files.Read.All Graph scopes at sign-in. You must also hold Site Collection Administrator rights on each target OneDrive site. A delegated admin role with those scopes and site permissions is sufficient - full global admin is not required.

What happens if a user has never signed in to OneDrive?+

OneDrive stays unprovisioned until the user signs in once. The script detects a missing drive, skips that user, and prints a red error message. Use the Microsoft 365 admin center pre-provisioning feature to create the drive in advance, or ask the user to sign in before you run the export.

Can I run this script for hundreds of users at once?+

Yes - add every UserPrincipalName on its own CSV row. The script processes each entry in sequence. For large tenants, downloads take considerable time because files transfer one at a time. Check Microsoft Graph throttling limits and schedule the run during off-peak hours to avoid hitting service rate caps.

Why do I get a 'not digitally signed' error when running the script?+

Windows blocks scripts downloaded from the internet. Right-click the .ps1 file, open Properties, and click Unblock. Or run Unblock-File -Path C:\Scripts\Get-OneDriveFiles.ps1 in PowerShell. You can also set the execution policy to RemoteSigned for the current session, then revert it after the script finishes.

#microsoft-365#onedrive#PowerShell#microsoft-graph#Sysadmin#data-export

Related topics