使用Microsoft Graph API上传文件至SharePoint Online遇400错误求助
我来帮你排查这个400 Bad Request错误的问题,主要有几个关键问题需要修正:
1. 站点ID格式不正确
你当前请求URL里的tenant.sharepoint.com不是Graph API认可的有效站点ID格式。Graph API中站点的标识有两种常用方式:
- 完整站点ID:格式为
{tenant-id},{site-collection-id},{site-id},你可以通过调用GET https://graph.microsoft.com/v1.0/sites/tenant.sharepoint.com:/sites/你的站点名称获取站点详情,其中的id字段就是完整站点ID。 - 路径式引用:直接用
sites/租户域名:/站点相对路径,比如sites/tenant.sharepoint.com:/sites/MyTeamSite,这种方式不需要提前获取ID,更直观。
2. 上传请求的参数与ContentType错误
你的RestMethod函数默认设置了-ContentType "application/json",但上传二进制文件(比如Excel)不需要这个参数,反而会导致请求格式错误。另外,上传本地文件需要使用-InFile参数指定文件路径,而不是把内容放在Body里。
3. URL中的文件名错误
你在URL里使用了完整本地路径c:\temp\reports.xlsx,但这里只需要文件名reports.xlsx,否则URL会包含反斜杠等非法字符,引发格式错误。
修正后的完整脚本
function RestMethod { Param ( [parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [String]$Request, [parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [String]$RequestMethod, [parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [String]$Body, [parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [String]$InFile ) $Headers = @{ Authorization = "$($global:RequestToken.token_type) $($global:RequestToken.access_token)" } $RestResults = $null [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 try { # 动态构建请求参数,区分JSON请求和文件上传请求 $requestParams = @{ Uri = $Request Headers = $Headers Method = $RequestMethod } if ($Body) { $requestParams["ContentType"] = "application/json" $requestParams["Body"] = $Body } if ($InFile) { $requestParams["InFile"] = $InFile } $RestResults = Invoke-RestMethod @requestParams } catch { Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__ Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription # 获取更详细的错误信息,方便排查 $errorStream = $_.Exception.Response.GetResponseStream() $reader = New-Object System.IO.StreamReader($errorStream) $errorDetails = $reader.ReadToEnd() Write-Host "Error Details:" $errorDetails } return $RestResults } # 配置参数 $localFilePath = "c:\temp\reports.xlsx" $fileName = [System.IO.Path]::GetFileName($localFilePath) $siteRelativePath = "/sites/你的站点名称" # 替换成你的SharePoint站点相对路径 $targetFolder = "Test" # 目标文件夹名称(需确保已存在) # 构建上传请求URL(使用路径式站点引用) $upLoadRequest = "https://graph.microsoft.com/v1.0/sites/tenant.sharepoint.com:$($siteRelativePath)/drive/root:/$($targetFolder)/$($fileName):/content" # 执行上传 $upLoadResults = RestMethod -Request $upLoadRequest -RequestMethod 'PUT' -InFile $localFilePath
额外注意事项
- 权限验证:确保你的
$global:RequestToken拥有足够的权限,比如Files.ReadWrite.All或Sites.ReadWrite.All(根据应用类型选择委派权限或应用权限)。 - 文件夹存在性:目标文件夹
Test必须已经存在于SharePoint站点的默认文档库中,否则会返回404错误。 - 错误排查:修正后的
RestMethod函数添加了详细错误信息输出,如果仍有问题,可以根据返回的错误详情进一步定位。
内容的提问来源于stack exchange,提问作者The_Thinker
相关产品推荐
相关产品推荐

