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