如何通过PowerShell经M365发邮件且不降低Entra AD安全性?
安全替代方案(无需关闭Azure安全默认值)
方案1:用应用密码绕过MFA限制
安全默认值强制开启MFA后,普通账户密码无法用于SMTP认证,给发件人账户创建应用密码就能解决:
- 登录M365账户设置页面,找到「安全」>「附加安全验证」>「创建和管理应用密码」
- 生成专属应用密码,在PowerShell的SMTP认证代码里,用这个密码替换普通账户密码
- 提示:每个账户最多能创建10个应用密码,仅适用于不支持现代认证的老客户端(SMTP属于这类场景)
方案2:用Microsoft Graph API发送邮件(推荐)
这是更安全的现代方式,依赖OAuth2认证,完全不需要SMTP基本认证:
- 在Entra ID里注册一个应用程序:
- 选「单租户」类型,重定向URI选「公共客户端/桌面应用」即可
- 给应用添加「Mail.Send」应用权限,然后让管理员同意该权限
- PowerShell调用示例:
# 配置参数 $tenantId = "你的租户ID" $clientId = "注册的应用ID" $clientSecret = "应用的客户端密钥" $sendFrom = "发件人邮箱" $sendTo = "收件人邮箱" $subject = "脚本运行通知" $body = "脚本已成功执行完成" # 获取访问令牌 $tokenUri = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" $tokenBody = @{ grant_type = "client_credentials" client_id = $clientId client_secret = $clientSecret scope = "https://graph.microsoft.com/.default" } $tokenResponse = Invoke-RestMethod -Uri $tokenUri -Method Post -Body $tokenBody # 构造邮件JSON $mailBody = @{ message = @{ subject = $subject body = @{ contentType = "Text" content = $body } toRecipients = @( @{ emailAddress = @{ address = $sendTo } } ) } saveToSentItems = $true } | ConvertTo-Json # 发送邮件 Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/users/$sendFrom/sendMail" -Method Post -Headers @{Authorization = "Bearer $($tokenResponse.access_token)"} -Body $mailBody -ContentType "application/json"
- 优势:完全符合安全默认值要求,权限可精细管控,不会暴露账户密码
方案3:用Exchange Online PowerShell模块发送
借助Exchange Online的官方模块,通过现代认证连接后发送邮件:
- 先安装模块:
Install-Module -Name ExchangeOnlineManagement - 用应用权限连接Exchange Online(需提前给注册的应用分配Exchange相关权限),再发送邮件:
$credential = New-Object System.Management.Automation.PSCredential($clientId, (ConvertTo-SecureString $clientSecret -AsPlainText -Force)) Connect-ExchangeOnline -AppId $clientId -Credential $credential -Organization $tenantId # 发送邮件 Send-MailMessage -From "发件人邮箱" -To "收件人邮箱" -Subject "脚本通知" -Body "脚本运行完成" -SmtpServer "smtp.office365.com" -Port 587 -UseSsl
- 特点:不需要启用SMTP基本认证,依托官方模块的现代认证机制,安全性有保障
内容的提问来源于stack exchange,提问作者Max
相关产品推荐
相关产品推荐

