SharePoint & Microsoft 365

List Every Document in a SharePoint Server Site with PowerShell

Inventory documents in a SharePoint Server site with PowerShell, including prerequisites, safe disposal, CSV export and the SharePoint Online boundary.

Collab365 Team · 23 December 2016 · Updated 24 August 2026 · 2 min read

This script inventories files in document libraries for one on-premises SharePoint Server site. It does not work in SharePoint Online because Get-SPWeb and the server object model run inside a SharePoint farm.

Use it for discovery, not as proof that a file is correctly classified, retained or accessible to the right people.

Before you run it

You need:

  • access to a SharePoint Server in the farm;
  • the SharePoint Management Shell;
  • permission to use SharePoint Server cmdlets and read the target site;
  • a local export folder that does not expose sensitive filenames;
  • an agreed scope: one web, a site collection or the whole farm.

Microsoft's Get-SPWeb documentation warns that stored SPWeb objects must be disposed correctly. The script below uses Start-SPAssignment and Stop-SPAssignment so cleanup still happens if the inventory fails.

Inventory one SharePoint Server site

Run this in the SharePoint Management Shell. Replace the URL and export path first.

$siteUrl = "https://sharepoint.contoso.com/sites/finance"
$csvPath = "C:\Temp\sharepoint-document-inventory.csv"

Start-SPAssignment -Global

try {
    $web = Get-SPWeb -Identity $siteUrl

    $rows = foreach ($library in $web.Lists) {
        if ($library.BaseType -ne "DocumentLibrary" -or $library.Hidden) {
            continue
        }

        foreach ($item in $library.Items) {
            if ($null -eq $item.File) {
                continue
            }

            [pscustomobject]@{
                WebUrl      = $web.Url
                Library     = $library.Title
                ItemId      = $item.ID
                FileName    = $item.File.Name
                ServerUrl   = $item.File.ServerRelativeUrl
                Created     = $item["Created"]
                Modified    = $item["Modified"]
                SizeBytes   = $item.File.Length
            }
        }
    }

    $rows | Export-Csv -Path $csvPath -NoTypeInformation -Encoding UTF8
    $rows | Measure-Object
}
finally {
    Stop-SPAssignment -Global
}

The try and finally block is important. It releases SharePoint objects even when a library or export operation throws an error.

Check the result

Open the CSV and verify:

  • expected libraries appear;
  • hidden system libraries were intentionally excluded;
  • file URLs are site-relative and not mistaken for public links;
  • the row count is plausible for the chosen scope;
  • large libraries did not cause a timeout or memory error.

The script skips folders because a folder is not a document. It also inventories current files only. It does not enumerate every historic version, recycle-bin item, retention copy or item the current account cannot read.

If the output stops part-way through, reduce the scope to one library and record which library failed. Do not keep rerunning a farm-wide script until you understand the failure.

SharePoint Online is a different job

Do not install the SharePoint Server snap-in on an admin workstation and expect it to query SharePoint Online. Use a supported cloud API or a current community tool such as PnP PowerShell, with an authentication method and permissions approved for your tenant.

For large online inventories, Microsoft Graph or SharePoint search may be more appropriate than loading every item. The right route depends on whether you need a file list, permissions, versions, retention state or an evidential export.

Keep the evidence boundary clear

A CSV proves only what the script returned at that time with that identity and scope. Save the script version, run time, site URL, account, exclusions and any errors alongside the export.

For help turning an inventory into a supportable SharePoint review, join the SharePoint & Teams Admins Space.

Sources