PowerShell通过OAuth2向Exchange Online发送认证邮件失败求助
问题排查与解决方案
核心问题定位
你遇到的Authentication failed: * BYE Connection is closed. 13错误,核心原因是权限配置不匹配:当前仅配置了IMAP.AccessAsApp权限,该权限仅用于接收邮件,无法支持发送邮件操作,导致Exchange服务器拒绝后续连接。
分步修正方案
1. 修正应用权限配置
登录Azure AD门户,找到MyApp应用,添加对应发送邮件的应用权限并完成租户授权:
- 若使用SMTP协议发送:添加Office 365 Exchange Online > SMTP.SendAsApp(应用权限)
- 若改用Microsoft Graph API发送(更推荐,无需处理复杂的SMTP连接逻辑):添加Microsoft Graph > Mail.Send(应用权限)
2. 调整令牌获取逻辑
获取OAuth2令牌时,scope参数必须匹配你使用的服务:
- 针对Exchange Online SMTP:
scope设为https://outlook.office365.com/.default - 针对Microsoft Graph API:
scope设为https://graph.microsoft.com/.default
示例令牌获取代码:
$tenantId = "你的租户ID" $clientId = "MyApp的客户端ID" $clientSecret = "MyApp的密钥" $tokenUri = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" $body = @{ grant_type = "client_credentials" client_id = $clientId client_secret = $clientSecret scope = "https://outlook.office365.com/.default" # 按需替换为Graph的scope } $tokenResponse = Invoke-RestMethod -Uri $tokenUri -Method Post -Body $body -ContentType "application/x-www-form-urlencoded" $accessToken = $tokenResponse.access_token
3. 发送邮件的两种实现方式
方式一:SMTP+OAuth2发送
$smtpServer = "smtp.office365.com" $smtpPort = 587 $fromAddress = "你的邮箱地址" $toAddress = "你的邮箱地址" $mailMessage = New-Object System.Net.Mail.MailMessage($fromAddress, $toAddress) $mailMessage.Subject = "OAuth2测试通知邮件" $mailMessage.Body = "这是通过SMTP+OAuth2发送的测试内容" $smtpClient = New-Object System.Net.Mail.SmtpClient($smtpServer, $smtpPort) $smtpClient.EnableSsl = $true $smtpClient.Credentials = New-Object System.Net.NetworkCredential($fromAddress, $accessToken) try { $smtpClient.Send($mailMessage) Write-Host "邮件发送成功" } catch { Write-Error "发送失败: $_" }
方式二:Microsoft Graph API发送(更简洁)
$graphApiUri = "https://graph.microsoft.com/v1.0/users/你的邮箱地址/sendMail" $mailPayload = @{ message = @{ subject = "Graph API测试通知邮件" body = @{ contentType = "Text" content = "这是通过Graph API发送的测试内容" } toRecipients = @( @{ emailAddress = @{ address = "你的邮箱地址" } } ) } saveToSentItems = $true } | ConvertTo-Json Invoke-RestMethod -Uri $graphApiUri -Method Post -Headers @{Authorization = "Bearer $accessToken"} -Body $mailPayload -ContentType "application/json" Write-Host "邮件发送成功"
4. 额外验证点
- 确认已为
MyApp服务主体授予目标邮箱的FullAccess权限(你之前的操作已完成,无需重复) - 可通过本地JWT解码工具验证获取的
access_token,确认其包含对应发送权限的声明
内容的提问来源于stack exchange,提问作者nadine
相关产品推荐
相关产品推荐

