使用PowerShell和Microsoft REST API同步本地文件共享到SharePoint Online站点集
单站点权限授予方案
该需求完全可以实现,无需为应用授予租户级的全站点权限,操作步骤如下:
- 无需在Azure应用注册界面添加任何Microsoft Graph或SharePoint的应用权限,也不需要申请租户级权限的管理员同意。
- 通过PnP.PowerShell为应用单独授予目标站点的专属权限:
# 连接目标SharePoint站点 Connect-PnPOnline -Url "https://<租户域名>.sharepoint.com/sites/<目标站点名>" -Interactive # 为指定应用注册授予站点读写权限 Grant-PnPAzureADAppSitePermission -AppId "<你的应用ClientID>" -DisplayName "<应用名称>" -Permissions ReadWrite
授予完成后,该服务主体仅可访问当前指定站点,无法访问租户内其他SharePoint资源,符合最小权限要求。
MSAL令牌获取代码修正
你当前的代码缺少应用权限场景必需的Scope参数,修正后代码如下:
Import-Module MSAL.PS $clientid = "my-appreg-client-id" $tenantID = 'my-tenant-id' $thumbPrint = 'certificate-thumbprint' $ClientCertificate = Get-Item "Cert:\CurrentUser\My\$thumbPrint" # 新增Graph应用权限默认Scope $myAccessToken = Get-MsalToken -ClientId $clientID -TenantId $tenantID -ClientCertificate $ClientCertificate -Scope 'https://graph.microsoft.com/.default'
返回的$myAccessToken.AccessToken即可用于后续Microsoft Graph API调用,请求头需添加Authorization: Bearer <令牌值>。
文档库文件清单拉取方法
无需自行递归遍历文件夹结构,调用Graph接口可一次性获取整个文档库的所有文件、文件夹条目:
- 获取目标站点ID:调用GET接口
https://graph.microsoft.com/v1.0/sites/<租户域名>.sharepoint.com:/sites/<目标站点名>,提取返回结果的id字段作为站点ID。 - 获取目标文档库ID:调用GET接口
https://graph.microsoft.com/v1.0/sites/<站点ID>/drives,找到目标文档库对应的id字段作为Drive ID。 - 拉取全量文件条目:调用GET接口
https://graph.microsoft.com/v1.0/drives/<Drive ID>/list/items?$expand=driveItem,返回结果包含所有文件、文件夹的相对路径、最后修改时间、哈希值、资源ID等信息,你可以将相对路径作为键,相关属性作为值存入哈希表,用于后续比对。
同步逻辑实现提示
- 新建文件夹:本地存在但SharePoint不存在的文件夹,调用POST接口
https://graph.microsoft.com/v1.0/drives/<Drive ID>/items/<父文件夹ID>/children,请求体传入{"name":"<文件夹名>","folder":{}}即可完成创建。 - 文件上传:小于4MB的文件直接调用PUT接口
https://graph.microsoft.com/v1.0/drives/<Drive ID>/items/<父文件夹ID>:/<文件名>:/content,传入文件二进制流即可;大于4MB的文件使用分片上传接口实现。 - 版本校验:常规场景比对本地文件UTC修改时间和Graph返回的
lastModifiedDateTime即可,高准确性要求的场景可直接比对Graph返回的文件SHA1哈希值和本地文件哈希。
如果不想自行封装HTTP请求,也可以直接使用Microsoft Graph PowerShell模块,所有接口均已封装完成,可直接调用对应cmdlet实现功能。
内容的提问来源于stack exchange,提问作者Eric Vegter
相关产品推荐
相关产品推荐

