7

I am trying to retrieve HasUniqueRoleAssignements property for multiple SharePoint Online lists using Powershell.

I can do it for each one in SharePoint on-premises:

$ctx.Load($list.HasUniqueRoleAssignments)

but the same cmdlet applied for SPO tenant returns an error:

Cannot find an overload for "Load" and the argument count: "1".
At C:\Users\Me\Documents\Customer.ps1:34 char:3
+ $ctx.Load($ll.HasUniqueRoleAssignments) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodCountCouldNotFindBest

If I don't load the property, it will not be displayed as it needs to be separately requested.
I can access Fields of a list, but fields are columns and not properties.

The property can be loaded and accessed without issue using C#:

ctx.Load(ctx.Web.Lists, wc => wc.Include(w => w.HasUniqueRoleAssignments));

I also tried $list.Retrieve() which should retrieve the properties and IntelliSense but it didn't recognize the HasUniqueRoleAssignments (mind you, it doesn't even suggest .Title)

That begs the questions:

  1. Is it possible that using CSOM I would be able to access one property with C# and not with Powershell? Where can I find a list of PS accessible properties?

  2. Can I use Expression like in C# example to load the properties for all the lists or do I need to do that one by one?

Amal Hashim
  • 28,306
  • 5
  • 31
  • 61
grisha
  • 2,445
  • 3
  • 27
  • 40

4 Answers4

16

The ClientRuntimeContext.Load method has the following signature:

public void Load<T>(
    T clientObject,
    params Expression<Func<T, Object>>[] retrievals
)
where T : ClientObject

How to invoke ClientRuntimeContext.Load<T> method in PowerShell

Invoke-LoadMethod function demonstrates how to specify retrievals parameter for ClientRuntimeContext.Load<T> method in PowerShell:

Function Invoke-LoadMethod() {
param(
   [Microsoft.SharePoint.Client.ClientObject]$Object = $(throw "Please provide a Client Object"),
   [string]$PropertyName
) 
   $ctx = $Object.Context
   $load = [Microsoft.SharePoint.Client.ClientContext].GetMethod("Load") 
   $type = $Object.GetType()
   $clientLoad = $load.MakeGenericMethod($type) 


   $Parameter = [System.Linq.Expressions.Expression]::Parameter(($type), $type.Name)
   $Expression = [System.Linq.Expressions.Expression]::Lambda(
            [System.Linq.Expressions.Expression]::Convert(
                [System.Linq.Expressions.Expression]::PropertyOrField($Parameter,$PropertyName),
                [System.Object]
            ),
            $($Parameter)
   )
   $ExpressionArray = [System.Array]::CreateInstance($Expression.GetType(), 1)
   $ExpressionArray.SetValue($Expression, 0)
   $clientLoad.Invoke($ctx,@($Object,$ExpressionArray))
}

Example

The following example demonstrates how to retrieve HasUniqueRoleAssignments property of List object:

$context = New-Object Microsoft.SharePoint.Client.ClientContext($Url)
$context.Credentials = Get-SPOCredentials -UserName $UserName -Password $Password

$list = $context.Web.Lists.GetByTitle($listTitle)    
Invoke-LoadMethod -Object $list -PropertyName "HasUniqueRoleAssignments"
$context.ExecuteQuery()

Write-Host $list.HasUniqueRoleAssignments

$context.Dispose() 

References

Vadim Gremyachev
  • 42,498
  • 3
  • 86
  • 167
1

Read this article http://jeffreypaarhuis.com/2012/06/07/scripting-sharepoint-online-with-powershell-using-client-object-model/

In one of the comments, a user has mentioned about retrieving property HasUniqueRoleAssignments and how he resolved it. The idea is to create a dll which uses csom to get the property. And then use it via PowerShell.

public void LoadSPWebWithBreakRoleInheritance(ClientObject objectToLoad)
{
    Web webToRetrieve = (Web) objectToLoad;
    base.Load(webToRetrieve, website => website.Title, website => website.HasUniqueRoleAssignments);
}

In your case, you can use similar technique to get list properties.

Amal Hashim
  • 28,306
  • 5
  • 31
  • 61
  • 1
    @VadimGremyachev Ok I have removed the statement. I will keep the answer so it will be another option for users. Thanks! – Amal Hashim Dec 29 '14 at 18:10
1

Gary Lapointe has the article Loading Specific Values Using Lambda Expressions and the SharePoint CSOM API with Windows PowerShell which is providing lots of insight and also the function Load-CSOMProperties.ps1 over on github

Utility PowerShell function that facilitates the loading of specific properties of a Microsoft.SharePoint.Client.ClientObject object or Microsoft.SharePoint.Client.ClientObjectCollection object.

That function works fine for me, using it to retrieve HasUniqueRoleAssignements should work like this:

        Load-CSOMProperties -object $list -propertyNames @("HasUniqueRoleAssignments") 
        $ctx.ExecuteQuery()
user1730
  • 556
  • 7
  • 18
1

You can use C# code in PowerShell scripts with Add-Type cmdlet:

Add-Type -Language CSharp -ReferencedAssemblies @("$PSScriptRoot\Microsoft.SharePoint.Client.dll", "$PSScriptRoot\Microsoft.SharePoint.Client.Runtime.dll") -TypeDefinition '
using Microsoft.SharePoint.Client;
public static class Helper
{
    public static void LoadHasUniqueRoleAssignments(ClientContext context, SecurableObject securableObject)
    {
        context.Load(securableObject, o => o.HasUniqueRoleAssignments);
    }
}'

[Helper]::LoadHasUniqueRoleAssignments($ctx, $list)
Rustam
  • 228
  • 1
  • 9