I have written this script based on some feedback I received in this article, which has become one of the more popular posts on the site. I was asked if there was any way of assigning group permissions for all sites in a site collection, bearing in mind that some sites will have unique permissions set on them whereas others will inherit their permissions from a parent site.
The function below provides this functionality, as well as a few other features:
- Skips sites where permissions are being inherited from a parent site
- Adds not only SharePoint groups to sites, but also Active Directory users and groups
- Provides the option to skip the root site of the site collection, should you only wish to set permissions on all sub-sites
- Will add a new SharePoint group to the site collection, if it doesn’t exist already. The script will allow you to add a description for the group, and it will automatically assign the user running the script as group owner and member
Before you can start assigning permissions to sites using the script, you have to run the function first in a PowerShell console with the SharePoint cmdlets loaded (e.g., the SharePoint 2010 Management Shell). I have annotated portions of the script so that you can hopefully follow what it is doing:
function AddAccountToAllSites ($siteURL, $accountName, $permLevel, [switch]$skipRootSite, $newGroupDescription)
{
#Get Site Collection
$site = Get-SPSite $siteURL
#Check if the accountName variable contains a slash - if so, it is an AD account
#If not, it is a SharePoint Group
$rootWeb = $site.RootWeb
if ($accountName.Contains("\")) { $account = $rootWeb.EnsureUser($accountName) }
else {
#If the SharePoint Group does not exist, create it with the name and description specified
if (!$rootWeb.SiteGroups[$accountName])
{
$rootWeb.SiteGroups.Add($accountName, $rootWeb.CurrentUser, $rootWeb.CurrentUser, $newGroupDescription)
}
$account = $rootWeb.SiteGroups[$accountName]
}
$rootWeb.Dispose()
#Step through each site in the site collection
$site | Get-SPWeb -limit all | ForEach-Object {
#Check if the user has chosen to skip the root site - if so, do not change permissions on it
if (($skipRootSite) -and ($site.Url -eq $_.Url)) { write-host "Root site" $_.Url "will be bypassed" }
else {
#Check if the current site is inheriting permissions from its parent
#If not, set permissions on current site
if ($_.HasUniqueRoleAssignments) {$assignment = New-Object Microsoft.SharePoint.SPRoleAssignment($account)
$role = $_.RoleDefinitions[$permLevel]
$assignment.RoleDefinitionBindings.Add($role)
$_.RoleAssignments.Add($assignment)
write-host "Account" $accountName "added to site" $_.Url "with" $permLevel "permissions."
}
else {
write-host "Site" $_.Url "will not be modified as it inherits permissions from a parent site."
}
}
}
#Display completion message and dispose of site object
write-host "Operation Complete."
$site.Dispose()
}
Once the script has been run, you can use it to assign permissions to your site collection by calling the function. Here are some scenarios:
- Add the Active Directory user PACDOMAIN\Phil to all sites except the root site and assign Read permissions to them:
AddAccountToAllSites -siteURL "http://portal" -accountName "PACDOMAIN\Phil" -permLevel "Read" -skipRootSite
- Add the Active Directory user PACDOMAIN\Phil to all sites including the root site and assign Read permissions to them:
AddAccountToAllSites -siteURL "http://portal" -accountName "PACDOMAIN\Phil" -permLevel "Read"
- Add the Active Directory group PACDOMAIN\Portal Users to all sites including the root site and assign Read permissions to it:
AddAccountToAllSites -siteURL "http://portal" -accountName "PACDOMAIN\Portal Users" -permLevel "Read"
- Add the SharePoint group “Test Group” to all sites except the root site and assign Full Control permissions to it. I am also assuming that this group has already been created in the site collection:
AddAccountToAllSites -siteURL "http://portal" -accountName "Test Group" -permLevel "Full Control" -skipRootSite
- Add the SharePoint group “Test New Group” to all sites except the root site and assign Contribute permissions to it. This time I would like to create the group in the site collection as it doesn’t currently exist, and so I am also specifying the group description to be used during creation:
AddAccountToAllSites -siteURL "http://portal" -accountName "Test New Group" -permLevel "Contribute" -skipRootSite -newGroupDescription "This is a test group"
The screenshot below shows the affect of running these commands on one of the sites configured with unique permissions. All sites inheriting permissions will not be changed, although they will inherit these changes if their parent site has been affected by them.
I have posted a follow up article demonstrating how users and group assignments can be removed from sites in a similar way.
Will this script also work in Sharepoint MOSS 2007?
ReplyDeleteYes, with a few tweaks:
ReplyDeletehttp://get-spscripts.com/2011/03/using-powershell-scripts-with-wss-30.html
This is a potentially awesome solution to what I'm trying to accomplish, but it simply stops without executing anything for me. Just blanks.
ReplyDeleteI'm trying to tweak this code a bit and hopefully I can get it to work.
Scratch that. I see what I was doing wrong. I actually ended up adding this function to another script and running it from the new script. Thanks!
ReplyDeleteHi Phil
ReplyDeleteGreat post!
I need to update the permissions for a particular site and subsites with in a site collection. i.e. we have 1 site collection which contains all of our departments, i only need to update the permissions for 1 department. Is this possible with this script?
Many thanks!
Tomas
Tomas - You can use elements of this script to do it just not the script as it is written here. You may also want to look at this one for inspiration: http://get-spscripts.com/2010/07/adding-groups-with-permission-levels-to.html
ReplyDeleteI've improved upon the script a bit, just a few minor changes. If you're interested, email me - "john at dumb dot org" or email my gmail id in my comments.
ReplyDeleteWonderful blog! I found it while searching on Yahoo News. Do you have any tips on how to get listed in Yahoo News? I’ve been trying for a while but I never seem to get there! Many thanks.sbo
ReplyDeleteHello Phil,
ReplyDeleteVery useful script. Is there a way to use it to add a user when using claims-based authentication? If I just add the user name they show up in the site's permissions list, but don't actually have any permissions. When added through the GUI the username is prefaced with 'i:0#.w'.
OK solved it - needed to put a pipe so "i:0#.w|domain\user"
DeleteHi Phil,
ReplyDeleteJust an off the topic question taht I'm looking for an answer... I'm writing a program to grant user permission to a folder. this is for Sharepoint 2007 and I'm using c# managed code. (not powershell) However I am unable to add user permissions to a folder in a document library unless the user is added to the site permissions. Am I missing something here? or is this a known issue in MOSS and if so is there a workaround available?