This article is contributed. See the original author and article here.

Following part 1 of How to Manage SharePoint via PowerShell, we’ll now look at getting started to interact with lists, libraries, and permissions.  Let’s get started!

How to get the information you need?

To get all the lists & libraries in a site, run Get-PnPList. Note there’s no Get-PnPLibrary cmdlet because under the hood, everything is a “list”. If you wish to differentiate what you want (list, library, or any other type available), you can use the ‘BaseTemplate’ property.
Connect-PnPOnline -Url ""
Get-PnPList | Where-Object {$_.BaseTemplate -eq 101}​
Where did I get this 101 number? Here’s a handy link for your future scripts, refer to the Template Id column: ListTemplateEnumeration.
Get all the files in multiple libraries
We use PowerShell for bulk actions right? So let’s loop through multiple libraries within a site, and retrieve all the files.
#Connect to the targeted site
Connect-PnPOnline -Url ""

#Declare variables
$results = @()
$allLibs = Get-PnPList | Where-Object {$_.BaseTemplate -eq 101}

foreach ($lib in $allLibs) {      
    #Store all docs in a variable
    $allItems = Get-PnPListItem -List $lib.Title
    foreach($item in $allItems){
        $results += [PSCustomObject][ordered]@{
            FileName    = $item["FileLeafRef"] 
            CreatedBy   = $item.FieldValues.Author.LookupValue
            CreatedDate = [DateTime]$item["Created_x0020_Date"]
            FilePath    = $item["FileRef"]



The properties are entirely up to you to decide. If you need all the files, for all sites, just add another loop. Be aware that if you have thousands of sites/libraries/documents, this might not be the best idea from a performance perspective.

Filtering results with conditions

In this scenario, we’d want all the files where the size is above 50MB for instance. Maybe there are videos in your SharePoint environment(s)?
#Connect to SPO Site
Connect-PnPOnline -Url ""

#Store in variable all the document libraries in the site
$docLibrary = Get-PnPList | Where-Object { $_.BaseTemplate -eq 101 }

foreach ($docLib in $docLibrary) {
    #Get list of all folders in the document library
    $AllItems = Get-PnPListItem -List $docLib -Fields "SMTotalFileStreamSize"
    #Loop through each files/folders in the document library for files >50Mb
    foreach ($item in $allItems) {
        if ((([int]$item["SMTotalFileStreamSize"]) -ge 50000000) -and ($item["FileLeafRef"] -like "*.*")) {
            Write-Host "File found:" $item["FileLeafRef"] -ForegroundColor Yellow
                FileName         = $item["FileLeafRef"] 
                FilePath         = $item["FileRef"]
                SizeInMB         = ($item["SMTotalFileStreamSize"] / 1MB).ToString("N")
                LastModifiedBy   = $item.FieldValues.Editor.LookupValue
                EditorEmail      = $item.FieldValues.Editor.Email
                LastModifiedDate = [DateTime]$item["Modified"]
This script is a bit special because we needed to filter even more with ($item[“FileLeafRef”] -like “*.*”) to return the appropriate results and skip the folders.

Create custom permissions on multiple sites

Custom permissions are created when Full Control is too much, and Read-only is not enough. So, it might happen that you need to create your own. In this scenario, let’s create a custom permission BUT on multiple sites by importing a CSV file.
Note: The CSV file contains a header called “SiteUrl” (without the quotes)
#Connect to SPO admin center
Connect-PnPOnline -Url

#Import sites from .csv
$mySites = Import-Csv -Path '<YOUR_FILE_PATH>'

#Create all for each site
foreach ($site in $mySites) {    
    #Connect to each site
    Write-Host "Connecting to $($site.SiteUrl)" -ForegroundColor Green
    Connect-PnPOnline -Url $site.SiteUrl
    #Create the NEW permission level (clone the 'READ' default permissions)
    $PermToClone = Get-PnPRoleDefinition -Identity "Read"
    $addPnPRoleDefinitionSplat = @{
        Include     = 'ManagePersonalViews', 'UpdatePersonalWebParts', 'AddDelPrivateWebParts'
        Description = "Copy of Read + Personal Permissions"
        RoleName    = "myCustomPermLevel"
        Clone       = $PermToClone
    Add-PnPRoleDefinition @addPnPRoleDefinitionSplat
If the format of this script is not familiar to you, I’m using splatting. which allows to pass parameters with a slightly different syntax. Want to know more? check out this Microsoft documentation.


There you have it. I hope this will get you get started on how to manage your SharePoint environment(s) using PowerShell, and if you want to know more, feel free to leave your comments below :)

Happy scripting!

Brought to you by Dr. Ware, Microsoft Office 365 Silver Partner, Charleston SC.

%d bloggers like this: