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, 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"

#get site group and setup permission/role
$group = $web.Groups[$group]
$roleAssignment = new-object Microsoft.SharePoint.SPRoleAssignment($group)
$roleDefinition = $web.RoleDefinitions[$PermissionLevel];
$roleAssignment.RoleDefinitionBindings.Add($roleDefinition);

if ($list -ne $null)
{
	foreach ($item in $list.Items)
	{
		if ($item.HasUniqueRoleAssignments -eq $False)
		{
			$item.BreakRoleInheritance($True)
		}
	       
                if ($web.SiteGroups[$group] -ne $null)
		{
			$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.

PowerShell SharePoint User Access

Let me start this off by saying I’m new to PowerShell AND I’m sure someone could sum up my code in one line of code.

I was asked to provide a list of all users in a SharePoint Site Collection / Web App. The person asking this, was wanting to see each user, the site and list they had access to. More or less I needed to iterate through all the sites, loop on the user, loop again on the site, then loop on the lists.

So the layout I could provide was:

Site Collection
User Name
Site
List

I’m outputting the results to a file name UserAccess.txt on the C:\ drive.

[System.Reflection.Assembly]::Load(“Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c”)
[System.Reflection.Assembly]::Load(“Microsoft.SharePoint.Portal, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c”)

$spsite=[Microsoft.SharePoint.SPSite]("http://sharepoint/")

out-file c:\UserAccess.txt -append

foreach ($Site in $spsite.AllWebs)
{
    "Site Collection Name:  $Site" | out-file c:\UserAccess.txt -append
    foreach ($User in $Site.SiteUsers)
    {
        "--User Name: $User" | out-file c:\UserAccess.txt -append
        foreach ($Site in $spsite.AllWebs)
        {
					$SitePermissions = $Site.Permissions
					foreach($mySitePermission in $SitePermissions)
					{
						if($User.ID -eq $mySitePermission.Member.ID)
						{
                            "----Site Name: $Site" | out-file c:\UserAccess.txt -append
						}
					}

                    foreach($myList in $Site.lists)
        			{

        					$myListPermissions = $myList.Permissions
        					foreach($myListPermission in $myListPermissions)
        					{
        						if($User.ID -eq $myListPermission.Member.ID)
        						{
                                    "------List Name: $MyList" | out-file c:\UserAccess.txt -append
        						}
        					}
        			}

                 $Site.Dispose()
			}
            $Site.Dispose()
        }
    }

Let me know if you have any questions or need any help.