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). Jul 25, 2018 at 10:04
  • Awarded the bounty to you, as you were the only person who replied with an answer. Aug 6, 2018 at 13:32

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.