Small Tricks and Tips : Microsoft 365 – PnP PowerShell – Breaking permission inheritance on subsites, all lists and list items

Hi All,
Greetings for the day!!!
Today new learning using – PnP PowerShell
Background / Use Cases
- We have scenario where we are migrating SharePoint Online sub sites only and not complete site collection
- So before migrating we need to make respective sub sites read only so users wont able to update the content
- But there is no OOB way to lock / make read only sub sites only
- So we have an approach is break the inheritance on sub sites including on all lists and listitems
- Next, set all user permissions to read only at each level – sub sites / Lists / ListItems
So here in this article I’ll be sharing first scenario – In SharePoint online – breaking permission inheritance on Sub Sites, Lists and list items using PnP PowerShell
Prerequisites
- Make sure PnP PowerShell module is installed
- We have detailed article on connecting our Microsoft 365 tenant using PnP, please have a look – https://knowledge-junction.in/2021/12/16/microsoft-365-few-approaches-options-for-connecting-to-tenant-using-pnp-powershell-connect-pnponline-part-1/
- We have one more another article – connecting Microsoft 365 tenant using PnP PowerShell when MFA is enabled – Microsoft 365 : PowerShell – Connect-PnPOnline – resolving error – AADSTS50126: Error validating credentials due to invalid username or password Microsoft – even though user name and password are correct – https://knowledge-junction.in/2023/04/03/microsoft-365-powershell-connect-pnponline-resolving-error-aadsts50126-error-validating-credentials-due-to-invalid-username-or-passwordmicrosoft-even-though-user-name-and-password-are-corre/
Details
- Here I’ll demonstrate for one subsite and then share complete script with reading list of subsites from CSV file
- We have detailed article for reading CSV file, please have a look – Read a CSV file with PowerShell using the Import-CSV function – https://knowledge-junction.in/2022/10/29/read-a-csv-file-with-powershell-using-the-import-csv-function/
- Connect to respective sub-site where we need to break the permission inheritance
- We will connect using PnP PowerShell CMDLET – Connect-PnPOnline
Connect-PnPOnline -Url <SubSiteURL> -Interactive
Example :
Connect-PnPOnline -Url https://knowledgejunction1.sharepoint.com/sites/Demo/PermissionsDemo -Interactive
In above code we are connecting to sub site – https://knowledgejunction1.sharepoint.com/sites/Demo/PermissionsDemo
- Permissions before breaking Sub Site level permission inheritance
- Permissions before breaking List level permission inheritance
- Permissions before breaking List Item level permission inheritance
- Now lets break the inheritance at each level – Sub-Site, List and ListItem
- For every object there is unique property to check if unique permissions are there or not – HasUniqueRoleAssignments
- And to break permission inheritance, every object has a common function – BreakRoleInheritance()
- Breaking permission inheritance at sub site level – To perform respective operation we need to connect the SharePoint online sub-site. In previous code segment we already connected
- Next step is to get the respective sub-site / web – Get-PnPWeb
#Get the web
$Web = Get-PnPWeb
- As we get respective web object for given sub-site, next to check if web has uniqe permissions or not – Web.HasUniqueRoleAssignments
#Remove unique permissions
if(!$web.HasUniqueRoleAssignments)
{
#if not then break the inheritance
}
- If web has not unique permissions then break the permissions
#Remove unique permissions
if(!$web.HasUniqueRoleAssignments)
{
$Web.BreakRoleInheritance($false,$false)
}
- Breaking permission inheritance at List level
- We will read the List – Get-PnPList
$documentLibrary = Get-PnPList -Identity "Shared Documents"
- As a next step, we will check in permission inheritance on given list already broken or not –
if(!documentLibrary.HasUniqueRoleAssignments)
- If permission inheritance for document library is not broken then we will broke the permission inheritance using – BreakRoleInheritance function
if(!$documentLibrary HasUniqueRoleAssignments){
$documentLibrary .BreakRoleInheritance($false,$false)
}#if(!$documentLibrary.HasUniqueRoleAssignments)
- Breaking permission inheritance at listi items level – we will get all listitems using CMDLET – Get-PnPListItem
- For list item we will use Get-PnPProperty CMDLET to read the “HasUniqueRoleAssignments” property
#going through all the list items - if permissions are inherited, breaking them
$listitems = Get-PnPListItem -List $documentLibrary.Title
#Iterate through each list item
ForEach($ListItem in $ListItems)
{
#Check if the Item has unique permissions
$HasUniquePermissions = Get-PnPProperty -ClientObject $ListItem -Property "HasUniqueRoleAssignments"
If(!$HasUniquePermissions)
{
$ListItem.BreakRoleInheritance($false,$false)
}#If(!$HasUniquePermissions)
}#ForEach($ListItem in $ListItems)
- After executing the complete script
- Respective Sub-Site level permissions will be
- Respective List level (document library) permissions will be
- List items permissions will be
Complete Script
- In below script we are reading the URLs of list of sub-sites from CSV file
#Loop through list of subsites - read from CSV file
#If there is no unique permission - break the inheritance
#Parameters - CSV file path from which we will be reading URLof CSV file
$CSVFilePath = "C:\PS\Making Subsite - readonly\subsites.csv"
Try {
#Read from CSV file and delete
Import-CSV $CSVFilePath | ForEach-Object {
Write-Host "Processing subsite" - $_.SubSiteURL
#Connect PnP Online
Connect-PnPOnline -Url $_.SubSiteURL -Interactive
#Get the web
$Web = Get-PnPWeb
#Remove unique permissions
if(!$web.HasUniqueRoleAssignments)
{
#break the permission inheritance on respective sub-site
$Web.BreakRoleInheritance($false,$false)
}
Invoke-PnPQuery
#get all lists from the current sub-site
Get-PnPList |ForEach-Object {
#avoid lists which we do not want to process
if($_.Title -ne "Composed Looks" -and
$_.Title -ne "Master Page Gallery" -and
$_.Title -ne "Site Assets" -and
$_.Title -ne "Site Pages" -and
$_.Title -ne "Web Template Extensions" ) {
Write-Host "Processing List" $_.Title
#check - current list has unique permissions
if(!$_.HasUniqueRoleAssignments){
#if not - break the permission inheritancd
$_.BreakRoleInheritance($false,$false)
}#if(!$_.HasUniqueRoleAssignments)
#going through all the list items - if permissions are inherited, breaking them
$listitems = Get-PnPListItem -List $_.Title
#Iterate through each list item
ForEach($ListItem in $ListItems)
{
#Check if the Item has unique permissions
$HasUniquePermissions = Get-PnPProperty -ClientObject $ListItem -Property "HasUniqueRoleAssignments"
If(!$HasUniquePermissions)
{
$ListItem.BreakRoleInheritance($false,$false)
}#If(!$HasUniquePermissions)
}#ForEach($ListItem in $ListItems)
}#if(! $_.Title -eq "Composed Looks"
}#Get-PnPList |ForEach-Object
Invoke-PnPQuery
}#foreach
}
catch {
write-host "Error: $($_.Exception.Message)" -foregroundcolor Red
$error1 = New-Object PSObject -Property @{ Exceptions = "Error: $($_.Exception.Message)"}
$error1 | Export-Csv -Append -Path "C:\Users\u1086350\Desktop\PS\Making Subsite - readonly\ErrorLogs.csv"
}
If you want to start your Microsoft 365 PowerShell journey – please have a look at my recent book – Microsoft 365 Power Shell hand book for Administrators and Beginners and 100 Power Shell Interview Questions

Thanks for reading !!! HAVE A FANTASTIC LEARNING AHED!!!
You must be logged in to post a comment.