like it said in the title, I would like to add custom permissions on folders and subfolder in a document library on SharePoint online using PowerShell? I've tried this code but only works for the 1st level folder, not for subfolders.
Can anyone help me?
<#
The sample scripts are not supported under any Microsoft standard support
program or service. The sample scripts are provided AS IS without warranty
of any kind. Microsoft further disclaims all implied warranties including,
without limitation, any implied warranties of merchantability or of fitness for
a particular purpose. The entire risk arising out of the use or performance of
the sample scripts and documentation remains with you. In no event shall
Microsoft, its authors, or anyone else involved in the creation, production, or
delivery of the scripts be liable for any damages whatsoever (including,
without limitation, damages for loss of business profits, business interruption,
loss of business information or other pecuniary loss) arising out of the use
of or inability to use the sample scripts or documentation, even if Microsoft
has been advised of the possibility of such damages.
#>
#requries -Version 2.0
<#
.SYNOPSIS
This script will Set Folder Permission in a library of SharePoint Online.
.DESCRIPTION
This script could be used to set a folder which could be only accessed by a security group. And this folder must have the same name of the security group. Otherwise, the script will create a new folder
.PARAMETER userName
This parameter specified the username to login into SharePoint Online
.PARAMETER Password
This parameter specifies the password to login into SharePoint Online
.PARAMETER siteURL
This parameter specifies the URL of the SharePoint site
.PARAMETER ListName
This parameter specifies library/list name of the site
.PARAMETER FolderName
This parameter specifies the parenet folder name/url.
.PARAMETER PrincipalName
This parameter specifies the security group or user who will be assigned the permission
.PARAMETER RoleType
This parameter specifies the permission level to be assigned
.EXAMPLE
SPOSetFolderPermissioninLibrary.ps1 –userName [email protected] –siteURL https://tenant.sharepoint.com/sites/wroking -PrincipalName SecuirtyA -Roletype Editor
The folder SecurityA in library ‘Demofile’ of site https://tenant.sharepoint.com/sites/working can only be edited by security group “SecuirtyA”
#>
Param
(
[Parameter(Mandatory=$true)]
[string] $userName,
[Parameter(Mandatory=$True)]
[Security.SecureString]$Password,
[Parameter(Mandatory=$true)]
[string] $siteURL,
[Parameter(Mandatory=$true)]
[string] $ListName,
[Parameter(Mandatory=$false)]
[string] $FolderName,
[Parameter(Mandatory=$true)]
[string] $PrincipalName,
[Parameter(Mandatory=$true)][ValidateSet('None','Guest','Reader','Contributor','WebDesigner','Administrator','Editor')]
[string] $RoleType
)
Begin
{
$SPClientDirRegKey = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\SharePoint Client Components\15.0" -PSProperty "Location" -ErrorAction:SilentlyContinue
if ($SPClientDirRegKey -ne $null)
{
$moduleFilePath1 = $SPClientDirRegKey.'Location' + 'ISAPI\Microsoft.SharePoint.Client.dll'
$moduleFilePath2 = $SPClientDirRegKey.'Location' + 'ISAPI\Microsoft.SharePoint.Client.Runtime.dll'
Import-Module $moduleFilePath1
Import-Module $moduleFilePath2
}
else
{
$errorMsg = "Please install SharePoint Server 2013 Client Components SDK"
throw $errorMsg
Exit
}
$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($username, $Password)
$context = New-Object Microsoft.SharePoint.Client.ClientContext($siteURL)
$context.Credentials = $credentials
$web = $context.Web
$site = $context.Site
$context.Load($web)
$context.Load($site)
try
{
$context.ExecuteQuery()
}
Catch
{
Write-Error $Error[0]
Exit
}
Write-host "Conntect To Sharepoint Site $siteURL"
}
Process
{
$web = $context.web
$folderurl = $Web.ServerRelativeUrl + "/" + $ListName + "/" + $FolderName
$folder = $web.GetFolderByServerRelativeUrl($folderurl)
$context.Load($folder)
$folderExist = $false
try
{
$Context.ExecuteQuery();
if ($folder.Path)
{
$folderExist = $true;
}
}
catch { }
if(!$folderExist)
{
$parentFolderUrl = $folderUrl.Replace('/' + $folderName,'')
$newItemInfo = new-object Microsoft.SharePoint.Client.ListItemCreationInformation
$newItemInfo.UnderlyingObjectType = [Microsoft.SharePoint.Client.FileSystemObjectType]::Folder
$newItemInfo.LeafName = $folderName
$newItemInfo.FolderUrl = $parentFolderUrl
$listurl = $context.web.ServerRelativeUrl + "/" + "demofile"
write-host $listurl
$method = [Microsoft.SharePoint.Client.ClientContext].GetMethod("Load")
$loadMethod = $method.MakeGenericMethod([Microsoft.SharePoint.Client.List])
$parameter = [System.Linq.Expressions.Expression]::Parameter(([Microsoft.SharePoint.Client.List]), "list")
$expression = [System.Linq.Expressions.Expression]::Lambda([System.Linq.Expressions.Expression]::Convert(
[System.Linq.Expressions.Expression]::PropertyOrField(
[System.Linq.Expressions.Expression]::PropertyOrField($parameter, "RootFolder"),
"ServerRelativeUrl"
),
[System.Object]),
$($parameter)
)
$expressionArray = [System.Array]::CreateInstance($expression.GetType(), 1)
$expressionArray.SetValue($expression, 0)
$lists = $web.Lists
$Context.Load($lists)
$Context.ExecuteQuery()
$list = $null
foreach ($listfinder in $lists)
{
$loadMethod.Invoke($Context, @($listfinder, $expressionArray))
$Context.ExecuteQuery()
if ($listfinder.RootFolder.ServerRelativeUrl -eq $listUrl)
{
$list = $listfinder
}
}
$newListItem = $list.AddItem($newItemInfo)
$newListItem.Update()
$context.load($list)
$context.ExecuteQuery()
}
$roleTypeObject = [Microsoft.SharePoint.Client.RoleType]$roleType
$roledefs = $web.RoleDefinitions
$context.Load($roledefs)
$Context.ExecuteQuery()
$role = $roleDefs | where {$_.RoleTypeKind -eq $roleTypeObject}
$principal = $context.Web.EnsureUser($PrincipalName)
$Context.Load($principal)
Try
{
$Context.ExecuteQuery()
}
Catch
{
Write-Error $Error[0]
Exit
}
$list = $web.Lists.GetByTitle($listname)
$camlQuery = new-object Microsoft.SharePoint.Client.CamlQuery
$camlQuery.ViewXml = "<View><Query><Where><Eq><FieldRef Name='FileLeafRef' /><Value Type='Text'>$FolderName</Value></Eq></Where></Query></View>"
$listItems = $list.GetItems($camlQuery)
$Context.Load($listItems)
$Context.ExecuteQuery()
$listitem = $listItems[0]
$method = [Microsoft.Sharepoint.Client.ClientContext].GetMethod("Load")
$loadMethod = $method.MakeGenericMethod([Microsoft.Sharepoint.Client.ListItem])
$parameter = [System.Linq.Expressions.Expression]::Parameter(([Microsoft.SharePoint.Client.ListItem]), "x")
$expression = [System.Linq.Expressions.Expression]::Lambda([System.Linq.Expressions.Expression]::Convert(
[System.Linq.Expressions.Expression]::Property(
$parameter, ([Microsoft.SharePoint.Client.ListItem]).GetProperty("HasUniqueRoleAssignments")),
([System.Object])), $($parameter))
$expressionArray = [System.Array]::CreateInstance($expression.GetType(), 1)
$expressionArray.SetValue($expression, 0)
$loadMethod.Invoke( $Context, @( $listItem, $expressionArray ) )
$Context.ExecuteQuery()
if (-not $listItem.HasUniqueRoleAssignments)
{
$listItem.BreakRoleInheritance($false, $true)
}
$rdb = New-Object Microsoft.SharePoint.Client.RoleDefinitionBindingCollection($Context)
$rdb.Add($role)
$ra = $listItem.RoleAssignments.Add($principal, $rdb)
$Context.ExecuteQuery()
}
Mr @Rajiv
I have now this script, it works for users but i changed it for groups but i have an error, any help ?
Here is the error: Impossible d’appeler une méthode dans une expression Null. in line 86
### Get the user credentials
$credential = Get-Credential
$username = $credential.UserName
$password = $credential.GetNetworkCredential().Password
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
### Input Parameters
$url = 'https://xxx.sharepoint.com/sites/Demo-
test/Interne/'
$ListName = 'Infrastructure'
$GroupName = 'TestPemissions'
$RootFolder = 'TestPermissions'
### References
# Specified the paths where the dll's are located.
Add-Type -Path 'c:\Program Files\Common Files\microsoft shared\Web Server
Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll'
Add-Type -Path 'c:\Program Files\Common Files\microsoft shared\Web Server
Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll'
### AddPermission Function
function AddPermission()
{
# Connect to SharePoint Online and get ClientContext object.
$clientContext = New-Object Microsoft.SharePoint.Client.ClientContext($url)
$credentials = New-Object
Microsoft.SharePoint.Client.SharePointOnlineCredentials($username,
$securePassword)
$clientContext.Credentials = $credentials
# Get the SharePoint web
$web = $clientContext.Web
$clientcontext.Load($web)
$groups = $web.SiteGroups
$clientcontext.Load($groups)
$clientcontext.ExecuteQuery()
$folderurl = $web.ServerRelativeUrl + "/" + $ListName + "/" + $RootFolder
Write-Host "group : " $group
Write-Host "relative url : " $web.ServerRelativeUrl
Write-Host "folderurl : " $folderurl
$root = $web.GetFolderByServerRelativeUrl($folderurl)
$clientcontext.Load($root.Folders)
$clientcontext.ExecuteQuery()
Write-Host "folders : " $root
$group=$GroupName
Function GetRole
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true, Position = 1)]
[Microsoft.SharePoint.Client.RoleType]$rType
)
$web = $clientContext.Web
if ($web -ne $null)
{
$roleDefs = $web.RoleDefinitions
$clientContext.Load($roleDefs)
$clientContext.ExecuteQuery()
$roleDef = $roleDefs | Where-Object { $_.RoleTypeKind -eq $rType }
return $roleDef
}
return $null
}
foreach($folder in $root.Folders){
#Break inheritance and remove existing permissions
$folder.ListItemAllFields.BreakRoleInheritance($false, $true)
#Get the role required and load it
write-host "folder : " $folder
$roleType = Read-Host "None, Guest, Reader, Contributor, WebDesigner,
Administrator, Editor"
$roleTypeObject = [Microsoft.SharePoint.Client.RoleType]$roleType
$roleObj = GetRole $roleTypeObject
$gpRDBC = New-Object
Microsoft.SharePoint.Client.RoleDefinitionBindingCollection($clientContext)
$gpRDBC.Add($roleObj)
$gpRoleAssign = $folder.RoleAssignement
line 86 $RoleAssign = $gpRoleAssign.Add($group,$gpRDBC)
$clientcontext.ExecuteQuery()
Write-Host $gpRDBC.Description
# Display the folder name and URL
Write-Host -ForegroundColor Green 'Folder Name: ' $folder.Name
' URL: '$folder1.ServerRelativeUrl;
}
}
#Execute the function
AddPermission