PowerShell调用Graph API sendMail接口返回400错误求助
PowerShell调用Graph API sendMail接口返回400错误排查
问题描述
我无法理解为何我的PowerShell代码调用Invoke-RestMethod时,始终针对Graph API的https://graph.microsoft.com/v1.0/me/sendMail接口返回400错误。
示例代码
#leaving out clientid and tenantid intentionally $MsalParams = @{ ClientId = $clientId TenantId = $tenantId Scopes = 'https://graph.microsoft.com/User.Read.All','https://graph.microsoft.com/Mail.Send','https://graph.microsoft.com/Mail.Send.Shared' } $MsalResponse = Get-MsalToken @MsalParams $accessToken = $MsalResponse.AccessToken $uri = "https://graph.microsoft.com/v1.0/me/sendMail" $headers = @{ 'Authorization' = "Bearer $accessToken" 'Content-Type' = 'application/json' } $email = @{ 'message' = @{ 'subject' = 'TestSubject' 'body' = @{ 'contentType' = 'text' 'content' = 'This is just a simple mail body' } 'toRecipients' = @( @{ 'emailAddress' = @{ 'address' = "someuser@somecompany.com" } } ) } } $result = Invoke-RestMethod -Uri $uri -Headers $headers -Method Post -Body $email -ContentType "application/json"
错误信息
Invoke-RestMethod : Der Remoteserver hat einen Fehler zurückgegeben: (400) Ungültige Anforderung. In ...... xxxxl.ps1:39 Zeichen:12 + $result = Invoke-RestMethod -Uri $uri -Headers $headers -Method Post ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
已排查情况
- 以个人用户身份登录(代表用户类型程序),获取AccessToken正常,排除权限问题
- 验证JSON结构符合Microsoft文档要求
- 使用PowerShell版本5.1.19041.3031
- 尝试过对请求体使用
ConvertTo-Json -Depth 3,但无变化
可能的解决方案
1. 确保请求体正确序列化为JSON字符串
PowerShell 5.1中,Invoke-RestMethod不会自动将哈希表转换为JSON格式,必须手动完成序列化。即使你尝试过ConvertTo-Json,也要确认是否正确替换了-Body参数的输入:
# 将哈希表转换为JSON字符串,确保深度足够覆盖嵌套结构 $jsonBody = $email | ConvertTo-Json -Depth 3 # 使用序列化后的JSON字符串作为请求体 $result = Invoke-RestMethod -Uri $uri -Headers $headers -Method Post -Body $jsonBody -ContentType "application/json"
2. 移除重复的Content-Type设置
你的代码同时在请求头和命令参数中设置了Content-Type: application/json,虽然多数情况下不会触发错误,但可能引发潜在的格式冲突。建议移除其中一个,比如保留命令参数的设置,删除headers中的对应项:
$headers = @{ 'Authorization' = "Bearer $accessToken" }
3. 验证收件人邮箱地址有效性
确认toRecipients中的邮箱地址someuser@somecompany.com格式正确、真实存在,拼写错误(如缺失@、域名错误)可能导致400错误。
4. 获取Graph API的详细错误响应
400错误通常包含具体的原因描述,通过捕获异常的响应体可以精准定位问题:
try { $jsonBody = $email | ConvertTo-Json -Depth 3 $result = Invoke-RestMethod -Uri $uri -Headers $headers -Method Post -Body $jsonBody -ContentType "application/json" } catch { $errorStream = $_.Exception.Response.GetResponseStream() $streamReader = New-Object System.IO.StreamReader($errorStream) $streamReader.BaseStream.Position = 0 $streamReader.DiscardBufferedData() $errorDetails = $streamReader.ReadToEnd() Write-Host "详细错误信息: $errorDetails" }
运行这段代码后,你会得到Graph API返回的具体错误说明(比如哪个字段格式错误、缺少必填参数等),这是最直接的排查方式。
内容的提问来源于stack exchange,提问作者Christoph
相关产品推荐
相关产品推荐

