OneDrive usage report: owner, storage and last activity
Export every OneDrive in your tenant with its owner, storage used, storage quota and the date content last changed, so you can size a OneDrive migration and spot empty or abandoned accounts before you move them.
What you need
Admin roles
- SharePoint Administrator
Runs on
- Windows PowerShell 5.1 on Windows, or PowerShell 7 on Windows with Import-Module -UseWindowsPowerShell
Options you can set
| Parameter | What it does |
|---|---|
-AdminUrl | Required. Your SharePoint admin URL, for example https://contoso-admin.sharepoint.com. |
-OutputPath | Optional. Where to save the CSV. Default: OneDriveUsageReport_yyyyMMdd_HHmm.csv in the current folder. |
-SkipConnect | Optional switch. Use a session you already opened with Connect-SPOService. |
Step by step
- 1
Step 1
Install the SharePoint Online Management Shell (see install SharePoint Online Management Shell).
- 2
Step 2
Save the script as
Get-CMOneDriveUsageReport.ps1, for example inC:\Scripts. - 3
Step 3
Open Windows PowerShell from the Start menu and run
cd C:\Scripts. - 4
Step 4
Run
.\Get-CMOneDriveUsageReport.ps1 -AdminUrl https://contoso-admin.sharepoint.comand sign in as a SharePoint Administrator. - 5
Step 5
Open the CSV the script names at the end. Sort by StorageUsageCurrent to plan migration batches, or by LastContentModifiedDate to find inactive OneDrives.
What you get: A UTF-8 CSV with one row per OneDrive: Url, Owner, Title, StorageUsageCurrent, StorageQuota, LastContentModifiedDate and LockState. Storage values are as Get-SPOSite returns them. For sign-in and file activity per user, also check the OneDrive usage report in the Microsoft 365 admin center.
Get-CMOneDriveUsageReport.ps1
<#
.SYNOPSIS
Get-CMOneDriveUsageReport.ps1
.DESCRIPTION
Lists every OneDrive (personal site) in the tenant with owner, storage used,
storage quota and last content modified date, and exports it to CSV.
Read-only: it changes nothing in your tenant.
The site query is the one Microsoft documents for listing OneDrive URLs:
Get-SPOSite -IncludePersonalSite $true -Limit all -Filter "Url -like '-my.sharepoint.com/personal/'"
Provided by cloud-migrations.au as is; test before use.
Read the script before you run it and try it in a test tenant first.
.NOTES
Requirements
- SharePoint Online Management Shell:
Install-Module -Name Microsoft.Online.SharePoint.PowerShell -Scope CurrentUser
- SharePoint Administrator role
- Windows PowerShell 5.1, or PowerShell 7 with:
Import-Module Microsoft.Online.SharePoint.PowerShell -UseWindowsPowerShell
Commands used (documented by Microsoft): Connect-SPOService, Get-SPOSite, Disconnect-SPOService
.EXAMPLE
.\Get-CMOneDriveUsageReport.ps1 -AdminUrl https://contoso-admin.sharepoint.com
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)][string]$AdminUrl,
[string]$OutputPath = (Join-Path -Path (Get-Location) -ChildPath ('OneDriveUsageReport_{0}.csv' -f (Get-Date -Format 'yyyyMMdd_HHmm'))),
[switch]$SkipConnect
)
$ErrorActionPreference = 'Stop'
# 1. Connect
if (-not $SkipConnect) {
try {
Write-Host "Connecting to $AdminUrl ..."
Connect-SPOService -Url $AdminUrl
}
catch {
Write-Error "Could not connect to SharePoint: $($_.Exception.Message)"
return
}
}
# 2. List OneDrive sites
try {
Write-Progress -Activity 'OneDrive usage report' -Status 'Listing OneDrive sites (this can take a while in large tenants)...' -PercentComplete 10
$sites = @(Get-SPOSite -IncludePersonalSite $true -Limit all -Filter "Url -like '-my.sharepoint.com/personal/'")
}
catch {
Write-Error "Get-SPOSite failed: $($_.Exception.Message)"
return
}
Write-Host ("Found {0} OneDrive sites." -f $sites.Count)
# 3. Shape the rows
$results = New-Object System.Collections.Generic.List[object]
$i = 0
foreach ($s in $sites) {
$i++
if ($i % 50 -eq 0 -or $i -eq $sites.Count) {
Write-Progress -Activity 'OneDrive usage report' -Status ("Processing {0} of {1}" -f $i, $sites.Count) -PercentComplete (10 + (($i / [math]::Max($sites.Count, 1)) * 90))
}
$results.Add([pscustomobject][ordered]@{
Url = $s.Url
Owner = $s.Owner
Title = $s.Title
StorageUsageCurrent = $s.StorageUsageCurrent
StorageQuota = $s.StorageQuota
LastContentModifiedDate = $s.LastContentModifiedDate
LockState = $s.LockState
})
}
Write-Progress -Activity 'OneDrive usage report' -Completed
# 4. Export
try {
$results | Sort-Object -Property StorageUsageCurrent -Descending | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8
Write-Host ("Done. {0} OneDrive sites written." -f $results.Count)
Write-Host "Report saved to: $((Resolve-Path -Path $OutputPath).Path)"
}
catch {
Write-Error "Could not write the CSV to $OutputPath : $($_.Exception.Message)"
}
finally {
if (-not $SkipConnect) { Disconnect-SPOService }
}Commands documented here
Every command in the script is documented on these vendor pages. Test in a non-production tenant or environment first.