Ejemplo n.º 1
0
        protected override void ExecuteCmdlet()
        {
            DefaultRetrievalExpressions = new Expression <Func <User, object> >[]
            {
                u => u.Id,
                u => u.Title,
                u => u.LoginName,
                u => u.Email,
                u => u.IsShareByEmailGuestUser,
                u => u.IsSiteAdmin,
                u => u.UserId,
                u => u.IsHiddenInUI,
                u => u.PrincipalType,
                u => u.Alerts.Include(
                    a => a.Title,
                    a => a.Status),
                u => u.Groups.Include(
                    g => g.Id,
                    g => g.Title,
                    g => g.LoginName)
            };

            if (Identity == null)
            {
                CurrentWeb.Context.Load(CurrentWeb.SiteUsers, u => u.Include(RetrievalExpressions));

                List <DetailedUser> users = new List <DetailedUser>();

                if (WithRightsAssigned ||
                    WithRightsAssignedDetailed
                    )
                {
                    // Get all the role assignments and role definition bindings to be able to see which users have been given rights directly on the site level
                    CurrentWeb.Context.Load(CurrentWeb.RoleAssignments, ac => ac.Include(a => a.RoleDefinitionBindings, a => a.Member));
                    var usersWithDirectPermissions = CurrentWeb.SiteUsers.Where(u => CurrentWeb.RoleAssignments.Any(ra => ra.Member.LoginName == u.LoginName));

                    // Get all the users contained in SharePoint Groups
                    CurrentWeb.Context.Load(CurrentWeb.SiteGroups, sg => sg.Include(u => u.Users.Include(RetrievalExpressions), u => u.LoginName));
                    CurrentWeb.Context.ExecuteQueryRetry();

                    // Get all SharePoint groups that have been assigned access
                    var usersWithGroupPermissions = new List <User>();
                    foreach (var group in CurrentWeb.SiteGroups.Where(g => CurrentWeb.RoleAssignments.Any(ra => ra.Member.LoginName == g.LoginName)))
                    {
                        usersWithGroupPermissions.AddRange(group.Users);
                    }

                    // Merge the users with rights directly on the site level and those assigned rights through SharePoint Groups
                    var allUsersWithPermissions = new List <User>(usersWithDirectPermissions.Count() + usersWithGroupPermissions.Count());
                    allUsersWithPermissions.AddRange(usersWithDirectPermissions);
                    allUsersWithPermissions.AddRange(usersWithGroupPermissions);

                    // Add the found users and add them to the custom object
                    if (WithRightsAssignedDetailed)
                    {
                        CurrentWeb.Context.Load(CurrentWeb, s => s.ServerRelativeUrl);
                        CurrentWeb.Context.ExecuteQueryRetry();

                        WriteWarning("Using the -WithRightsAssignedDetailed parameter will cause the script to take longer than normal because of the all enumerations that take place");
                        users.AddRange(GetPermissions(CurrentWeb.RoleAssignments, CurrentWeb.ServerRelativeUrl));
                        foreach (var user in allUsersWithPermissions)
                        {
                            users.Add(new DetailedUser()
                            {
                                Groups = user.Groups,
                                User   = user,
                                Url    = CurrentWeb.ServerRelativeUrl
                            });
                        }
                    }
                    else
                    {
                        // Filter out the users that have been given rights at both places so they will only be returned once
                        WriteObject(allUsersWithPermissions.GroupBy(u => u.Id).Select(u => u.First()), true);
                    }
                }
                else
                {
                    CurrentWeb.Context.ExecuteQueryRetry();
                    WriteObject(CurrentWeb.SiteUsers, true);
                }

                if (WithRightsAssignedDetailed)
                {
                    CurrentWeb.Context.Load(CurrentWeb.Lists, l => l.Include(li => li.ItemCount, li => li.IsSystemList, li => li.IsCatalog, li => li.RootFolder.ServerRelativeUrl, li => li.RoleAssignments, li => li.Title, li => li.HasUniqueRoleAssignments));
                    CurrentWeb.Context.ExecuteQueryRetry();

                    var progress        = new ProgressRecord(0, $"Getting lists for {CurrentWeb.ServerRelativeUrl}", "Enumerating through lists");
                    var progressCounter = 0;

                    foreach (var list in CurrentWeb.Lists)
                    {
                        WriteProgress(progress, $"Getting list {list.RootFolder.ServerRelativeUrl}", progressCounter++, CurrentWeb.Lists.Count);

                        // ignoring the system lists
                        if (list.IsSystemList || list.IsCatalog)
                        {
                            continue;
                        }

                        // if a list or a library has unique permissions then proceed
                        if (list.HasUniqueRoleAssignments)
                        {
                            WriteVerbose(string.Format("List found with HasUniqueRoleAssignments {0}", list.RootFolder.ServerRelativeUrl));
                            string url = list.RootFolder.ServerRelativeUrl;

                            CurrentWeb.Context.Load(list.RoleAssignments, r => r.Include(
                                                        ra => ra.RoleDefinitionBindings,
                                                        ra => ra.Member.LoginName,
                                                        ra => ra.Member.Title,
                                                        ra => ra.Member.PrincipalType));
                            CurrentWeb.Context.ExecuteQueryRetry();

                            users.AddRange(GetPermissions(list.RoleAssignments, url));

                            // if the list with unique permissions also has items, check every item which is uniquely permissioned
                            if (list.ItemCount > 0)
                            {
                                WriteVerbose(string.Format("Enumerating through all listitems of {0}", list.RootFolder.ServerRelativeUrl));

                                CamlQuery query        = CamlQuery.CreateAllItemsQuery();
                                var       queryElement = XElement.Parse(query.ViewXml);

                                var rowLimit = queryElement.Descendants("RowLimit").FirstOrDefault();
                                if (rowLimit != null)
                                {
                                    rowLimit.RemoveAll();
                                }
                                else
                                {
                                    rowLimit = new XElement("RowLimit");
                                    queryElement.Add(rowLimit);
                                }

                                rowLimit.SetAttributeValue("Paged", "TRUE");
                                rowLimit.SetValue(1000);

                                query.ViewXml = queryElement.ToString();

                                List <ListItemCollection> items = new List <ListItemCollection>();

                                do
                                {
                                    var listItems = list.GetItems(query);
                                    CurrentWeb.Context.Load(listItems);
                                    CurrentWeb.Context.ExecuteQueryRetry();
                                    query.ListItemCollectionPosition = listItems.ListItemCollectionPosition;

                                    items.Add(listItems);
                                } while (query.ListItemCollectionPosition != null);

                                // Progress bar for item enumerations
                                var itemProgress        = new ProgressRecord(0, $"Getting items for {list.RootFolder.ServerRelativeUrl}", "Enumerating through items");
                                var itemProgressCounter = 0;

                                foreach (var item in items)
                                {
                                    WriteProgress(itemProgress, $"Retrieving items", itemProgressCounter++, items.Count);

                                    WriteVerbose(string.Format("Enumerating though listitemcollections"));
                                    foreach (var listItem in item)
                                    {
                                        WriteVerbose(string.Format("Enumerating though listitems"));
                                        listItem.EnsureProperty(i => i.HasUniqueRoleAssignments);

                                        if (listItem.HasUniqueRoleAssignments)
                                        {
                                            string listItemUrl = listItem["FileRef"].ToString();
                                            WriteVerbose(string.Format("List item {0} HasUniqueRoleAssignments", listItemUrl));

                                            CurrentWeb.Context.Load(listItem.RoleAssignments, r => r.Include(
                                                                        ra => ra.RoleDefinitionBindings,
                                                                        ra => ra.Member.LoginName,
                                                                        ra => ra.Member.Title,
                                                                        ra => ra.Member.PrincipalType));
                                            CurrentWeb.Context.ExecuteQueryRetry();

                                            users.AddRange(GetPermissions(listItem.RoleAssignments, listItemUrl));
                                        }
                                    }
                                }
                                itemProgress.RecordType = ProgressRecordType.Completed;
                                WriteProgress(itemProgress);
                            }
                        }
                        progress.RecordType = ProgressRecordType.Completed;
                        WriteProgress(progress);
                    }

                    // Fetch all the unique users from everything that has been collected
                    var uniqueUsers = (from u in users
                                       select u.User.LoginName).Distinct();

                    // Looping through each user, getting all the details like specific permissions and groups an user belongs to
                    foreach (var uniqueUser in uniqueUsers)
                    {
                        // Getting all the assigned permissions per user
                        var userPermissions = (from u in users
                                               where u.User.LoginName == uniqueUser && u.Permissions != null
                                               select u).ToList();

                        // Making the permissions readable by getting the name of the permission and the URL of the artifact
                        Dictionary <string, string> Permissions = new Dictionary <string, string>();
                        foreach (var userPermission in userPermissions)
                        {
                            StringBuilder stringBuilder = new StringBuilder();
                            foreach (var permissionMask in userPermission.Permissions)
                            {
                                stringBuilder.Append(permissionMask);
                            }
                            Permissions.Add(userPermission.Url, stringBuilder.ToString());
                        }

                        // Getting all the groups where the user is added to
                        var groupsMemberships = (from u in users
                                                 where u.User.LoginName == uniqueUser && u.Groups != null
                                                 select u.Groups).ToList();

                        // Getting the titles of the all the groups
                        List <string> Groups = new List <string>();
                        foreach (var groupMembership in groupsMemberships)
                        {
                            foreach (var group in groupMembership)
                            {
                                Groups.Add(group.Title);
                            }
                        }

                        // Getting the User object of the user so we can get to the title, loginname, etc
                        var userInformation = (from u in users
                                               where u.User.LoginName == uniqueUser
                                               select u.User).FirstOrDefault();

                        WriteObject(new { userInformation.Title, userInformation.LoginName, userInformation.Email, Groups, Permissions }, true);
                    }
                }
            }
            else
            {
                User user = null;
                if (Identity.Id > 0)
                {
                    user = CurrentWeb.GetUserById(Identity.Id);
                }
                else if (Identity.User != null && Identity.User.Id > 0)
                {
                    user = CurrentWeb.GetUserById(Identity.User.Id);
                }
                else if (!string.IsNullOrWhiteSpace(Identity.Login))
                {
                    user = CurrentWeb.SiteUsers.GetByLoginName(Identity.Login);
                }
                if (user != null)
                {
                    CurrentWeb.Context.Load(user, RetrievalExpressions);
                    CurrentWeb.Context.ExecuteQueryRetry();
                }
                WriteObject(user);
            }
        }