Use PowerShell to Update Item Permssions in SharePoint

What if you want to update the item permissions on every item in a list or library, BUT you don’t want to trigger an associated workflow?

Why?

Request came in to add a new SharePoint group to all the items in a library.  Options were to update EVERY item in the library and let the workflow update the permissions. Or, update the items ONE AT A TIME.

OR

Use PowerShell to update item permissions and not stress the server(s).


# add powershell snapin
 $web = Get-SPWeb -Identity "http://sharepointed.com"
$list = $web.Lists.TryGetList("Taco Time")
$group = "Taco Makers"
$PermissionLevel = "Read"

if ($list -ne $null)
{
	foreach ($item in $list.Items)
	{
		if ($item.HasUniqueRoleAssignments -eq $False)
		{
			$item.BreakRoleInheritance($True)
		}
		else
		{
			if ($web.SiteGroups[$group] -ne $null)
			{
				$group = $web.SiteGroups[$group]
				$roleAssignment = new-object Microsoft.SharePoint.SPRoleAssignment($group)
				$roleDefinition = $web.RoleDefinitions[$PermissionLevel];
				$roleAssignment.RoleDefinitionBindings.Add($roleDefinition);
				$item.RoleAssignments.Add($roleAssignment)
			}
			else
			{
				Write-Host "Group is not valid."
			}
		}
	}
}
$web.Dispose()

How to control permissions from a central List

Say you have  your site setup where every one of your customers has a sub site.  How could you easily manage the permissions on those sites?  What I have adopted is, creating a List where the sub sites are created from and managed.

Using the workflow actions from ilovesharepoint I’m doing the following.

1. Setup a Contact List (Customers) with these additional fields: Customer Site (Hyperlink), UserPermissions(Person or Group), Customer Status (Choice)

2. Using the ilovesharepoint Create a new site action, create a new customer site.  Using the Output variable of this action, write the URL to our Customer Site field.

3. Use the ilovesharepoint Execute PowerShell action to run our PowerShell script.


Add-PsSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
 $site = Get-SPweb "http://www.sharepointed.com"

$mList=$site.Lists["Customers"]
 #Here you will want to add the ID of the item calling the workflow.
 #Simply remove [%Current Item:ID%], click on Add or Change Lookup, and add the ID field
 $item = $mList.GetItemById([%Current Item:ID%])
 $ActionType=$Item["Customer Status"]
 $CustomerSite= new-object Microsoft.SharePoint.SPFieldUrlValue($item["Customer Site"])
 $ClientSiteURL=$CustomerSite.URL
 $users=$item["UserPermissions"]

#build array of User Permissions
 $PowerUsr = New-Object System.Collections.ArrayList

foreach($usr in $users)
	{	 
						
		 $sUser = $usr.User
		 if($sUser -ne $null)
		 {
			$parseUsr = $site.SiteUsers.GetByID($usr.LookupId)
		 }
		 else
		 {
			$parseUsr = $usr.LookupValue
		 }
						 
		$PowerUsr.add($parseUsr)					 
	}

$web = Get-SPWeb $ClientSiteURL
$SDlist = $web.Lists["Shared Documents"]

#break role inheritance
 $SDlist.BreakRoleInheritance($true)

#remove all permissions from the List
 foreach ($assignment in $SDlist.RoleAssignments)
 {
 $assignment.RoleDefinitionBindings.RemoveAll();
 $assignment.Update();
 }

# Customer Status = Active
 If ($ActionType -eq "Active")
 {
 		if($PowerUsr.Count -ge 0)
		{
			foreach($Ausr in $PowerUsr)
				{
					$siteUsr = ""
					$account = ""
					$siteUsr = $site.SiteUsers[$Ausr]
					$siteGroup = $web.SiteGroups[$Ausr]
					
					if($siteUsr -ne $null)
					{
						$role = $web.RoleDefinitions["Read"]
						$assignment = New-Object Microsoft.SharePoint.SPRoleAssignment($siteUsr)
						$assignment.RoleDefinitionBindings.Add($role)
						$SDlist.RoleAssignments.Add($assignment)
						$web.RoleAssignments.Add($assignment)

					}
					else
					{
						$role = $web.RoleDefinitions["Read"]
						$assignment = New-Object Microsoft.SharePoint.SPRoleAssignment($siteGroup)
						$assignment.RoleDefinitionBindings.Add($role)
						$SDlist.RoleAssignments.Add($assignment)
						$web.RoleAssignments.Add($assignment)
					}
				}
		}
 }

# Customer Status = Not Active
 If ($ActionType -eq "Not Active")
 {
 if($PowerUsr.Count -ge 0)
 {
 foreach($Ausr in $PowerUsr)
 {
 $account = $web.SiteGroups[$Ausr]
 $role = $web.RoleDefinitions["Read"]

$assignment = New-Object Microsoft.SharePoint.SPRoleAssignment($account)
 $assignment.RoleDefinitionBindings.Add($role)
 $SDlist.RoleAssignments.Add($assignment)
 }
 }
 }

$SDlist.Update()
$web.Dispose()
$site.Dispose()

The script gets the URL of our sub site and permissions we are wanting to set on the Shared Documents library. By setting the Customer Status to Active or Not Active, the script will change the permissions accordingly.

*update*
Updated the script to work with users and groups.