2

I'm trying to show all Item level Permissions in a SharePoint list Column. I already solved this using PowerShell, however it was so slow to run sequentially, I've decided I need a C# Solution:

I have a Multiple "People / Group" field called "WhoHasAccess" which has been added to the "Item" Content Type. This ensures that all files and folders will inherit this column.

What I want is for the Column to be populated with all the User Objects, SharePoint Group Objects, and AD Security Group Objects that have access to the item.

The problem is, I am new to C#. I do not have much of a clue on how to create this, although I would like something that listens for Role Assignment change events, or if that isn't possible perhaps a Custom Field that shows current item permissions.

In PowerShell, I handled getting Folder Permissions like this :

foreach ($Folder in $List.Folders)
{
    if ($Folder.RoleAssignments.Count -gt 0)
    {
        [Microsoft.SharePoint.SPFieldUserValueCollection]$UserCollection = New-Object Microsoft.SharePoint.SPFieldUserValueCollection

        foreach ($Role in $Folder.RoleAssignments)  
        {
            $User = $Role.Member.Name  
            foreach ($Roledef in $Role.RoleDefinitionBindings | where {$_.Name -ne "Limited Access"})  
            {   
                if ($Role.Member.Name -like "*,*" -or $Role.Member.Name -like "*\*") #Handles the UserNames on our Domain
                {
                    #Is User
                    $SPUser = $Web.EnsureUser($Role.Member.Name)
                    $UserFieldValue = New-Object Microsoft.SharePoint.SPFieldUserValue($Web, $SPUser.ID, $SPUser.LoginName)
                    $UserCollection.Add($UserFieldValue)
                }
                else
                {
                    #Is Group
                    $SPGroup = $Web.SiteGroups.GetByName($Role.Member.Name)
                    $UserFieldValue = new-object Microsoft.SharePoint.SPFieldUserValue($Web, $SPGroup.ID, $SPGroup.LoginName)
                    $UserCollection.Add($UserFieldValue)
                }
            }  
        }
    }  
    $Folder["WhoHasAccess"] = $UserCollection
    $Folder.Update()
}

and I handled Item Permissions like this :

foreach ($Item in $List.Items)
{       
    if ($Item.RoleAssignments.Count -gt 0) 
    {
        [Microsoft.SharePoint.SPFieldUserValueCollection]$UserCollection = New-Object Microsoft.SharePoint.SPFieldUserValueCollection

        foreach ($Role in $Item.RoleAssignments)  
        {
            $User = $Role.Member.Name  
            foreach ($Roledef in $Role.RoleDefinitionBindings | where {$_.Name -ne "Limited Access"})  
            {  
                if ($Role.Member.Name -like "*,*" -or $Role.Member.Name -like "*\*") #Handles the UserNames on our Domain
                {
                    #Is User
                    $SPUser = $Web.EnsureUser($role.Member.Name)
                    $UserFieldValue = new-object Microsoft.SharePoint.SPFieldUserValue($Web, $SPUser.ID, $SPUser.LoginName)
                    $UserCollection.Add($UserFieldValue)
                }
                else
                {
                    #Is Group
                    $SpGroup = $web.SiteGroups.GetByName($role.Member.Name)
                    $UserFieldValue = new-object Microsoft.SharePoint.SPFieldUserValue($Web, $SPGroup.ID, $SPGroup.LoginName)
                    $UserCollection.Add($UserFieldValue)
                }
            }  
        }
    }  
    $Item["WhoHasAccess"] = $UserCollection
    $Item.Update()
}

I expect to get a few down-votes for posting such a n00b question, but any help provided would be valuable to me as I figure out SharePoint and C#!

To Summarise, I am looking for :

  • An Event Receiver that listens for Role Assignment changes at the item level
  • When the Event occurs, the Users and Groups are added to the field "WhoHasAccess"

or

  • A Custom Field that shows the current Item Permissions.
1
  • 2
    I don't think you can capture permission change event which will update users in column. However to achieve , you can think of timer job which will update column values periodically . Or you can run powershell through scheduler. Jul 30, 2018 at 12:58

1 Answer 1

1
+50

Here is a demo that use the C# code to get the users and groups for the item level permissions:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;

namespace SharePointConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {

            using (SPSite site = new SPSite("http://sp"))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    SPSecurity.RunWithElevatedPrivileges(delegate() { GetPermission(web); });
                    Console.WriteLine("Enter some value to exit");
                    Console.ReadLine();
                }
            }
        }

        private static void GetPermission(SPWeb web)
        {
            //Get roles assigned for the file
            SPList list = web.GetList("/Lists/list6");
            web.AllowUnsafeUpdates = true;
            SPFieldUserValueCollection userCollection = new SPFieldUserValueCollection();

            foreach (SPListItem item in list.Items)
            {
                foreach (SPRoleAssignment assignedRoles in item.RoleAssignments)
                {
                    if (assignedRoles.Member is SPGroup)
                    {
                        SPGroup group = (SPGroup)assignedRoles.Member;
                        SPFieldUserValue groupToAdd = new SPFieldUserValue(web, group.ID, group.LoginName);
                        userCollection.Add(groupToAdd);
                    }
                    else
                    {
                        SPUser user = (SPUser)assignedRoles.Member;
                        SPFieldUserValue userToAdd = new SPFieldUserValue(web, user.ID, user.LoginName);
                        userCollection.Add(userToAdd);
                    }
                }
                item["WhoHasAccess"] = userCollection;
                item.Update();
            }
        }
    }
}
2
  • Thanks for the reply, although this doesn't do what I am looking for . I couldn't actually get this to do anything unfortunately (although it did deploy).
    – user43832
    Jul 25, 2018 at 10:04
  • Awarded the bounty to you, as you were the only person who replied with an answer.
    – user43832
    Aug 6, 2018 at 13:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.