How to Make a Subsite Read-Only using PowerShell?

Requirement: Make a SharePoint Subsite read-only.

This method replaces all other permissions applied on the subsite with "Read" and can't be reverted! Make sure you are proceeding only in scenarios where you don't need to revert the read-only (E.g. Post migration)! You can take backup of the existing permissions though.

How to Make a Subsite Read-only by Resetting Permissions?
We can make a SharePoint subsite to read-only by replacing all user and group permissions to the "Read" permission level.
  • Navigate to the subsite >> Click on Site Settings >> Site Permissions
  • In the site permissions page, Leave all users and groups with "Read", "View Only" or "Limited Access" rights and select the rest.
  • Click on the "Edit User Permissions" button from the ribbon to bulk edit permission levels of the selected users and groups.make a sharepoint subsite read-only
  • Select "Read" permission level and  Click on "OK" to save! how to make sharepoint subsite read only
This sets the subsite read only.

These methods don't control Farm Administrators, Site Collection Administrators!

PowerShell to Reset Subsite Permissions to Read-Only:
Here is the SharePoint PowerShell to make subsite read only
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Parameters
$SubsiteURL = "http://intranet.crescent.com/legal"

#Get the Subsite
$Web = Get-SPWeb $SubsiteURL

#Break Permission Inheritance, if not already
If(!$Web.HasUniqueRoleAssignments)
{
    $Web.BreakRoleInheritance($true)
}

#Get Required Permission Levels
$ReadPermission = $web.RoleDefinitions["Read"]
$ViewOnlyPermission = $web.RoleDefinitions["View Only"]
$LimitedAccessPermission = $web.RoleDefinitions["Limited Access"]

#Add Read Permission to Role Assignment, if not added already
ForEach ($RoleAssignment in $Web.RoleAssignments) 
{
    $RoleDefinitionBindings = $RoleAssignment.RoleDefinitionBindings
    If(!($RoleDefinitionBindings.Contains($ReadPermission) -or $RoleDefinitionBindings.Contains($ViewOnlyPermission) -or $RoleDefinitionBindings.Contains($LimitedAccessPermission)))
    {
        $RoleAssignment.RoleDefinitionBindings.Add($ReadPermission)
        $RoleAssignment.Update()
        Write-host "Added Read Permissions to '$($RoleAssignment.Member.Name)'" -ForegroundColor Green
    }
}

#Remove All permissions other than Read or Similar
ForEach ($RoleAssignment in $Web.RoleAssignments) 
{ 
    $RoleDefinitionBindings = $RoleAssignment.RoleDefinitionBindings
    For($i=$RoleAssignment.RoleDefinitionBindings.Count-1; $i -ge 0; $i--)
    {
        $RoleDefBinding = $RoleAssignment.RoleDefinitionBindings[$i] 
        If( ($RoleDefBinding.Name -eq "Read") -or ($RoleDefBinding.Name -eq "View Only") -or ($RoleDefBinding.Name -eq "Limited Access") )
        {
            Continue;
        }
        Else
        {
            $RoleAssignment.RoleDefinitionBindings.Remove($RoleAssignment.RoleDefinitionBindings[$i])
            $RoleAssignment.Update()
            Write-host "Removed '$($RoleDefBinding.Name)' Permissions from '$($RoleAssignment.Member.Name)'" -ForegroundColor Yellow
        }
    }
}

Wait, What if the lists, libraries, folders or files in the subsite have unique permission (broken inheritance!)? Let's extend the script to reset permissions on all underlying objects.
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Function to replace all permission levels granted with "Read"
Function Reset-Permissions([Microsoft.SharePoint.SPSecurableObject]$Object)
{
    #Add Read Permission to Role Assignment, if not added already
    ForEach ($RoleAssignment in $Object.RoleAssignments) 
    {
        $RoleDefinitionBindings = $RoleAssignment.RoleDefinitionBindings
        If(!($RoleDefinitionBindings.Contains($ReadPermission) -or $RoleDefinitionBindings.Contains($ViewOnlyPermission) -or $RoleDefinitionBindings.Contains($LimitedAccessPermission)))
        {
            $RoleAssignment.RoleDefinitionBindings.Add($ReadPermission)
            $RoleAssignment.Update()
            Write-host "`tAdded Read Permission to '$($RoleAssignment.Member.Name)'" -ForegroundColor Green
        }
    }

    #Remove All permissions other than Read or Similar
    ForEach ($RoleAssignment in $Object.RoleAssignments) 
    { 
        $RoleDefinitionBindings = $RoleAssignment.RoleDefinitionBindings
        For($i=$RoleAssignment.RoleDefinitionBindings.Count-1; $i -ge 0; $i--)
        {
            $RoleDefBinding = $RoleAssignment.RoleDefinitionBindings[$i] 
            If( ($RoleDefBinding.Name -eq "Read") -or ($RoleDefBinding.Name -eq "View Only") -or ($RoleDefBinding.Name -eq "Limited Access") )
            {
                Continue;
            }
            Else
            {
                $RoleAssignment.RoleDefinitionBindings.Remove($RoleAssignment.RoleDefinitionBindings[$i])
                $RoleAssignment.Update()
                Write-host "`tRemoved '$($RoleDefBinding.Name)' Permission from '$($RoleAssignment.Member.Name)'" -ForegroundColor Yellow
            }
        }
    }
}

#Parameters
$SubsiteURL = "http://intranet.sharepoint.com/2010"

#Get the Subsite
$Web = Get-SPWeb $SubsiteURL

#Break Permission Inheritance of the subsite, if not already
If(!$Web.HasUniqueRoleAssignments)
{
    $Web.BreakRoleInheritance($true)
}

#Get Required Permission Levels
$ReadPermission = $web.RoleDefinitions["Read"]
$ViewOnlyPermission = $web.RoleDefinitions["View Only"]
$LimitedAccessPermission = $web.RoleDefinitions["Limited Access"]

#Call the function to Reset Web permissions
Write-host "Resetting Permissions on Web..."-NoNewline
Reset-Permissions $Web
Write-host "Done!" -f Green

#Array to Skip System Lists and Libraries
$SystemLists [email protected]("Converted Forms", "Master Page Gallery", "Customized Reports", "Form Templates", "List Template Gallery", "Theme Gallery", 
           "Reporting Templates", "Solution Gallery", "Style Library", "Web Part Gallery","Site Assets", "wfpub")
  
#Loop through each list in the web
Foreach ($List in $Web.Lists)
{
    #Get only lists with unique permissions & Exclude Hidden System libraries
    If (($List.Hidden -eq $false) -and ($SystemLists -notcontains $List.Title) -and ($List.HasUniqueRoleAssignments) )
    {
        #Call the function to Reset List permissions
        Write-host -NoNewline "Resetting Permissions on List '$($List.title)'..."
        Reset-Permissions $List
        Write-host "Done!" -f Green
    }
}

#Check List items with unique permissions
Foreach ($List in $Web.Lists)
{
    #Get only lists with unique permissions & Exclude Hidden System libraries
    If (($List.Hidden -eq $false) -and ($SystemLists -notcontains $List.Title))
    {
        #Get All list items with unique permissions
        $UniqueItems = $List.GetItemsWithUniquePermissions()
        If($UniqueItems.count -gt 0)
        {
            #Call the function to Reset List Item permissions
            Write-host "Resetting Permissions on List Items of '$($List.title)'"
            $UniqueItems | ForEach-Object {
                Reset-Permissions $List.GetItemById($_.ID)
            }            
        }
    }
}
Here is my another post on how to set SharePoint list to read-only How to Make a SharePoint List or Library to Read Only Mode using PowerShell?

No comments:

Please Login and comment to get your questions answered!

Powered by Blogger.