PowerShell通过Invoke-RestMethod调用Graph API创建文档集报400错误
问题背景
需要通过PowerShell脚本中的Invoke-RestMethod直接调用Graph API,在SharePoint Online中创建文档集(Document Set)。
相同请求在Graph Explorer门户中测试可正常运行并返回HTTP 201成功状态码,测试结果如下:
但在PowerShell脚本中执行完全相同的请求时返回HTTP 400错误请求,无法完成文件夹创建。创建文件夹是创建文档集的第一步,该步骤阻塞后续流程。
当前已配置的API权限如下,已在Graph Explorer中验证权限有效性:
- Files.ReadAndWrite.All
- Sites.ReadAndWrite.All
- Sites.FullControl.All(排查问题时额外添加的验证权限,非操作必需)
按照操作流程,文件夹创建成功后需要获取新文件夹ID,再发送PATCH请求修改其content type匹配目标文档集。现有公开资料大多仅描述操作逻辑,无直接可运行的参考代码。
问题根因
返回400错误由两处PowerShell语法使用不当导致,请求体格式不符合Graph API要求:
- PowerShell中不能直接用
{}表示空对象,该写法代表脚本块,会导致序列化失败,空对象需要用空哈希表@{}表示 Invoke-RestMethod不会自动将传入的哈希表格式Body序列化为JSON结构,直接传入哈希表会导致请求体格式错误,必须手动调用ConvertTo-Json完成序列化,同时需要指定足够的序列化深度避免嵌套对象内容丢失。
修复方案
第一步:修正文件夹创建代码
核心修改点:
- 空folder对象替换为PowerShell空哈希表
@{} - 传入请求体前先序列化为JSON格式,指定序列化深度为10
- 通过
Invoke-RestMethod的ContentType参数指定带UTF-8编码的JSON类型,避免解析错误
修正后的可运行代码:
$uri = "https://graph.microsoft.com/v1.0/drives/b!yVnguUBzyUC1PxgTM0JP-_ERFp1PTZFCjycaWZK6yKulBi9Ce_J8RIfF-OkWKE4B/root/children" $headers = @{ "Authorization" = "$($token.token_type) $($token.access_token)" } $body = @{ "name" = "Test" "folder" = @{} "@microsoft.graph.conflictBehavior" = "rename" } | ConvertTo-Json -Depth 10 $folder = Invoke-RestMethod -Headers $headers -Body $body -Method Post -Uri $uri -ContentType "application/json; charset=utf-8"
执行上述代码即可正常创建文件夹,返回201状态码及创建完成的文件夹对象。
第二步:将文件夹转换为目标文档集
文件夹创建完成后,发送PATCH请求修改对应列表项的内容类型为目标文档集的内容类型ID即可,操作步骤如下:
- 获取目标文档库下的文档集内容类型ID
# 替换为实际站点ID和文档库对应列表ID $siteId = "替换为你的SharePoint站点ID" $listId = "替换为目标文档库的列表ID" $ctUri = "https://graph.microsoft.com/v1.0/sites/$siteId/lists/$listId/contenttypes?`$filter=isFolder eq true" $contentTypes = Invoke-RestMethod -Headers $headers -Uri $ctUri -Method Get # 输出所有文件夹类型的内容类型,找到目标文档集对应的ID $contentTypes.value | Select-Object Name, Id
- 调用PATCH接口更新文件夹的内容类型
$folderId = $folder.id # 替换为上一步查询到的目标文档集内容类型ID $docSetCtId = "替换为你的文档集内容类型ID" $patchUri = "https://graph.microsoft.com/v1.0/sites/$siteId/lists/$listId/items/$folderId" $patchBody = @{ "contentType" = @{ "id" = $docSetCtId } } | ConvertTo-Json -Depth 10 $docSet = Invoke-RestMethod -Headers $headers -Body $patchBody -Method Patch -Uri $patchUri -ContentType "application/json; charset=utf-8"
执行完成后,之前创建的普通文件夹就会转换为指定类型的文档集。
提示:操作完成后建议移除非必需的Sites.FullControl.All权限,遵循最小权限原则。
内容的提问来源于stack exchange,提问作者Mr. Dr. Sushi
相关产品推荐
相关产品推荐

