Friday, March 2, 2018

How to implement "GetItemsWithUniquePermissions" through PowerShell and CSOM

In C# or JavaScript, it's easy. As this link shows, we can do it through the script below:

var items = list.GetItems(CamlQuery.CreateAllItemsQuery());
ctx.Load(items, col => col.Include(i => i.HasUniqueRoleAssignments));
ctx.ExecuteQuery();
int itemCount = items.Where(i => i.HasUniqueRoleAssignments).Count;


However, can we do similar thing in PowerShell by ONE "ctx.ExecuteQuery()" submit?

The answer is YES.

Below is the script.

$query = [Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery()
$items = $list.GetItems($query)

$items | %{
$_.Retrieve("HasUniqueRoleAssignments")
$ctx.Load($_)
$ctx.Load($_.RoleAssignments)
}
$ctx.ExecuteQuery()

foreach($item in $items){
if ($item.HasUniqueRoleAssignments){
# your code here
}
}


If there are too many items in the list, we may see the error message:

"The request message is too big. The server does not allow messages larger than 2097152 bytes"

Based on my test, 1000 items is fine. In that case, we need to do it in batches. Below is the script.

$Global:_BatchRowLimit = 1000
$caml = ""
$viewFields = ""
$position = $null
$allItems = @()

Do{
$camlQuery = New-Object Microsoft.SharePoint.Client.CamlQuery
$camlQuery.ViewXml = "$caml$viewFields$Global:_BatchRowLimit"
$camlQuery.ListItemCollectionPosition = $position

$listItems = $list.getItems($camlQuery)
$ctx.Load($listItems)
$ctx.ExecuteQuery()

$listItems | %{
$_.Retrieve("HasUniqueRoleAssignments")
$ctx.Load($_)
}
$ctx.ExecuteQuery()

$position = $listItems.ListItemCollectionPosition
$allItems += $listItems
}
Until($position -eq $null) 

No comments:

Post a Comment