求PnP PowerShell脚本:为SharePoint根文件夹设置只读权限
问题背景
我们有一个包含约1000个根文件夹的SharePoint Online文档库,需要编写PnP PowerShell脚本实现以下操作:
- 仅处理文档库的根文件夹(不包含子文件夹)
- 打破文件夹的权限继承,设置唯一权限
- 获取文件夹现有权限组和用户,将其权限改为只读
之前编写的脚本在访问RoleAssignments时触发错误:
The collection has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested. At line:13 char:9
- ForEach($RoleAssignment in $RoleAssignments)
~~~~~~~~~~~~~~~
- CategoryInfo : OperationStopped: (:) [], CollectionNotInitializedException
- FullyQualifiedErrorId : Microsoft.SharePoint.Client.CollectionNotInitializedException
错误原因
使用Get-PnPFolderItem获取的文件夹对象默认不会加载RoleAssignments等关联属性,直接访问未初始化的集合就会抛出该异常。需要显式加载文件夹对应的列表项及权限相关属性,或者改用Get-PnPListItem来获取完整的权限信息。
完整可行脚本
# 参数配置 $SiteURL = "https://你的租户名.sharepoint.com/sites/你的站点名" $LibraryName = "Shared Documents" # 文档库名称 $ReadOnlyRoleName = "只读" # 根据环境调整,英文环境用"Read" # 连接到SharePoint站点 Connect-PnPOnline -Url $SiteURL -UseWebLogin # 获取文档库的根文件夹对应的列表项集合(仅根文件夹,不含子文件夹) $rootFolders = Get-PnPListItem -List $LibraryName -Query "<View><Query><Where><Eq><FieldRef Name='FSObjType'/><Value Type='Integer'>1</Value></Eq></Where></Query><RowLimit>5000</RowLimit></View>" -Fields "Title", "FileRef", "HasUniqueRoleAssignments" # 获取只读权限定义 $readRoleDefinition = Get-PnPRoleDefinition -Identity $ReadOnlyRoleName foreach ($folderItem in $rootFolders) { $folderUrl = $folderItem["FileRef"] Write-Host "正在处理文件夹: $folderUrl" -ForegroundColor Cyan # 检查是否已拥有唯一权限 if ($folderItem.HasUniqueRoleAssignments) { Write-Host "文件夹已设置唯一权限,跳过权限继承打破步骤" -ForegroundColor Yellow } else { # 打破权限继承,保留现有权限(第一个$true),不影响子项权限(第二个$false) $folderItem.BreakRoleInheritance($true, $false) Invoke-PnPQuery Write-Host "已打破文件夹权限继承" -ForegroundColor Green } # 加载当前文件夹的角色分配(必须显式加载,避免未初始化异常) $folderItem.Load("RoleAssignments") Invoke-PnPQuery # 遍历现有角色分配,替换为只读权限 foreach ($roleAssignment in $folderItem.RoleAssignments) { # 加载角色分配的成员和角色定义绑定 $roleAssignment.Load("Member", "RoleDefinitionBindings") Invoke-PnPQuery # 获取当前成员(用户/组) $member = $roleAssignment.Member Write-Host "正在修改成员 $($member.Title) 的权限为只读" -ForegroundColor Gray # 删除原有角色绑定 $roleAssignment.DeleteObject() # 添加只读权限绑定 Add-PnPRoleAssignment -ListItem $folderItem -Principal $member -RoleDefinition $readRoleDefinition } # 提交所有权限修改 Invoke-PnPQuery Write-Host "文件夹 $folderUrl 权限修改完成`n" -ForegroundColor Green } Write-Host "所有根文件夹权限处理完成!" -ForegroundColor Green
关键说明
- 仅处理根文件夹:通过
FSObjType=1筛选文件夹,且未使用递归查询,确保只获取文档库根目录下的文件夹 - 显式加载属性:使用
$folderItem.Load("RoleAssignments")和$roleAssignment.Load("Member", "RoleDefinitionBindings")显式请求加载权限相关属性,解决集合未初始化的问题 - 权限替换逻辑:先删除原有角色分配,再为相同成员添加只读权限,确保权限完全替换为只读
- 批量处理优化:每处理一个文件夹后调用
Invoke-PnPQuery提交修改,避免单次请求数据量过大 - 权限名称适配:根据你的SharePoint环境语言调整
$ReadOnlyRoleName,中文环境用"只读",英文环境用"Read"
内容的提问来源于stack exchange,提问作者John John
相关产品推荐
相关产品推荐

