SharePoint Online: Get Document Library Inventory (Folder-SubFolder-File Structure) using PowerShell

Requirement: Get the file-folder structure of a SharePoint document library and export to CSV.

SharePoint Online: PowerShell to get the Document Library Inventory
Let's export all folders, sub-folders and files structure from a SharePoint Online document library to a CSV file:
#Load SharePoint CSOM Assemblies
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
     
#Config Parameters
$SiteURL= "https://crescent.sharepoint.com/sites/marketing"
$ListName = "Documents"
$CSVPath = "C:\Temp\DocumentLibraryRpt.csv"
$BatchSize = 500
 
#Get Credentials to connect
$Cred = Get-Credential
 
Try {
    #Setup the context
    $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
    $Ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.UserName,$Cred.Password)
     
    #Get the Document Library
    $List =$Ctx.Web.Lists.GetByTitle($ListName)
     
    #Define CAML Query to Get List Items in batches
    $Query = New-Object Microsoft.SharePoint.Client.CamlQuery
    $Query.ViewXml ="
    <View Scope='RecursiveAll'>
        <Query>
            <OrderBy><FieldRef Name='ID' Ascending='TRUE'/></OrderBy>
        </Query>
        <RowLimit Paged='TRUE'>$BatchSize</RowLimit>
    </View>"

    $DataCollection = @()
    Do
    {
        #get List items
        $ListItems = $List.GetItems($Query) 
        $Ctx.Load($ListItems)
        $Ctx.ExecuteQuery() 

        #Iterate through each item in the document library
        ForEach($ListItem in $ListItems)
        {
            #Collect data        
            $Data = New-Object PSObject -Property ([Ordered] @{
                Name  = $ListItem.FieldValues.FileLeafRef
                RelativeURL = $ListItem.FieldValues.FileRef
                Type =  $ListItem.FileSystemObjectType
                CreatedBy =  $ListItem.FieldValues.Author.Email
                CreatedOn = $ListItem.FieldValues.Created
                ModifiedBy =  $ListItem.FieldValues.Editor.Email
                ModifiedOn = $ListItem.FieldValues.Modified
                FileSize = $ListItem.FieldValues.File_x0020_Size
            })
            $DataCollection += $Data
        }
        $Query.ListItemCollectionPosition = $ListItems.ListItemCollectionPosition
    }While($Query.ListItemCollectionPosition -ne $null)

    #Export Documents data to CSV
    $DataCollection | Export-Csv -Path $CSVPath -Force -NoTypeInformation
    Write-host -f Green "Document Library Inventory Exported to CSV!"
}
Catch {
    write-host -f Red "Error:" $_.Exception.Message
}

Get File-Folder Structure in a Document Library using PnP PowerShell
Similarly, If you want to export all file-folders structure of a document library to CSV file, use this PnP PowerShell script:
#Parameters
$SiteURL = "https://crescent.sharepoint.com/sites/RI/"
$ListName= "Non-Transaction"
$ReportOutput = "C:\Temp\ListInventory.csv"
 
#Connect to SharePoint Online site
Connect-PnPOnline $SiteURL -UseWebLogin
 
#Array to store results
$Results = @()
 
#Get all Items from the document library
$List  = Get-PnPList -Identity $ListName
$ListItems = Get-PnPListItem -List $ListName -PageSize 500
Write-host "Total Number of Items in the List:"$List.ItemCount

$ItemCounter = 0 
#Iterate through each item
Foreach ($Item in $ListItems)
{
        $Results += New-Object PSObject -Property ([ordered]@{
            Name              = $Item["FileLeafRef"]
            Type              = $Item.FileSystemObjectType
            FileType          = $Item["File_x0020_Type"]
            RelativeURL       = $Item["FileRef"]
            CreatedBy         = $Item["Author"].Email
            CreatedOn         = $Item["Created"]
        })
    $ItemCounter++
    Write-Progress -PercentComplete ($ItemCounter / ($List.ItemCount) * 100) -Activity "Processing Items $ItemCounter of $($List.ItemCount)" -Status "Getting Metadata from Item '$($Item['FileLeafRef'])"          
}

#Export the results to CSV
$Results | Export-Csv -Path $ReportOutput -NoTypeInformation
Write-host "Document Library Inventory Exported to CSV Successfully!"
and the output report of the script:
Get sharepoint online document library inventory using powershell

9 comments:

  1. What if you only want the folder structure, no file names

    ReplyDelete
    Replies
    1. Use the CAML Filter: <FieldRef Name='FSObjType' /><Value Type='Integer'>1</Value>

      Delete
  2. thanks for this awesome script! saves me a lot of time (I hope) Do you happen to know what i'm doing wrong to get this error?

    PS C:\WINDOWS\system32> #Load SharePoint CSOM Assemblies
    PS C:\WINDOWS\system32> Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
    Add-Type : Cannot bind parameter 'Path' to the target. Exception setting "Path": "Cannot find path 'C:\Program
    Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll' because it does
    not exist."
    At line:1 char:16
    + ... -Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Serve ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : WriteError: (:) [Add-Type], ParameterBindingException
    + FullyQualifiedErrorId : ParameterBindingFailed,Microsoft.PowerShell.Commands.AddTypeCommand

    ReplyDelete
  3. ok i got around the error messages by replacing the first two lines with:
    [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client")
    [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime")

    but for some reason, its only listing one file in the CSV :( so close but I'm still missing something

    ReplyDelete
  4. ok i didn't realize you have to change the list name for each library and run the script again. Awesome! I got what I needed, thanks again for the excellently written script!

    ReplyDelete
  5. How to get the file and folder structure from an entire site instead of changing document library name one by one?

    ReplyDelete
  6. Can I just get the File name instead of File name with extension? (I need to remove extension!)

    ReplyDelete
    Replies
    1. There are no properties to get just the file name. However, You can use: $Item.FieldValues.FileLeafRef.Replace(".$($Item.FieldValues.File_x0020_Type)","")

      Delete

Please Login and comment to get your questions answered!

Powered by Blogger.