RoleDefinitionBindingCollection调用中的SPO Powershell设置权限错误

时间:2016-09-21 00:39:44

标签: powershell permissions sharepoint-online

在Sharepoint Online上,使用Powershell,我正在尝试设置列表项权限,并且找到了许多使用RoleDefinitionBindingCollection($ ctx)调用的教程......

但是,当我这样做时,我收到以下错误:

New-Object : Cannot find an overload for "RoleDefinitionBindingCollection" and 
the argument count: "1".At 
C:\Users\thebear\Desktop\SEDA\SEDASetIPPermissions.ps1:172 char:31
+ ... entReader = New-Object Microsoft.SharePoint.Client.RoleDefinitionBind ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidOperation: (:) [New-Object], MethodException
+ FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand

我正在迭代Doclib文件夹,然后通过Folder.Files,检查自定义字段中的值,并设置匹配项的权限。 编辑:以下是完整代码

# cd 'C:\Users\thebear\Desktop\SEDA'
# .\SEDASetIPPermissions test KLY KLY1

Set-ExecutionPolicy RemoteSigned -Scope CurrentUser

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" 

If($($args.Count) -ne 3) 
{ 
    Write-Host   “Usage: .\SEDASetIPPermissions <'prod' or 'test'> <ProgCode i.e. 'LCL' or 'All'> <IPGroup i.e. 'KLY1' or 'All'>"
    break
}

$Site = if($args[0] -eq 'prod') {'sedasearch'} elseif ($args[0] -eq 'test') {'sedasearchtest'}
$Lib = $args[1]
$IPGroup = $args[2] 


# Get Connected
$Cred = Get-Credential
$Credentials = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $Cred.UserName,         $Cred.Password
$Url = "https://MySite.sharepoint.com/sites/$Site"
Connect-SPOnline -Url $Url -Credentials $Credentials

# Get Client Context
$ctx = Get-SPOContext
$ctx.RequestTimeout = 1000000
$ctx.ExecuteQuery()

# Get Web & Lists
$web = $ctx.Web
$ctx.Load($web)
$ctx.Load($web.Lists)
$ctx.Load($web.RoleDefinitions)
$ctx.ExecuteQuery()
$lists = $web.Lists

# Get Site Groups
$groups = $web.SiteGroups
$ctx.Load($groups)
$ctx.ExecuteQuery()

# Get Target Group
$groupFound = $false
$ScriptStart = Get-Date

foreach ($group in $groups)
{
    if ($group.Title -eq "SEDA Admins")
    {
        $AdminGroupID = $group.Id
    }    
    elseif($group.Title -eq $IPGroup + " Security Group")
    { 
        $groupFound = $true
        $IPGroupID = $group.Id
        Write-Host "`n'$IPGroup Security Group' Found...`n" -ForegroundColor Green
    }
}

if (!$groupFound) { Write-Host "`n'$IPGroup Security Group' NOT Found...`n" -ForegroundColor Red; break }

# Get Target List
$list = $lists.GetByTitle($Lib + " Library")
$ctx.Load($list)
$ctx.Load($list.RootFolder)
$ctx.Load($list.Fields)
$ctx.ExecuteQuery()

if($list -ne $null)
{ "`n'{0}' Found...`n" -f $list.Title | Write-Host -ForegroundColor Green }
else
{ "`n'{0}' NOT Found...`n" -f $list.Title | Write-Host -ForegroundColor Red; break }

# Get List Folders
$folders = $list.RootFolder.Folders 
$ctx.Load($folders)
$ctx.ExecuteQuery()

$folders = $folders | sort Name

# Set Up Group and Admin Permissions (if not already there)
$RoleDefinitions = $web.RoleDefinitions
$ctx.Load($RoleDefinitions)
$ctx.ExecuteQuery()

$foundIPGroupRole = $false
$foundIPAdminRole = $false

foreach ($role in $RoleDefinitions)
{
    if ($role.Name -eq "Read") 
    { 
        $IPGroupRole = $role
        $foundIPGroupRole = $true 
    }
    elseif ($role.Name -eq "Full Control") 
    { 
        $IPAdminRole = $role
        $foundIPAdminRole = $true
    }
}


# Set the permissions for 'IP Group'
$roleAssignmentReader = New-Object Microsoft.SharePoint.Client.RoleDefinitionBindingCollection($ctx)
$roleAssignmentReader.Add($IPGroupRole)

# Set the permissions for 'IP Admin'
$roleAssignmentAdmin = New-Object Microsoft.SharePoint.Client.RoleDefinitionBindingCollection($ctx)
$roleAssignmentAdmin.Add($IPAdminRole)


# Set Counters
$FileCount = 0
$FailCount = 0

foreach ($folder in $folders)
{
    $FolderFileCount = 0

    $ctx.Load($folder)
    $ctx.Load($folder.ListItemAllFields)
    $ctx.ExecuteQuery()

    if ($folder.ItemCount -lt 5000)
    {
        $files = $folder.Files
        $ctx.Load($files)
        $ctx.ExecuteQuery()

        "`nProcessing Folder {0}..." -f $folder.Name | Write-Host -ForegroundColor Green

    }
    else
    { "`nFolder {0} Exceeds 5000 Items...`n" -f $folder.Url | Write-Host -ForegroundColor Red; continue }

    foreach ($file in $files)
    {
        $ctx.Load($file)
        $ctx.Load($file.ListItemAllFields)
        $ctx.ExecuteQuery()

        $item = $file.ListItemAllFields
        $ctx.Load($item)
        $ctx.ExecuteQuery()

        $name = $file.Name
        $group = $item.get_item('IPGroup')

        if($group -eq $IPGroup)
        { 
            "`nProcessing File {0}...`n" -f $name | Write-Host -ForegroundColor Green;

            # Break inheritance on the list item and remove existing permissons.
            # NOTE: Use $item.ResetRoleInheritance() to Restore Roll Inheritance
            $item.BreakRoleInheritance($false, $true)

            # Apply the two permission roles to the list item.
            $ctx.Load($item.RoleAssignments.Add($IPGroupID, $roleAssignmentReader))
            $ctx.Load($item.RoleAssignments.Add($AdminGroupID, $roleAssignmentAdmin))

            # Update the list item and execute
            $item.Update()
            $ctx.ExecuteQuery()

            "`nProcessed File {0}...`n" -f $name | Write-Host -ForegroundColor Green;
        }

        $FolderFileCount += 1
        if($FolderFileCount % 1000 -eq 0) { "{0}K" -f ($FolderFileCount/1000).ToString() | Write-Host }
        elseif($FolderFileCount % 100 -eq 0) {Write-Host '*'}
        else {Write-Host -NoNewline '.'}    
    }
}
“`n{0} Files Processed, {1} Error(s), Elapsed Time: {2}" -f $FileCount, $FailCount, $((Get-Date) - $ScriptStart) | Write-Host

$ ctx似乎是合法的...还有什么可能导致这个错误(现在一天)?

2 个答案:

答案 0 :(得分:1)

发生此错误,因为RoleDefinitionBindingCollection constructor期望ClientRuntimeContext对象,但是以下行:

$ctx = Get-SPOContext

返回OfficeDevPnP.Core.PnPClientContext type的对象。即使它继承自ClientRuntimeContext对象(PnPClientContext -> ClientContext -> ClientRuntimeContext),它也不能用于实例化Microsoft.SharePoint.Client.RoleDefinitionBindingCollection对象。

<强>解决方案

一种选择是替换线:

Connect-SPOnline -Url $Url -Credentials $Credentials
#Get Client Context
$ctx = Get-SPOContext

$ctx = Get-Context -WebUrl $Url -UserName $Credentials.UserName -Password $Credentials.Password

,其中

Function Get-Context([String]$WebUrl,[String]$UserName,[System.Security.SecureString]$Password) {
    $context = New-Object Microsoft.SharePoint.Client.ClientContext($WebUrl)
    $context.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $Password)
    return $context
}

返回Microsoft.SharePoint.Client.ClientContext个对象。

答案 1 :(得分:0)

根据以下链接。 Microsoft.SharePoint.Client.RoleDefinitionBindingCollection($ ctx)正在寻找一个url作为参数,而不是文件名。 https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.client.roledefinitionbindingcollection.aspx