Contents

Get nested folders, files count, folder size, and more in SharePoint using PowerShell

 

Isn’t it nice to have some reports, inventory, or any visual about a SharePoint site? So we know what’s going on, at a high level at least.

Today’s post will be about running PnP PowerShell to extract info on a SharePoint site, and we’ll go fetch those nested folders! But that’s not all, we’ll also get the number of files in each folder, and the folder size!

Want another bonus? We’ll go through 1 document library, then through all document libraries in your site. Which means 2 PowerShell scripts! 🤠

Scripts
Most of my scripts are also on my Github repos available to anyone.
 

Report on ONE particular document library

OK, let’s set the scene.

  • One Site Collection
  • One document library
  • Multiple folders (with nested ones)
  • Multiple files (maybe?)
  • And we don’t know about the size…

So here we go.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#Connect to SPO
Connect-PnPOnline -Url "https://<TENANT-NAME>.sharepoint.com/sites/<YOUR-SITE>"

#My list target 
$myList = "/Shared Documents"

#Store the results
$results = @()

foreach ($list in $myList) {
    $allItems = Get-PnPListItem -List $list -Fields "FileLeafRef", "SMTotalFileStreamSize", "FileDirRef", "FolderChildCount", "ItemChildCount"
    
    foreach ($item in $allItems) {
        
        #Narrow down to folder type only
        if (($item.FileSystemObjectType) -eq "Folder") {
            $results += New-Object psobject -Property @{
                FileType          = $item.FileSystemObjectType 
                RootFolder        = $item["FileDirRef"]
                LibraryName       = $list 
                FolderName        = $item["FileLeafRef"]
                FullPath          = $item["FileRef"]
                FolderSizeInMB    = ($item["SMTotalFileStreamSize"] / 1MB).ToString("N")
                NbOfNestedFolders = $item["FolderChildCount"]
                NbOfFiles         = $item["ItemChildCount"]
            }
        }
    }
}
#Export the results
$results | Export-Csv -Path "C:\Users\$env:USERNAME\Desktop\NestedFoldersForONEdoclib.csv" -NoTypeInformation

 

So what are we doing here?

  1. First, as usual, we connect to our SharePoint site using the Connect-PnPOnline cmdlet,
  2. We target our document library to report on ($myList),
  3. And we create an array to store our results in ($results)

Then we need to create 2x foreach (nested) loops:

  • In the first one, we loop through each list item, declare the fields we are interested in, and we store the whole lot in a variable called $allItems,
  • In the second one, we narrow down by selecting only the “Folder” type using the IF statement, create a New-Object for our values, and do a bit of customisation with the SMTotalFileStreamSize to format the output in MB.

Finally, we export the $results into a csv file.
 

The export should look like this:

/images/powershell-screenshots/nested-folders-and-sizes-img3.png
 

If we look at the first row, in the Shared Documents library, we have a folder called “Folder 1“, which has 3x nested folders & 1 file inside.

We can check this out in 2 ways: In SharePoint Online (you’ll have to trust me 😉)

/images/powershell-screenshots/nested-folders-and-sizes-img2.png
 

But ALSO in the csv file itself! Look at the rows 4, 5, and 8? They contain the full path of those 3 sub-folders… So they were really here when I run the script.
 

Report on MULTIPLE document libraries

Now let’s have a look at how we can extend our scenario, and report on multiple document libraries within the site. This part will be shorter as the script will not change too much, so I’m not gonna bore you with a remake of the above

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#Connect to SPO
Connect-PnPOnline -Url "https://<TENANT-NAME>.sharepoint.com/sites/<YOUR-SITE>"

#Target multiple lists 
$allLists = Get-PnPList | Where-Object {$_.BaseTemplate -eq 101}

#Store the results
$results = @()

foreach ($row in $allLists) {
    $allItems = Get-PnPListItem -List $row.Title -Fields "FileLeafRef", "SMTotalFileStreamSize", "FileDirRef", "FolderChildCount", "ItemChildCount"
    
    foreach ($item in $allItems) {
        if (($item.FileSystemObjectType) -eq "Folder") {
            $results += New-Object psobject -Property @{
                FileType          = $item.FileSystemObjectType 
                RootFolder        = $item["FileDirRef"] 
                LibraryName       = $row.Title
                FolderName        = $item["FileLeafRef"]
                FullPath          = $item["FileRef"]
                FolderSizeInMB    = ($item["SMTotalFileStreamSize"] / 1MB).ToString("N")
                NbOfNestedFolders = $item["FolderChildCount"]
                NbOfFiles         = $item["ItemChildCount"]
            }
        }
    }
}
#Export the results
$results | Export-Csv -Path "C:\Users\$env:USERNAME\Desktop\NestedFoldersForMULTIPLEdoclibs.csv" -NoTypeInformation

 

What changed?

Only a couple of things have changed in this script:

  • We use the Get-PnPList to retrieve all the libraries, and store in a variable called $allLists,
  • The -List parameter is now referring to $row.Title,
  • And the LibraryName is also $row.Title

The rest is unchanged.

Output anyone? Sure!

/images/powershell-screenshots/nested-folders-and-sizes-img1.png
 

Thanks for reading!