You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 05:16:30