How to list all documents in a SharePoint site with Powershell
At a Glance
- Target Audience
- SharePoint Administrators, IT Ops Managers
- Problem Solved
- Tedious manual auditing of documents across multiple SharePoint libraries and nested folders via UI.
- Use Case
- Full site document inventory for compliance audits, data cleanup, or migration prep.
<p>Most admins try to audit SharePoint by clicking through folders. It never works.</p>
<p>You cannot manually check 50 libraries and expect to get an accurate count. Things get messy fast. You end up with hundreds of nested folders and thousands of misplaced files.</p>
<p>Stop trying to click your way out of a data problem. Your time is too valuable to spend tallying files by hand. You need to script the boring work.</p>
<p>I recently had to generate a full inventory of every document uploaded to a specific SharePoint site. Doing this through the UI is a nightmare. So I wrote a custom PowerShell function called <code>Get-Documents</code>.</p>
<p>It is not sexy. It is just a reliable process that loops through your environment and pulls exactly what you need.</p>
<h3 id="the-inventory-script">The Inventory Script</h3><p>Here is the exact code. Notice that the memory cleanup command sits outside the loop. If you put it inside, your script will crash after reading the first library.</p>
<pre><code class="hljs language-powershell"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Get-Documents</span> <span class="hljs-params">()</span></span> {
<span class="hljs-built_in">Add-PSSnapin</span> Microsoft.SharePoint.PowerShell
<span class="hljs-variable">$web</span> = <span class="hljs-built_in">Get-SPWeb</span> (<span class="hljs-built_in">Read-Host</span> <span class="hljs-string">"Enter Site URL"</span>)
<span class="hljs-keyword">foreach</span> (<span class="hljs-variable">$list</span> <span class="hljs-keyword">in</span> <span class="hljs-variable">$web</span>.Lists) {
<span class="hljs-keyword">if</span> (<span class="hljs-variable">$list</span>.BaseType <span class="hljs-operator">-eq</span> <span class="hljs-string">"DocumentLibrary"</span>) {
<span class="hljs-keyword">foreach</span> (<span class="hljs-variable">$item</span> <span class="hljs-keyword">in</span> <span class="hljs-variable">$list</span>.Items) {
<span class="hljs-variable">$data</span> = <span class="hljs-selector-tag">@</span>{
<span class="hljs-string">"Web"</span> = <span class="hljs-variable">$web</span>.Url
<span class="hljs-string">"List"</span> = <span class="hljs-variable">$list</span>.Title
<span class="hljs-string">"Item ID"</span> = <span class="hljs-variable">$item</span>.ID
<span class="hljs-string">"Item URL"</span> = <span class="hljs-variable">$item</span>.Url
<span class="hljs-string">"Item Title"</span> = <span class="hljs-variable">$item</span>.Title
<span class="hljs-string">"Item Name"</span> = <span class="hljs-variable">$item</span>.Name
<span class="hljs-string">"Item Created"</span> = <span class="hljs-variable">$item</span>[<span class="hljs-string">"Created"</span>]
<span class="hljs-string">"Item Modified"</span> = <span class="hljs-variable">$item</span>[<span class="hljs-string">"Modified"</span>]
<span class="hljs-string">"File Size"</span> = <span class="hljs-variable">$item</span>.File.Length / <span class="hljs-number">1</span>KB
}
<span class="hljs-built_in">New-Object</span> PSObject <span class="hljs-literal">-Property</span> <span class="hljs-variable">$data</span>
}
}
}
<span class="hljs-variable">$web</span>.Dispose()
}
</code></pre><h3 id="how-it-works">How It Works</h3><p>Let us break down what is actually happening here.</p>
<p>First, the script loads the SharePoint Server on-premises object model. It prompts you for a site URL and then goes to work. If you ever struggle to load the required PowerShell snap-in, make sure you are running the management shell as an administrator.</p>
<p>The function ignores standard lists. It specifically targets document libraries using the <code>$list.BaseType</code> filter. Then it grabs the critical metadata for every single file.</p>
<p>You get the exact site-relative URL for each item. You get the creation dates. You get the file sizes.</p>
<h3 id="exporting-your-data">Exporting Your Data</h3><p>Once the function is loaded into your session, you have two ways to view your data.</p>
<p>You can push it directly to a grid view for quick sorting and filtering:<br><code>Get-Documents | Out-GridView</code></p>
<p>Or you can export it to a CSV file to hand off to your compliance team:<br><code>Get-Documents | Export-Csv -NoTypeInformation -Path C:\temp\inventory.csv</code></p>
<p>Focus on the data that matters. Let the script handle the heavy lifting.</p>
