Create Custom Permissions for multiple Site Collections in SPO using PowerShell PnP

It might be useful from time to time, and depending on the business requirements, to create custom permissions in SharePoint.
Best practice would want to copy (or duplicate) a default permission already in SharePoint (and not modify any built-ins), and then add/remove whatever you don’t need.

In this blog post, we are going to use SharePoint PowerShell PnP to create custom permissions for multiple Sites in SharePoint Online.



For brand new sites, this is what we’ve got as built-in permissions under Site Permissions >> Permission Levels (in the ribbon):

  • Full Control
  • Design
  • Edit
  • Contribute
  • Read


Built-In Permissions


Let’s take the scenario where we’d like to add a little bit more to the “Read” permission level 😇
The below are currently unchecked, so let’s add them in!


Currently unchecked in the Read perm level



Create the PowerShell script

For this scenario, and because we’re going to be using a built-in permission level as the source, we’re going to clone it, and add other permissions to it.
Remember that we’d like to create this custom permission for multiple sites, therefore, we can use a .csv file containing our sites, and integrate it in the script.

The .csv file looks like this:


CSV file


For the PowerShell script, let’s explain the steps first.

    1. Connect to SharePoint Online Admin Center using the Connect-PnPOnline cmdlet (my credentials are stored in the Credential Manager so I’m not using the -Credential parameter)
    2. Import the Sites contained in the csv file using the Import-Csv cmdlet
    3. Create a foreach loop, where we:
      a)  Connect to each site in the csv file to access it
      b)  Retrieve the “Read” permission level using the Get-PnPRoleDefinition cmdlet + store it in a variable
      c)  Run the Add-PnPRoleDefinition cmdlet by using splatting (not necessary, but just a way for the code to be easier to read by other colleagues for instance!)


So the script will look like this:

ℹ️ Replace the placeholders by your tenant name & the path for your csv file

#Connect to SPO admin center
Connect-PnPOnline -Url https://<TENANT_NAME>

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

#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




The results after running the script should look like the below on each site 🙂


Custom permissions created


And the Personal Permissions are now checked!


Personal Permissions checked


What else?

Well… You could also use this script and, at the same time…

  1. Create a new SharePoint group using the New-PnPGroup
  2. Set this custom permission to the newly created SharePoint group using Set-PnPGroupPermissions
  3. And finally, add members to this group using the Add-PnPUserToGroup


Just as an example… 😉



Comments are closed.

%d bloggers like this: