{"id":2137,"date":"2017-01-05T07:52:51","date_gmt":"2017-01-05T07:52:51","guid":{"rendered":"https:\/\/poiseddevelopers.com\/reality-tech\/?p=2137"},"modified":"2024-05-13T10:33:12","modified_gmt":"2024-05-13T10:33:12","slug":"sharepoint-group-management-2","status":"publish","type":"post","link":"https:\/\/poiseddevelopers.com\/reality-tech\/sharepoint-group-management-2\/","title":{"rendered":"SharePoint Group Management"},"content":{"rendered":"<h2>Managing SharePoint Groups in PowerShell<\/h2>\n<p>SharePoint Groups are a great mechanism for managing user permissions; however, they exist within a single site collection. What if you have hundreds of site collections? We can easily script a range of common operations.<\/p>\n<p>I prefer to use a CSV-fed approach to manage groups and users. I create a CSV with the name of the group and the users, which I list in pipe-separated format (commas are already being used for the CSV). To read in a CSV, use:<\/p>\n<pre lang=\"php\"> \r\nImport-Csv \"L:PowerShellAD and SP group mapping.csv\"\r\n<\/pre>\n<p>Let\u2019s get the Site, Root Web, as well as an SPUser for the group owner, and get the groups object:<\/p>\n<pre lang=\"php\"> \r\n$Site = New-Object Microsoft.SharePoint.SPSite($SiteName)\r\nwrite-host $site.Url\r\n$rootWeb = $site.RootWeb;\r\n$Owner = $rootWeb.EnsureUser($OwnerName)\r\n$Groups = $rootWeb.SiteGroups;\r\n<\/pre>\n<p>Here\u2019s how to add a Group:<\/p>\n<pre style=\"overflow-x: scroll; width: 60%;\" lang=\"php\"> \r\n$Groups.Add($SPGroupName, $Owner, $web.Site.Owner, \u201cSharePoint Group to hold AD group for Members\")\r\n<\/pre>\n<p>Here\u2019s how to give the group Read access, for example:<\/p>\n<pre style=\"overflow-x: scroll; width: 30%;\" lang=\"php\"> \r\n$GroupToAddRoleTo = $Groups[$SPGroupName]\r\nif ($GroupToAddRoleTo) #if group exists\r\n{\r\n   $MyAcctassignment = New-Object Microsoft.SharePoint.SPRoleAssignment($GroupToAddRoleTo)\r\n   $MyAcctrole = $RootWeb.RoleDefinitions[\"Read\"]\r\n   $MyAcctassignment.RoleDefinitionBindings.Add($MyAcctrole)\r\n   $RootWeb.RoleAssignments.Add($MyAcctassignment)\r\n}\r\n<\/pre>\n<p>Here\u2019s how to add a Member to a Group:<\/p>\n<pre lang=\"php\">$UserObj = $rootWeb.EnsureUser($userName);\r\nif ($UserObj) #if it exists\r\n{\r\n   $GroupToAddTo.addUser($UserObj)  \r\n}\r\n<\/pre>\n<p>Note that a duplicate addition of a member is a null-op, throwing no errors.<\/p>\n<p>Here\u2019s how to remove a member:<\/p>\n<pre lang=\"php\"> \r\n$UserObj = $rootWeb.EnsureUser($userName);\r\nif ($UserObj)\r\n{\r\n   $GroupToAddTo.RemoveUser($UserObj)  \r\n}\r\n<\/pre>\n<p>Here\u2019s how to remove all the members from a given group. This wipes the users from the whole site collection, so use this approach with care and consideration:<\/p>\n<pre lang=\"php\">$user1 = $RootWeb.EnsureUser($MyUser)\r\ntry\r\n{\r\n   $RootWeb.SiteUsers.Remove($MyUser)\r\n   $RootWeb.update()\r\n}\r\n<\/pre>\n<p>Here\u2019s the full script, with flags to setting the specific actions described above:<\/p>\n<pre style=\"overflow-x: scroll; width: 70%;\" lang=\"php\">Add-PSSnapin \"Microsoft.SharePoint.PowerShell\" -ErrorAction SilentlyContinue\r\n# uses feedfile to load and create set of SharePoint Groups.\r\n$mylogfile=\"L:PowerShellongoinglogfile.txt\"\r\n$ADMap= Import-Csv \"L:PowerShellAD and SP group mapping.csv\"\r\n$OwnerName = \"DOMAIN\\sp2013farm\"\r\n$AddGroups = $false;\r\n$AddMembers = $false;  # optionally populates those groups, Comma separated list\r\n$GrantGroupsRead = $true; #grants read at top rootweb level\r\n$RemoveMembers = $false; # optionally  removes Comma separated list of users from the associated group\r\n$WipeMembers = $false;  # wipes the groups clean        \r\n$WipeUsersOutOfSite = $false;  #The Nuclear option. Useful to eliminate AD groups used directly as groups\r\n \r\n \r\n #we do not need a hashtable for this work, but let's load it for extensibility\r\n$MyMap=@{}  #load CSV contents into HashTable\r\nfor ($i=0; $i -lt $AD.Count; $i++)\r\n{\r\n    $MyMap[$ADMap[$i].SharePointGroup] = $ADMap[$i].ADGroup;\r\n}\r\n \r\n# Script changes the letter heading for each site collection\r\n$envrun=\"Dev\"           # selects environment to run in\r\n \r\nif ($envrun -eq \"Dev\")\r\n{\r\n$siteUrl = \"h ttp:\/\/DevServer\/sites\/\"\r\n$mylogfile=\"L:PowerShellongoinglogfile.txt\"\r\n$LoopString = \"A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z\"\r\n$LoopStringArr = $LoopString.Split(\u201c,\u201d)\r\n \r\n}\r\nelseif ($envrun -eq \"Prod\")\r\n{\r\n$siteUrl = \"ht tp:\/\/SharePoint\/sites\/\"\r\n$mylogfile=\"L:PowerShellongoinglogfile.txt\"\r\n$LoopString = \"A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z\"\r\n$LoopStringArr = $LoopString.Split(\u201c,\u201d)\r\n}\r\nelse\r\n{\r\nWrite-Host \"ENVIRONMENT SETTING NOT VALID: script terminating...\"\r\n$siteUrl =  $null;\r\nreturn;\r\n}\r\n \r\nWrite-Host \"script starting\"\r\n \r\n$myheader = \"STARTING: $(get-date)\"\r\n \r\nforeach ($letter in $LoopStringArr)\r\n{\r\n    $SiteName=$siteurl+$letter\r\n    $Site = New-Object Microsoft.SharePoint.SPSite($SiteName)\r\n \r\n    write-host $site.Url\r\n    $rootWeb = $site.RootWeb;\r\n    $Owner = $rootWeb.EnsureUser($OwnerName)\r\n    $Groups = $rootWeb.SiteGroups;\r\n \r\n    for ($ADi = 0; $ADi -lt $ADMap.count; $ADi++)\r\n    {\r\n        $SPGroupName = $ADMap[$ADi].SharePoint Group;\r\n         \r\n        if ($AddGroups)\r\n        {\r\n            if (!$Groups[$SPGroupName]) #no exist, so create\r\n            {\r\n                try\r\n                {\r\n                    $Groups.Add($SPGroupName, $Owner, $web.Site.Owner, \u201cSharePoint Group to hold AD group members\")\r\n                }\r\n                catch\r\n                {\r\n                    Write-Host -ForegroundColor DarkRed \"Ouch, could not create $($SPgroupName)\"\r\n                }\r\n            }\r\n            else\r\n            {\r\n                    Write-Host -ForegroundColor DarkGreen \"Already exists: $($SPgroupName)\"\r\n            }\r\n        } #endif Add Groups\r\n     \r\n            if ($GrantGroupsRead)\r\n        {\r\n            $GroupToAddRoleTo = $Groups[$SPGroupName]\r\n            if ($GroupToAddRoleTo) #if group exists\r\n            {\r\n                 \r\n                $MyAcctassignment = New-Object Microsoft.SharePoint.SPRoleAssignment($GroupToAddRoleTo)\r\n                $MyAcctrole = $RootWeb.RoleDefinitions[\"Read\"]\r\n                $MyAcctassignment.RoleDefinitionBindings.Add($MyAcctrole)\r\n                $RootWeb.RoleAssignments.Add($MyAcctassignment)\r\n            } #if the group exists in the first place\r\n        } #ActionFlagTrue\r\n     \r\n        if ($AddMembers)\r\n        {\r\n            $GroupToAddTo = $Groups[$SPGroupName]\r\n            if ($GroupToAddTo) #if group exists\r\n            {\r\n                $usersToAdd = $ADMap[$ADi].ADGroup;\r\n                 \r\n                if ($usersToAdd.length -gt 0) #if no users to add, skip\r\n                {\r\n                    $usersToAddArr = $usersToAdd.split(\"|\")\r\n                    foreach ($userName in $usersToAddArr)\r\n                    {\r\n                        try\r\n                        {\r\n                            $UserObj = $rootWeb.EnsureUser($userName);\r\n                            if ($UserObj)\r\n                            {\r\n                                $GroupToAddTo.addUser($UserObj)  #dup adds are a null-op, throwing no errors\r\n                            }\r\n                        }\r\n                        catch\r\n                        {\r\n                        Write-Host -ForegroundColor DarkRed \"cannot add user ($($userName) to $($GroupToAddTo)\"\r\n                        }\r\n \r\n                    }\r\n                } #users to add\r\n            } #if the group exists in the first place\r\n        } #ActionFlagTrue\r\n         \r\n        if ($RemoveMembers)\r\n        {\r\n            $GroupToAddTo = $Groups[$SPGroupName]\r\n            if ($GroupToAddTo) #if group exists\r\n            {\r\n                $usersToAdd = $ADMap[$ADi].SharePoint Group;\r\n                 \r\n                if ($usersToAdd.length -gt 0) #if no users to add, skip\r\n                {\r\n                    $usersToAddArr = $usersToAdd.split(\"|\")\r\n                    foreach ($userName in $usersToAddArr)\r\n                    {\r\n                        try\r\n                        {\r\n                            $UserObj = $rootWeb.EnsureUser($userName);\r\n                            if ($UserObj)\r\n                            {\r\n                                $GroupToAddTo.RemoveUser($UserObj)  #dup adds are a null-op, throwing no errors\r\n                            }\r\n                        }\r\n                        catch\r\n                        {\r\n                        Write-Host -ForegroundColor DarkRed \"cannot add user ($($userName) to $($GroupToAddTo)\"\r\n                        }\r\n \r\n                    }\r\n                } #users to add\r\n            } #if the group exists in the first place\r\n        } #ActionFlagTrue\r\n         \r\n        if ($WipeMembers)  #Nukes all users in the group\r\n        {\r\n            $GroupToAddTo = $Groups[$SPGroupName]\r\n            if ($GroupToAddTo) #if group exists\r\n            {\r\n                    foreach ($userName in $GroupToAddTo.Users)\r\n                    {\r\n                        try\r\n                        {\r\n                            $UserObj = $rootWeb.EnsureUser($userName);\r\n                            if ($UserObj)\r\n                            {\r\n                                $GroupToAddTo.RemoveUser($UserObj)  #dup adds are a null-op, throwing no errors\r\n                            }\r\n                        }\r\n                        catch\r\n                        {\r\n                        Write-Host -ForegroundColor DarkRed \"cannot remove user ($($userName) to $($GroupToAddTo)\"\r\n                        }\r\n \r\n                    }\r\n                 \r\n            } #if the group exists in the first place\r\n        } #ActionFlagTrue\r\n \r\nif ($WipeUsersOutOfSite)  #Nukes all users in the group\r\n        {\r\n        $usersToNuke = $ADMap[$ADi].ADGroup;\r\n         \r\n        if ($usersToNuke.length -gt 0) #if no users to add, skip\r\n                {\r\n                    $usersToNukeArr = $usersToNuke.split(\"|\")\r\n                    foreach ($MyUser in $usersToNukeArr)\r\n                    {\r\n                        try\r\n                            {\r\n                                try\r\n                                {\r\n                                    $user1 = $RootWeb.EnsureUser($MyUser)\r\n                                }\r\n                                catch\r\n                                {\r\n                                    Write-Host \"x1: Failed to ensure user $($MyUser) in $($Site.url)\"\r\n                                }\r\n                                 \r\n                                try\r\n                                {\r\n                                    $RootWeb.SiteUsers.Remove($MyUser)\r\n                                    $RootWeb.update()\r\n                                }\r\n                                catch\r\n                                {\r\n                                    Write-Host \"x2: Failed to remove $($MyUser) from all users in $($Site.url)\"\r\n                                }\r\n                           }\r\n                           catch\r\n                           {\r\n                                Write-Host \"x4: other failure for $($MyUser) in $($Site.url)\"\r\n                           }\r\n                } #if user is not null\r\n            } #foreach user to nuke\r\n        } #ActionFlagTrue\r\n         \r\n    }\r\n     \r\n     \r\n    $rootWeb.dispose()\r\n    $site.dispose()\r\n     \r\n} #foreach site\r\n\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Managing SharePoint Groups in PowerShell SharePoint Groups are a great mechanism for managing user permissions; however, they exist within a single site collection. What if you have hundreds of site collections? We can easily script a range of common operations. I prefer to use a CSV-fed approach to manage groups and users. I create a [&hellip;]<\/p>\n","protected":false},"author":8,"featured_media":2138,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[26],"tags":[],"class_list":["post-2137","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-powershell"],"acf":[],"_links":{"self":[{"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/posts\/2137","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/users\/8"}],"replies":[{"embeddable":true,"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/comments?post=2137"}],"version-history":[{"count":5,"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/posts\/2137\/revisions"}],"predecessor-version":[{"id":3941,"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/posts\/2137\/revisions\/3941"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/media\/2138"}],"wp:attachment":[{"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/media?parent=2137"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/categories?post=2137"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/tags?post=2137"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}