SharePoint Online: Grant Permission to List Item using PowerShell

Permissions are hierarchical in SharePoint from Top Site collection till the List Item level. When items are created in a list or library, they inherit the permissions of that list or library. However, This inheritance can be broken and permissions can be applied directly to the items. To set unique permissions on list items, you need to configure permissions on item level. Here is how:

How to Grant Access to Individual List Items in SharePoint Online?
Got a business requirement to grant permissions at List item level. To set explicit permissions on SharePoint online list items, we need to break the permission inheritance first (stop inheriting permissions) and then add user or group to the List Item.
  • Go to your SharePoint Online list or library >> Select the Item to which you want to provide unique permissions. 
  • Click on "Shared With" button from the ribbon. On the Shared With page, click Advanced.
    set item level permission in sharepoint online
  • On the Permissions tab, in the Inheritance group, click Stop Inheriting Permissions button. Confirm the prompt.
    sharepoint online list item permissions powershell
  • Now, from the ribbon, click on "Grant Permissions." button. In the Share dialog box, enter names, email addresses. Click the Show Options button. In the Select A Permission Level list box, select appropriate permission level such as Edit.
    powershell to grant permission to list item in sharepoint online
  • Click Share.
Having too many Item level permissions often leads to performance issues! so, be careful.

SharePoint Online: Set List Item Permissions using PowerShell:
Here is my PowerShell to grant permissions in SharePoint Online
#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"

#To call non-generic method Load(list, x => x.HasUniqueRoleAssignments)
Function Invoke-LoadMethod() {
    param(
            [Microsoft.SharePoint.Client.ClientObject]$Object = $(throw "Please provide a Client Object"),
            [string]$PropertyName
        ) 
   $ctx = $Object.Context
   $load = [Microsoft.SharePoint.Client.ClientContext].GetMethod("Load") 
   $type = $Object.GetType()
   $clientLoad = $load.MakeGenericMethod($type)

   $Parameter = [System.Linq.Expressions.Expression]::Parameter(($type), $type.Name)
   $Expression = [System.Linq.Expressions.Expression]::Lambda([System.Linq.Expressions.Expression]::Convert([System.Linq.Expressions.Expression]::PropertyOrField($Parameter,$PropertyName),[System.Object] ), $($Parameter))
   $ExpressionArray = [System.Array]::CreateInstance($Expression.GetType(), 1)
   $ExpressionArray.SetValue($Expression, 0)
   $clientLoad.Invoke($ctx,@($Object,$ExpressionArray))
}

Function Set-ListItemPermission
{
    param
    (   
        [Parameter(Mandatory=$true)] [string]$SiteURL,
        [Parameter(Mandatory=$true)] [string]$ListName,
        [Parameter(Mandatory=$true)] [string]$ItemID,
        [Parameter(Mandatory=$true)] [string]$PermissionLevel,
        [Parameter(Mandatory=$true)] [string]$UserID
    )
    Try {
        #Setup Credentials to connect
        $Cred= Get-Credential
        $Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)

        #Setup the context
        $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
        $Ctx.Credentials = $Credentials
        
        #Get the List and Item
        $List = $Ctx.Web.Lists.GetByTitle($ListName)
        $ListItem=$List.GetItemByID($ItemID)
        $Ctx.Load($List)
        $Ctx.Load($ListItem)
        $Ctx.ExecuteQuery()

        #Check if Item has unique permission already
        Invoke-LoadMethod -Object $list -PropertyName "HasUniqueRoleAssignments"
        $Ctx.ExecuteQuery()

        #Break Item's permission Inheritance, if its inheriting permissions from the parent
        if (-not $ListItem.HasUniqueRoleAssignments)
        {
            $ListItem.BreakRoleInheritance($false, $false) #keep the existing permissions: No -  Clear listitems permissions: No
            $ctx.ExecuteQuery()
        }

        #Get the User
        $User = $Ctx.Web.EnsureUser($UserID)
        $Ctx.load($User)
        $Ctx.ExecuteQuery()

        #Get the role 
        $Role = $Ctx.web.RoleDefinitions.GetByName($PermissionLevel)
        $RoleDB = New-Object Microsoft.SharePoint.Client.RoleDefinitionBindingCollection($Ctx)
        $RoleDB.Add($Role)
         
        #Assign permissions
        $UserPermissions = $ListItem.RoleAssignments.Add($User,$RoleDB)
        $ListItem.Update()
        $Ctx.ExecuteQuery()
    
        Write-host -f Green "Permission granted to List Item successfully!"
    }
    Catch {
        Write-host -f Red "Error granting permission to List Item!" $_.Exception.Message
    }
}

#Set parameter values
$SiteURL="https://crescent.sharepoint.com"
$ListName="Projects"
$ItemID="1"
$UserID="salaudeen@crescent.com"
$PermissionLevel="Edit"

#Call the function
Set-ListItemPermission -SiteURL $SiteURL -ListName $ListName -ItemID $ItemID -UserID $UserID -PermissionLevel $PermissionLevel 

This script grants permission on Item level for given user. If you want to provide permission to SharePoint Group, Instead of line
$User = $Web.EnsureUser($UserAccount)
#use:
$Group =$Web.SiteGroups.GetByName($GroupName)
#and then
$GroupPermissions = $Item.RoleAssignments.Add($Group,$RoleDB)

PnP PowerShell to Set Item Level Permission
#Config Variables
$SiteURL = "https://crescenttech.sharepoint.com/sites/Marketing"
$ListName ="Projects"
$ListItemID ="1"
$GroupName="Marketing Members"
$UserID="Peter@TheCrescentTech.com"

#Connect to PnP Online
Connect-PnPOnline -Url $SiteURL -Credentials (Get-Credential)

#Get the Group
$Group = Get-PnPGroup | where-Object {$_.Title -eq $GroupName}

#Grant permission to Group - Remove all existing permissions
Set-PnPListItemPermission -Identity $ListItemID -List $ListName -AddRole "Read" -Group $Group -ClearExisting

#Grant permission to User
Set-PnPListItemPermission -Identity $ListItemID -List $ListName -AddRole "Edit" -User $UserID
Similarly, we can grant permission to all list items as:
#Config Variables
$SiteURL = "https://crescenttech.sharepoint.com/sites/Marketing"
$ListName ="Projects"
$UserID="Peter@TheCrescentTech.com"

#Connect to PnP Online
Connect-PnPOnline -Url $SiteURL -Credentials (Get-Credential)

#Get all list items
$ListItems = Get-PnPListItem -List $ListName
ForEach($ListItem in $ListItems)
{
    #Grant permission on List Item to User
    Set-PnPListItemPermission -Identity $ListItem.ID -List $ListName -AddRole "Edit" -User $UserID
}
SharePoint Online: Grant Permission to List Item using PowerShell SharePoint Online: Grant Permission to List Item using PowerShell Reviewed by Salaudeen Rajack on November 12, 2017 Rating: 5

1 comment:

  1. Hi, I am having trouble getting this to work. Have recent changes in SharePoint Online stopped this method working? Even a simple count of lists returns null.
    Thanks Mark

    ReplyDelete

Please Login and comment to get your questions answered!

Powered by Blogger.