A few weeks ago, while working with a client on a SharePoint Online storage cleanup project, I got a very simple-sounding request: “Bijay, can you tell us which document libraries are eating up all our storage?”
Sounds easy, right? But when you have 40+ SharePoint sites and hundreds of document libraries, clicking through each site one by one is not going to work. That’s when PnP PowerShell became my best friend.
In this tutorial, I’ll show you exactly how I did it. I’ll cover the manual method (Storage Metrics), then three PnP PowerShell methods to get the SharePoint document library size — for a single library, for all libraries in a site, and even exporting everything to a CSV file.
Let’s get started.
What You Need Before You Start
Before running any of the scripts below, make sure you have these ready:
- PnP.PowerShell module installed on your machine
- An Azure AD App Registration (Client ID) — since PnP PowerShell no longer works with the old multi-tenant app
- At least Site Collection Administrator permissions on the site
If you don’t have the module yet, install it using this command:
Install-Module PnP.PowerShell -Scope CurrentUser -Force
And if you haven’t registered an app yet, you can create one in a single line:
Register-PnPAzureADApp -ApplicationName "PnP-Storage-Reporter" `
-Tenant "yourtenant.onmicrosoft.com" `
-Interactive
Copy the Client ID it returns — you’ll need it in every script below.
Method 1: Get Document Library Size Using Storage Metrics (No Code)
If you just need a quick look and don’t want to touch PowerShell, SharePoint has a built-in page for this.
Here’s how to find it:
- Open your SharePoint site and click the gear icon → Site contents
- Click Site settings
- Under Site Collection Administration, click Storage Metrics
You’ll now see every library and folder on the site, along with:
- Size (total size of the library)
- % of Parent
- % of Site Quota
This is honestly the fastest way to eyeball your biggest storage consumers, and it’s exactly where I start when I’m troubleshooting a single site.
You can see the storage metrics of one of my SharePoint Online sites in the screenshot below.

One thing to note: Storage Metrics includes version history and metadata in the size calculation, so the number will usually be larger than the sum of the current file sizes. That’s normal — and it’s actually the number you want, since versions count against your quota too.
The limitation? You have to do this site by site. That’s fine for one site, painful for fifty. So let’s automate it.
Method 2: Get the Size of a Single Document Library Using PnP PowerShell
This is the script I use when a client asks about the size of one specific SharePoint document library.
$SiteURL = "https://tsinfotechnologies.sharepoint.com/sites/SPGuides"
$LibraryName = "Training Documents"
$ClientID = "your-client-id-here"
# Connect to the SharePoint site
Connect-PnPOnline -Url $SiteURL -ClientId $ClientID -Interactive
# Get the storage metrics of the library
$LibraryStorage = Get-PnPFolderStorageMetric -List $LibraryName
# Convert the size from bytes to MB
$LibrarySizeMB = [Math]::Round($LibraryStorage.TotalSize / 1MB, 2)
Write-Host "Total Library Size: $LibrarySizeMB MB" -ForegroundColor Green
How This Script Works
Let me break down what’s happening here, line by line:
| Line | What It Does |
|---|---|
$SiteURL | The URL of the site that holds your library |
$LibraryName | The display name of the document library |
$ClientID | The Client ID from your Azure AD app registration |
Connect-PnPOnline | Opens an interactive login prompt to connect |
Get-PnPFolderStorageMetric | Pulls the storage metrics for the library’s root folder |
[Math]::Round(... / 1MB, 2) | Converts bytes to MB and rounds to 2 decimals |
When you run this, you’ll see something like this in your terminal:
Total Library Size: 1.5 MB
You can also see the exact output in the screenshot below:

Pro Tip: Get-PnPFolderStorageMetric also returns TotalFileCount and TotalFileStreamSize. Add $LibraryStorage | Format-List * to see everything available — I do this all the time when a client wants file counts too.
Method 3: Get the Size of ALL Document Libraries in a SharePoint Site
This script actually solved my client’s problem. It loops through every document library on the SharePoint site and gives you a clean, sorted table.
$SiteURL = "https://tsinfotechnologies.sharepoint.com/sites/SPGuides"
$ClientID = "655a839c-8659-AAAAAAAAAAAAAAA"
Connect-PnPOnline -Url $SiteURL -ClientId $ClientID -Interactive
# Get all document libraries (BaseTemplate 101 = Document Library)
# Also filtering out hidden system libraries
$SP_Doc_Libraries = Get-PnPList | Where-Object {
$_.BaseTemplate -eq 101 -and $_.Hidden -eq $false
}
# Array to store the results
$Storage_Results = @()
foreach ($Library in $SP_Doc_Libraries) {
try {
$Storagedata = Get-PnPFolderStorageMetric -List $Library.Title
$SizeMB = [Math]::Round($Storagedata.TotalSize / 1MB, 2)
$Storage_Results += [PSCustomObject]@{
"Library Name" = $Library.Title
"Item Count" = $Library.ItemCount
"Size (MB)" = $SizeMB
"Size (GB)" = [Math]::Round($Storagedata.TotalSize / 1GB, 3)
}
}
catch {
Write-Warning "Couldn't get size for library: $($Library.Title)"
}
}
$Storage_Results | Sort-Object "Size (MB)" -Descending | Format-Table -AutoSize
Understanding the Key Parts
BaseTemplate -eq 101 — This is the magic number for a document library. If you skip this filter, you’ll also get lists, calendars, and task lists, which will throw errors.
Hidden -eq $false — I added this because SharePoint has a bunch of hidden system libraries (Form Templates, Style Library, etc.) that just add noise to your report. Remove this filter if you want the complete picture.
The try...catch block — Trust me on this one. Some libraries (especially ones with restricted permissions) will throw errors. Without the catch block, your whole script stops halfway through. With it, the script logs a warning and keeps going.
Sort-Object "Size (MB)" -Descending — This puts the biggest storage hogs right at the top, which is exactly what your client wants to see first.
Your output will look something like this:
Library Name Item Count Size (MB) Size (GB)
------------ ---------- --------- ---------
Documents 17 41.78 0.04
Site Assets 29 3.54 0.00
Project Documents 2 2.36 0.00
Training Documents 13 1.50 0.00
PowerBI Report 1 0.67 0.00
Form Templates 0 0.04 0.00
Marketing Policies 2 0.04 0.00
Style Library 0 0.03 0.00
You can see the exact output in the screenshot below:

Check out Delete Files From SharePoint Document Library Using Rest API in Power Automate
Method 4: Get Library Sizes Across All Sites and Export to CSV
Now for the one my client actually paid me for. This script connects to the SharePoint Admin Center, loops through every site collection in the tenant, and exports a complete storage report to CSV.
$AdminURL = "https://<tenant>-admin.sharepoint.com"
$ClientID = "655a839c-8659-AAAAAAAAAAAAAAA"
$ReportPath = "C:\Reports\SPO-Library-Storage-Report.csv"
Connect-PnPOnline -Url $AdminURL -ClientId $ClientID -Interactive
# Get all site collections (excluding OneDrive personal sites)
$AllSites = Get-PnPTenantSite | Where-Object { $_.Template -notlike "SPSPERS*" }
$FinalReport = @()
foreach ($Site in $AllSites) {
Write-Host "Processing: $($Site.Url)" -ForegroundColor Cyan
try {
Connect-PnPOnline -Url $Site.Url -ClientId $ClientID -Interactive
$Libraries = Get-PnPList | Where-Object {
$_.BaseTemplate -eq 101 -and $_.Hidden -eq $false
}
foreach ($Lib in $Libraries) {
try {
$Metric = Get-PnPFolderStorageMetric -List $Lib.Title
$FinalReport += [PSCustomObject]@{
"Site Title" = $Site.Title
"Site URL" = $Site.Url
"Library Name" = $Lib.Title
"Item Count" = $Lib.ItemCount
"Size (MB)" = [Math]::Round($Metric.TotalSize / 1MB, 2)
"Size (GB)" = [Math]::Round($Metric.TotalSize / 1GB, 3)
"Last Modified"= $Lib.LastItemUserModifiedDate
}
}
catch {
Write-Warning " Skipped library: $($Lib.Title)"
}
}
}
catch {
Write-Warning "Could not connect to site: $($Site.Url)"
}
}
$FinalReport | Sort-Object "Size (MB)" -Descending |
Export-Csv -Path $ReportPath -NoTypeInformation
Write-Host "Report saved to $ReportPath" -ForegroundColor Green
Why I Added Last Modified
This turned out to be the most valuable column in the whole report. My client had several 5+ GB libraries that hadn’t been touched in three years. Being able to say “here’s 40 GB you can archive today” is what made the report actually useful instead of just interesting.
Heads up: If you run this with -Interactive, you’ll get a login prompt for every single site — which is miserable for a large tenant. For production runs, use certificate-based authentication with app-only permissions instead:
Connect-PnPOnline -Url $Site.Url `
-ClientId $ClientID `
-Tenant "yourtenant.onmicrosoft.com" `
-CertificatePath "C:\Certs\PnPApp.pfx" `
-CertificatePassword (ConvertTo-SecureString "YourPassword" -AsPlainText -Force)
Check out Create Folders and Subfolders in SharePoint document library
Common Errors and How to Fix Them
Here are the issues I run into most often, and how to fix them:
| Error | Cause | Fix |
|---|---|---|
Connect-PnPOnline: AADSTS700016 | Client ID is missing or invalid | Register an app with Register-PnPAzureADApp |
List does not exist | Using the URL name instead of the display name | Use the library’s Title, not its folder name |
Access denied | Not a Site Collection Admin | Grant yourself SCA rights in the Admin Center |
| Sizes don’t match Storage Metrics | Version history is included | This is expected — versions count toward quota |
| Script stops on one library | No error handling | Wrap the loop body in try...catch |
Which Method Should You Use?
Here’s my quick decision guide:
- One site, quick check? → Use Storage Metrics (Method 1)
- One specific library? → Use Method 2
- All libraries in one site? → Use Method 3
- Tenant-wide audit or a report for management? → Use Method 4
Conclusion
In this tutorial, I showed you four different ways to get the SharePoint document library size — starting with the no-code Storage Metrics page, then moving to PnP PowerShell for single libraries, all libraries in a site, and finally a full tenant-wide CSV report.
The command doing the heavy lifting in all of these is Get-PnPFolderStorageMetric, and once you understand how to loop it through Get-PnPList with a BaseTemplate -eq 101 filter, you can build almost any storage report your organization needs.
My advice: start with Method 3 on a single site to get comfortable, then scale up to Method 4 once you’re confident in the output. And always add that try...catch block — you’ll thank yourself later.
If you have any questions or run into an error I didn’t cover, drop a comment below, and I’ll help you out.
You may also like:
- Create and Delete SharePoint Document Library Using PowerShell
- Enable Sensitivity Labels For Microsoft 365 Groups & SharePoint Sites Using PowerShell

Hey! I’m Bijay Kumar, founder of SPGuides.com and a Microsoft Business Applications MVP (Power Automate, Power Apps). I launched this site in 2020 because I truly enjoy working with SharePoint, Power Platform, and SharePoint Framework (SPFx), and wanted to share that passion through step-by-step tutorials, guides, and training videos. My mission is to help you learn these technologies so you can utilize SharePoint, enhance productivity, and potentially build business solutions along the way.