Before a migration or a cleanup, the first thing I ask for is an inventory: which lists and libraries does this site actually have, how big are they, and which ones nobody has touched in months? Clicking through Site contents works for one site, but not for ten.
PnP PowerShell answers that in a single line. Here’s how I get every list and library on a site, separate libraries from lists, skip the system ones, export the result to CSV, and run the same report across several sites. Every script ran read-only against my own Microsoft 365 tenant in PowerShell 7, and the screenshots are the real output.
Quick answer: Connect with Connect-PnPOnline -Url https://contoso.sharepoint.com/sites/Sales -ClientId <app id> -Interactive, then run Get-PnPList. Add | Where-Object { -not $_.Hidden } to drop hidden system lists, and filter on BaseType -eq "DocumentLibrary" to keep only libraries.
Get all lists and libraries with Get-PnPList
Run without parameters, Get-PnPList returns every list and library in the site you’re connected to. You’ll need PnP PowerShell 3.x in PowerShell 7 and your own Entra ID app; installing PnP PowerShell covers the setup. My test site returned 26 lists, but 12 of them were hidden galleries and catalogs, so I filter those out:

BaseType tells you whether it’s a list (GenericList) or a library (DocumentLibrary). ItemCount is the stored total, so it’s instant even on big lists, and RootFolder.ServerRelativeUrl gives the real URL. Look at the archive lists: a renamed list keeps its original URL, so report both columns.
| BaseTemplate | What it is |
|---|---|
| 100 | Custom list (including lists made in Microsoft Lists) |
| 101 | Document library, also Site Assets, Style Library, Form Templates |
| 104 / 106 / 107 | Announcements / Calendar (Events) / Tasks |
| 109 | Picture library |
| 119 | Site Pages |
Get only document libraries or only lists
Filtering on BaseTemplate -eq 101 is the common trick, but it lets Site Assets and Style Library through and misses Site Pages. I filter on BaseType instead and drop system libraries with IsSystemList, which you load through -Includes:
# Skip hidden and system lists (Site Pages, Site Assets, Style Library, Form Templates)
$lists = Get-PnPList -Includes IsSystemList | Where-Object { -not $_.Hidden -and -not $_.IsSystemList }
$lists | Where-Object BaseType -eq "DocumentLibrary" |
Select-Object Title, ItemCount,
@{ N = "LastModified"; E = { $_.LastItemUserModifiedDate.ToString("MM/dd/yyyy") } } |
Format-Table -AutoSize
$lists | Where-Object BaseType -ne "DocumentLibrary" |
Select-Object Title, BaseTemplate, ItemCount | Format-Table -AutoSize

Only the two real libraries are left, with their last modified date, which is a quick way to spot abandoned content. Need folder sizes too? See how to get a SharePoint document library size.
Load extra properties with -Includes
Get-PnPList loads the common properties, and RootFolder came back ready in my runs. Others, such as HasUniqueRoleAssignments (broken permission inheritance) and IsSystemList, stay empty until you name them: Get-PnPList -Includes HasUniqueRoleAssignments, IsSystemList. To go one level deeper, the list column details script lists every column of a list.
Export the list inventory to CSV
Pipe the same objects to Export-Csv. Calculated properties flatten the URL and format the date, so the file opens cleanly in Excel:
$lists | Select-Object Title, BaseType, BaseTemplate, ItemCount,
@{ N = "Url"; E = { $_.RootFolder.ServerRelativeUrl } },
@{ N = "LastModified"; E = { $_.LastItemUserModifiedDate.ToString("MM/dd/yyyy") } } |
Export-Csv -Path "C:\Reports\Sales-lists.csv" -NoTypeInformation
My run exported ten rows. If you also need the files themselves,