使用Get-PnPFile操作SharePoint Online时遇未授权错误求助
在SharePoint Online PowerShell中使用Get-PnPFile cmdlet时,持续收到Attempted to perform an unauthorized operation错误。当前环境为PowerShell 7.4.2 + PnP.PowerShell 2.4.0,已确认自身是网站集所有者且列表权限配置无误,使用Connect-PnPOnline -UseWebLogin参数连接(因暂无法完成PowerShell注册,依赖该方式绕过Azure注册流程)。
相关代码片段:
Connect-PnPOnline -Url $TargetSiteURL -UseWebLogin -ForceAuthentication $TargetCtx = Get-PnPContext $targetConnection = Get-PnPConnection # Get target list $TargetList = Get-PnPList -Identity $TargetListName -Connection $targetConnection # Get target items $TargetItems = Get-PnPListItem -List $TargetList -Connection $targetConnection $Attachments = Get-PnPProperty -ClientObject $SourceItem -Property "AttachmentFiles" -Connection $SourceConnection if ($Attachments) { $Attachments | ForEach-Object { # Download the attachment to Temp $File = Get-PnPFile -Url $_.ServerRelativeUrl -FileName $_.FileName -Path $env:TEMP -AsFile -Force -Connection $SourceConnection # Add attachment to target list item $FileStream = New-Object IO.FileStream(($env:TEMP + "\" + $_.FileName), [System.IO.FileMode]::Open) $AttachmentInfo = New-Object -TypeName Microsoft.SharePoint.Client.AttachmentCreationInformation $AttachmentInfo.FileName = $_.FileName $AttachmentInfo.ContentStream = $FileStream $AttachFile = $TargetItem.AttachmentFiles.Add($AttachmentInfo) $TargetItem.Context.ExecuteQuery() # Delete the temporary file Remove-Item -Path $env:TEMP\$($_.FileName) -Force } }
成因1:-UseWebLogin的权限限制
-UseWebLogin基于浏览器会话Cookie验证身份,这种方式的权限范围有限,新版本PnP.PowerShell对API操作的权限校验更严格,Get-PnPFile的文件下载操作可能需要Cookie会话未涵盖的权限范围。
解决方法:
调整Get-PnPFile调用方式,跳过本地文件保存,直接获取文件字节流:
# 直接获取文件字节数组,避免本地文件操作 $FileContent = Get-PnPFile -Url $_.ServerRelativeUrl -AsByteArray -Connection $SourceConnection $FileStream = New-Object System.IO.MemoryStream($FileContent)
这种方式减少了本地文件IO的权限校验环节,同时避免了临时文件的创建与删除。
成因2:版本兼容性问题
PowerShell 7.4.2与PnP.PowerShell 2.4.0的组合可能存在未公开的兼容性问题,尤其是在-UseWebLogin模式下的权限传递逻辑。
解决方法:
临时降级测试:切换到PnP.PowerShell 2.3.0搭配PowerShell 7.3.x版本,验证问题是否消失,确认是否为版本兼容导致。
成因3:跨站点连接会话冲突
代码中同时使用SourceConnection和TargetConnection两个连接对象,-UseWebLogin的会话可能无法在跨站点场景下正确复用权限,导致其中一个连接的权限校验失败。
解决方法:
分开建立并管理两个站点的连接:确保每个站点的连接都是单独通过Connect-PnPOnline -UseWebLogin建立,避免会话复用导致的权限异常。
成因4:个别附件的独立权限设置
虽然你是网站集所有者,但部分附件可能被设置了独立的权限(继承被打破),阻止了当前账号的访问。
解决方法:
在浏览器中直接访问附件的ServerRelativeUrl(格式:https://<tenant>.sharepoint.com<ServerRelativeUrl>),确认是否能正常打开。若无法访问,检查该附件的权限设置,恢复继承或添加自身权限。
# 建立目标站点连接 Connect-PnPOnline -Url $TargetSiteURL -UseWebLogin -ForceAuthentication $TargetConnection = Get-PnPConnection $TargetList = Get-PnPList -Identity $TargetListName -Connection $TargetConnection $TargetItems = Get-PnPListItem -List $TargetList -Connection $TargetConnection # 建立源站点连接(单独建立,避免会话冲突) Connect-PnPOnline -Url $SourceSiteURL -UseWebLogin -ForceAuthentication $SourceConnection = Get-PnPConnection # 处理附件 $Attachments = Get-PnPProperty -ClientObject $SourceItem -Property "AttachmentFiles" -Connection $SourceConnection if ($Attachments) { $Attachments | ForEach-Object { # 直接获取文件字节流,跳过本地文件保存 $FileContent = Get-PnPFile -Url $_.ServerRelativeUrl -AsByteArray -Connection $SourceConnection $FileStream = New-Object System.IO.MemoryStream($FileContent) # 添加到目标列表项 $AttachmentInfo = New-Object -TypeName Microsoft.SharePoint.Client.AttachmentCreationInformation $AttachmentInfo.FileName = $_.FileName $AttachmentInfo.ContentStream = $FileStream $AttachFile = $TargetItem.AttachmentFiles.Add($AttachmentInfo) # 切换到目标上下文执行查询 $TargetConnection.Context.ExecuteQuery() # 释放流资源 $FileStream.Dispose() } }
内容的提问来源于stack exchange,提问作者Agni200895

