Office 365 – Create Permissions Level and Groups using CSOM


I was recently helping a customer to deploy the OneNote Class Notebook App (which is really cool) to 200 of their SharePoint Online sites, the deployment part is super-easy however the assignment of permissions to users (teachers) to use the app isn't so straightforward when you have this number of sites as a new Permission Level and Group need to be created within each Site as documented here (which can be time consuming) presuming that you don't want to grant excessive permissions!

I created a script that automates the creation of the relevant Permission Level and Group, simply update the highlighted variables and execute, all you then need to do is add the teachers to the group – which can also be automated if required! For an added level of automation you could also wrap into a ForEach loop to iterate through all Sites.

If you'd like to use this in a different scenario, such as you need to create a new Permission Level and Group with slightly different permissions then all you need to do is update the highlighted $PermissionLevel variable, a reference for the valid values can be found here.

$Username = "admin@tenant.onmicrosoft.com"
$Site = "https://tenant.sharepoint.com/sites/sitetocreategroupwithin"
$Password = Read-Host -Prompt "Please enter your password" -AsSecureString
$PermName = "OneNote Class Notebook Authors"
$PermDescription = "OneNote Class Notebook Authors"

#Add references to SharePoint client assemblies and authenticate to Office 365 site
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"

$Context = New-Object Microsoft.SharePoint.Client.ClientContext($Site)
$Creds = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Username,$Password)
$Context.Credentials = $Creds

$Web = $Context.Web
$Context.Load($web)
$permissionlevel = "ManageLists, CancelCheckOut, AddListItems, EditListItems, DeleteListItems, ViewListItems, ApproveItems, OpenItems, ViewVersions, DeleteVersions, CreateAlerts, ViewFormPages, ManagePermissions, BrowseDirectories, ViewPages, EnumeratePermissions, BrowseUserInfo, UseRemoteAPIs, Open"
$RoleDefinitionCol = $web.RoleDefinitions
$Context.Load($roleDefinitionCol)
$Context.ExecuteQuery()
$permExists = $false
$spRoleDef = New-Object Microsoft.SharePoint.Client.RoleDefinitionCreationInformation
$spBasePerm = New-Object Microsoft.SharePoint.Client.BasePermissions
$permissions = $permissionlevel.split(",");
foreach($perm in $permissions){$spBasePerm.Set($perm)}

$spRoleDef.Name = $permName
$spRoleDef.Description = $permDescription
$spRoleDef.BasePermissions = $spBasePerm   
$roleDefinition = $web.RoleDefinitions.Add($spRoleDef)
$Context.ExecuteQuery()

#Retrieve Groups
$Groups = $Context.Web.SiteGroups
$Context.Load($Groups)
$Context.ExecuteQuery()

#Create Group
$NewGroup = New-Object Microsoft.SharePoint.Client.GroupCreationInformation
$NewGroup.Title = $PermName
$NewGroup.Description = $PermDescription
$OneNoteGroup = $Context.Web.SiteGroups.Add($NewGroup)

#Retrieve Permission Level
$PermissionLevel = $Context.Web.RoleDefinitions.GetByName($PermDescription)

#Bind Permission Level to Group
$RoleDefBind = New-Object Microsoft.SharePoint.Client.RoleDefinitionBindingCollection($Context)
$RoleDefBind.Add($PermissionLevel)
$Assignments = $Context.Web.RoleAssignments
$RoleAssignOneNote = $Assignments.Add($OneNoteGroup,$RoleDefBind)
$Context.Load($OneNoteGroup)
$Context.ExecuteQuery()

Brendan Griffin – @brendankarl

Comments (5)

  1. Duane says:

    Thanks for this Post Brendan. Is there a way to call such a script from a workflow?

    I need a workflow to add permissions groups based on a variable. The permissions groups need to have their permissions level set accordingly.

  2. WebGeorge0 says:

    This was a big help Brendan – thanks!

    Don’t suppose you have anything about how to now add members to the groups? Struggling to find it anywhere (other than how to do it at ONLY the Site Collection level)…

    Thanks again!

  3. WebGeorge0 says:

    Never mind – think I have it… here’s some stuff I added to my version of the script (slightly different use case)

    #Update Group
    $currentGroup = $Web.SiteGroups.GetByName($spoGName)
    $currentGroup.AllowMembersEditMembership = $false
    $currentGroup.OnlyAllowMembersViewMembership = $true

    $Member = $Context.Web.EnsureUser($userToAdd)
    $Context.Load($Member)

    # Add Member (can be user or Security Group)
    $addMember=$currentGroup.Users.AddUser($Member)
    $Context.Load($addMember)
    $Context.ExecuteQuery()

    Now I’m off to wrap it up a little better and use it with a CSV import 🙂

  4. Andrew says:

    Hi Brendan
    Great article. How do i check whether a new site permission already exists?

  5. Shivaprasad Rao says:

    Thanks a lot. This is how I modified the above code to Disable Sub site creation from SharePoint UI for Site Owners. This will remove the OOTB “FullControl” Permission from the group and add a newly created Permission level “LimitedFullControl”. This code works in SharePoint online for Inherited permissions and Unique permissions as well. (Note: I was not successful in finding what are the Roledinition in a roleassignment for a SharePoint group. I.e. to check whether SiteGroup already has fullcontrol hence with the help of try catch managing this part)

    try
    {
    #Get the current sites RoleDefinitions
    $roleDefinitions = $web.RoleDefinitions
    $ctx.Load($roleDefinitions)
    $ctx.ExecuteQuery()

    $custom = $roleDefinitions | Where-Object { $_.Name -eq “LimitedFullControl” }

    #Create “LimitedFullControl” without “Create Subsite” permissions
    if ($custom -eq $null)
    {
    $permissionlevel = “EmptyMask,ViewListItems,AddListItems,EditListItems,DeleteListItems,ApproveItems,OpenItems,ViewVersions,
    DeleteVersions,CancelCheckout,ManagePersonalViews,ManageLists,ViewFormPages,AnonymousSearchAccessList,Open,
    ViewPages,AddAndCustomizePages,ApplyThemeAndBorder,ApplyStyleSheets,ViewUsageData,CreateSSCSite,CreateGroups,
    ManagePermissions,BrowseDirectories,BrowseUserInfo,AddDelPrivateWebParts,UpdatePersonalWebParts,ManageWeb,AnonymousSearchAccessWebLists,
    UseClientIntegration,UseRemoteAPIs,ManageAlerts,CreateAlerts,EditMyUserInfo,EnumeratePermissions”
    $RoleDefinitionCol = $web.RoleDefinitions
    $ctx.Load($roleDefinitionCol)
    $ctx.ExecuteQuery()
    $permExists = $false
    $spRoleDef = New-Object Microsoft.SharePoint.Client.RoleDefinitionCreationInformation
    $spBasePerm = New-Object Microsoft.SharePoint.Client.BasePermissions
    $permissions = $permissionlevel.split(“,”);
    foreach($perm in $permissions){$spBasePerm.Set($perm)}

    $spRoleDef.Name = “LimitedFullControl”
    $spRoleDef.Description = “FullControl without Create Subsite permissions”
    $spRoleDef.BasePermissions = $spBasePerm
    $roleDefinition = $web.RoleDefinitions.Add($spRoleDef)
    $ctx.ExecuteQuery()
    }

    #Retrieve Permission Level
    $PermissionLevel = $ctx.Web.RoleDefinitions.GetByName(“LimitedFullControl”)

    $InheritedSite = $false
    try
    {
    #Add “LimitedFullControl” Permission Level to the Site Owners Group
    if($PermissionLevel -ne $null)
    {
    $OwnerGroup = $web.AssociatedOwnerGroup
    $LimitedFullControlRoleDefBind = New-Object Microsoft.SharePoint.Client.RoleDefinitionBindingCollection($ctx)
    $LimitedFullControlRoleDefBind.Add($PermissionLevel)
    $Assignments = $ctx.Web.RoleAssignments
    $RoleAssignment = $Assignments.Add($OwnerGroup,$LimitedFullControlRoleDefBind)
    $ctx.Load($RoleAssignment)
    $ctx.Load($OwnerGroup)
    $ctx.ExecuteQuery()
    Write-Host “LimitedFullControl Control – Role Definition Added Successfully”
    }
    }
    catch
    {
    if($_.Exception.Message -like ‘*This operation is not allowed on an object that inherits permissions.*’)
    {
    $InheritedSite = $true
    Write-Host “Inherited site already has LimitedFullControl permissions”
    }
    }

    try
    {
    if($InheritedSite -eq $false)
    {
    #Remove the “Full Control” Role Definition from Owners Group
    $newfullControlRoleDef = $web.RoleDefinitions|where{$_.Name -eq “Full Control”}
    if($newfullControlRoleDef -ne $null)
    {
    $ctx.Load($newfullControlRoleDef)
    $groupRoleAssignments = $web.RoleAssignments.GetByPrincipalId($OwnerGroup.Id)
    $ctx.Load($groupRoleAssignments)
    $groupRoleAssignments.RoleDefinitionBindings.Remove($newfullControlRoleDef);
    $ctx.Load($groupRoleAssignments)
    $groupRoleAssignments.Update();
    $ctx.ExecuteQuery()
    Write-Host “Full Control – Role Definition Removed Successfully”
    }
    }
    }
    catch
    {
    if($_.Exception.Message -like ‘*Can not find the principal with id*’)
    {
    Write-Host “The site owner group do not have Full Control permissions”
    }
    }
    }
    catch
    {
    Write-Host $_.Exception.Message
    }

Skip to main content