SharePoint Item Level Permissions using PowerShell and CSOM

I generally try to avoid using item level permissions, but I had a specific scenario where these were needed. Had I been using an on-premise solution I would have built a timer job to manage the permissions, however as Office 365 was being used I decided to build a PowerShell script using the Client Side Object Model – the script is executed every night.

  • The script iterates through a couple of lists each night a performs a couple of actions:
    Checks for new items
  •  Based on the list item data, find the column ‘EmployeeId’ and query active directory to find the User Principle Name (UPN) (EmployeID is stored against each user in AD).
  • If the above action finds a user from AD the script removes all permissions on the list item and sets unique permissions so only the employee and a management group have access to that list item.

The following code snippets assume a connection to SharePoint is open (ClientContext), and the current web is loaded into context.

To find the SharePoint group the following was used:

# Load in list of groups on the current web.
$groups = $web.SiteGroups
$ctx.Load($groups)
$ctx.ExecuteQuery()

# Find the group called HR. Note - using GetGroupByName was not working, therefore I had to iterate through the groups.

foreach($group in $groups)
{

if($group.Title -eq "hr")
{
$hrGrp = $group.Id
}
}

# Get the group and load into context to be used.
$spGrp = $groups.GetById($hrGrp)
$ctx.Load($spGrp);
$ctx.ExecuteQuery();

To set item level permission on each list item:

# Get the list by Title and load.
$list = $web.Lists.GetByTitle("MyList")
$ctx.Load($list)
$ctx.ExecuteQuery()
$listTitle = $list.Title

# Simple query - purely used to ensure all data is returned.
$camlQuery = New-Object microsoft.SharePoint.Client.CamlQuery
$camlQuery.ViewXml = "10000"
	
# Load in the items.
$collListItem = $list.GetItems($camlQuery)
$ctx.Load($collListItem)
$ctx.ExecuteQuery()

# Iterate through each item.
foreach ($item in $collListItem)
{	
	# reset variable to ensure no false positives.
	$upn = $null
	$user = $null
	$roleAssignment = $null	
	$continue = $false

	# Set a couple of variable, get the user from AD based on employee number.
	$recordId = $item.Id
	$upn = Get-Upn -eid $item["EmployeeID"]
	$continue = $false

	if($upn -ne $null)
	{
		$continue = $true
	}
	else
	{
		Add-LogMessage "ERROR: Missing employee number on record '$recordId' "
	}	

	if($continue)
	{
		# Break inheritance on the list item and remove existing permissons.
		$item.BreakRoleInheritance($false, $true)

		# Get the permissions role for 'Read' and 'Edit'.
		$reader = $web.RoleDefinitions.GetByName("Read");
		$Editor = $web.RoleDefinitions.GetByName("Edit");
		
		# Create a role assignment and apply the 'read' role.
		$roleAssignment = New-Object microsoft.SharePoint.Client.RoleDefinitionBindingCollection($ctx)
		$roleAssignment.Add($reader)
		
		# Create a role assignment for editors - applying the 'edit' role.
		$roleAssignmentEditor = New-Object microsoft.SharePoint.Client.RoleDefinitionBindingCollection($ctx)
		$roleAssignmentEditor.Add($Editor)

		# Ensure the user exists on the site level, using EnsureUser.
		$user = $ctx.Site.RootWeb.EnsureUser($upn)
		$ctx.Load($user)

		# Apply the two permission roles to the list item.
		# $user is a SharePoint user.
		$ctx.Load($item.RoleAssignments.Add($user, $roleAssignment))    
		# spGrp is the HR group returned in the above snippet.
		$ctx.Load($item.RoleAssignments.Add($spGrp, $roleAssignmentEditor))

		# Update field on the list item to show it has ben processed.
		$item["A001"] = "PROCESSED"
		$item.Update()
	}

	# Execute changes.
	$ctx.ExecuteQuery();
}
Advertisements

One thought on “SharePoint Item Level Permissions using PowerShell and CSOM

  1. Awesome David… This is exactly what i was looking for.. I was breaking my head until i found this… Thanks a lot !!!!!!!!!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s