Skip to content
All articlesSharePoint

Find Over-Quota OneDrives and SharePoint Sites with PowerShell

Audit OneDrive and SharePoint Online sites over their licensed storage quota with PowerShell - useful for MC1310684 remediation and routine storage management.

6 June 20268 min read
Find Over-Quota OneDrives and SharePoint Sites with PowerShell

Find Over-Quota OneDrives and SharePoint Sites with PowerShell

To find every OneDrive or SharePoint Online site exceeding its allocated storage, run Get-SPOSite against your tenant and filter on StorageUsageCurrent versus StorageQuota. The scripts below cover OneDrive personal sites and SharePoint team/communication sites. Both work against any Microsoft 365 tenant with the SharePoint Online PowerShell module and a SharePoint Administrator account, with CSV export and a cross-reference to user account status at the end.

This audit is particularly relevant in the lead-up to Microsoft's OneDrive quota enforcement in July 2026 (MC1310684), where OneDrive users currently over their licensed quota will transition to read-only state during the rollout. The same scripts are useful for routine storage management - identifying which SharePoint sites are pushing tenant storage toward the cap.

Prerequisites

  • Microsoft 365 tenant with SharePoint Online.
  • PowerShell 5.1 or later (Windows) or PowerShell 7+ (any platform).
  • The SharePoint Online Management Shell module. Install with Install-Module -Name Microsoft.Online.SharePoint.PowerShell.
  • An account with the SharePoint Administrator role. Microsoft recommends using roles with the fewest permissions; Global Administrator is a highly privileged role that should be limited to emergency scenarios.
  • For Step 5 (cross-referencing user account status), the Microsoft Graph PowerShell SDK: Install-Module Microsoft.Graph.

Step 1: Connect to SharePoint Online

Connect-SPOService -Url https://<tenant>-admin.sharepoint.com

Replace <tenant> with your Microsoft 365 tenant name. Sign in with an account that holds the SharePoint Administrator role.

Step 2: Find OneDrive Accounts Over Their Licensed Quota

Get-SPOSite -IncludePersonalSite $true -Limit All |
    Where-Object {
        $_.Url -like "*-my.sharepoint.com/personal/*" -and
        $_.StorageUsageCurrent -gt $_.StorageQuota
    } |
    Select-Object Url, Owner, StorageUsageCurrent, StorageQuota,
        @{Name="OverByMB"; Expression={ $_.StorageUsageCurrent - $_.StorageQuota }} |
    Sort-Object OverByMB -Descending

This enumerates every OneDrive personal site in the tenant, filters to those whose current usage exceeds the assigned quota, and sorts by how far over each one is.

  • StorageUsageCurrent and StorageQuota are returned in MB. Divide by 1024 for GB.
  • The OverByMB calculated column surfaces the worst offenders first.
  • -IncludePersonalSite $true is required to enumerate OneDrives - they are not returned by Get-SPOSite by default.
  • For very large tenants Get-SPOSite is slow. Allow several minutes per 10,000 personal sites.

Step 3: Find SharePoint Sites Approaching Their Quota

Get-SPOSite -Limit All |
    Where-Object {
        $_.StorageQuota -gt 0 -and
        $_.StorageUsageCurrent -gt ($_.StorageQuota * 0.8)
    } |
    Select-Object Url, StorageUsageCurrent, StorageQuota,
        @{Name="PercentUsed"; Expression={ [math]::Round(($_.StorageUsageCurrent / $_.StorageQuota) * 100, 1) }} |
    Sort-Object PercentUsed -Descending

This returns SharePoint sites that have used more than 80% of their per-site quota. Adjust the 0.8 threshold to taste - 1.0 returns only fully-over sites; 0.5 returns anything past the halfway mark. The StorageQuota -gt 0 guard prevents a divide-by-zero on sites with no explicit quota set.

Per-site quota is set explicitly in the SharePoint admin centre or via PowerShell with Set-SPOSite -StorageQuota. If the tenant uses Storage Management set to "Automatic", sites can exceed their per-site quota as long as the tenant has headroom - in that case the per-site quota acts as a soft cap, not a hard cap.

Step 4: Export to CSV

For stakeholder conversations and helpdesk handoffs, export the results to CSV:

$over = Get-SPOSite -IncludePersonalSite $true -Limit All |
    Where-Object {
        $_.Url -like "*-my.sharepoint.com/personal/*" -and
        $_.StorageUsageCurrent -gt $_.StorageQuota
    } |
    Select-Object Url, Owner, StorageUsageCurrent, StorageQuota,
        @{Name="OverByMB"; Expression={ $_.StorageUsageCurrent - $_.StorageQuota }}

$over | Export-Csv -Path .\over-quota-onedrives.csv -NoTypeInformation

A clean spreadsheet for triage. Replace the OneDrive filter with the SharePoint version from Step 3 to export site-level data instead.

Step 5: Cross-Reference with User Account Status

The single largest cohort in most enterprise tenants is departed users whose OneDrives are still consuming space on active licences. Add user account status to the CSV:

Connect-MgGraph -Scopes "User.Read.All"

$over = Import-Csv .\over-quota-onedrives.csv

foreach ($row in $over) {
    $upn = ($row.Url -split "/personal/")[1] -replace "_", "@"
    $upn = $upn -replace "@(?=.*@)", "_"  # restore underscores in the local part
    $user = Get-MgUser -Filter "userPrincipalName eq '$upn'" `
        -Property AccountEnabled, AssignedLicenses -ErrorAction SilentlyContinue
    if ($user) {
        $row | Add-Member -NotePropertyName AccountEnabled `
            -NotePropertyValue $user.AccountEnabled -Force
        $row | Add-Member -NotePropertyName LicenceCount `
            -NotePropertyValue $user.AssignedLicenses.Count -Force
    }
}

$over | Export-Csv -Path .\over-quota-onedrives-with-status.csv -NoTypeInformation

The output has two extra columns: whether the user account is enabled, and how many Microsoft 365 licences are currently assigned. Sort by AccountEnabled = False and LicenceCount > 0 to surface the departed users still holding licences open against their OneDrive data.

The UPN reconstruction from the OneDrive URL is approximate - it handles the standard john.smith_company_com to john.smith@company.com encoding, but edge cases (apostrophes, hyphens in domains, special characters) may need manual review.

What to Do Once You Have the List

The over-quota population usually splits three ways. Each has a different remediation path.

Departed users on active licences. The OneDrive should not be holding an active licence open. The standard pattern is to capture the data into a preservation store the customer controls and then release the licence. Chipmunk automates this for Microsoft 365 - OneDrive, Exchange mailbox, and Teams data is captured into the customer's own Azure Blob Storage and the licence is released. See Microsoft 365 departed user archiving for the broader pattern.

Admin-elevated quotas above the licence entitlement. These are the ones MC1310684 specifically targets. They usually need a stakeholder conversation - is the higher quota actually required, or is it a forgotten one-off from a migration years ago? See OneDrive quota enforcement July 2026 (MC1310684) for the full remediation pattern.

Genuine high-footprint active users. A small group of users whose storage need is real - large CAD assemblies, video, research datasets. The choice is between a licence upgrade and a workflow change (move bulk reference data into a SharePoint document library, Azure storage, or a dedicated file service). For SharePoint sites pushing tenant storage, Squirrel moves cold content into the customer's own Azure Blob Storage with stub files left in place across SharePoint, OneDrive sync, and Teams - the site stays live and the bytes leave SharePoint.

Frequently Asked Questions

How long does Get-SPOSite take on a large tenant? For tenants under 10,000 users, the OneDrive scan typically completes within a few minutes. For tenants over 50,000 users, allow up to 30 minutes for -IncludePersonalSite $true -Limit All. The cmdlet pages through results internally and does not stream.

Do I need Global Administrator to run these scripts? No. The SharePoint Administrator role is sufficient. Microsoft documents Global Administrator as a highly privileged role to be limited to emergency scenarios.

Why are the storage values in MB? Get-SPOSite returns StorageUsageCurrent and StorageQuota as integers in megabytes. Divide by 1024 for GB, or by 1024^2 for TB. The example scripts leave the values in MB for direct comparison and CSV clarity.

Can I run this against deleted OneDrives in the recycle bin? No. Get-SPOSite returns active sites only. For deleted personal sites within the recycle bin retention window, use Get-SPODeletedSite -IncludePersonalSite $true.

Does this find Microsoft Teams sites and Communication sites? Yes. Get-SPOSite -Limit All returns every SharePoint site in the tenant, including Microsoft 365 Group sites that back Teams, Communication sites, and classic sites. Filter by Template if you want to scope to a specific site type.

Where does Microsoft's official MC1310684 PnP script live? Microsoft published a PnP PowerShell script inside the original Message Center post MC1310684 that identifies OneDrive users exceeding their licensed storage quota. The script in Step 2 above is a simpler Get-SPOSite equivalent that does not require the PnP module; either approach works.

Can I run this unattended on a schedule? Yes. Register a certificate-based app in Entra ID with SharePoint Online application permissions, then connect with Connect-SPOService -Url <admin-url> -ClientId <appid> -Tenant <tenantid> -CertificateThumbprint <thumb>. For Microsoft Graph in Step 5, use Connect-MgGraph -ClientId <appid> -TenantId <tenantid> -CertificateThumbprint <thumb>.

What's the difference between StorageUsageCurrent and StorageQuotaWarningLevel? StorageUsageCurrent is the current consumed storage in MB. StorageQuota is the hard cap in MB. StorageQuotaWarningLevel is the threshold at which SharePoint sends a warning email - typically set to 90% of the quota. For the MC1310684 audit, StorageUsageCurrent versus StorageQuota is what matters.

Ready when you are

Cut your Microsoft 365 storage bill - keep your data in your tenant.