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

使用Outlook SMTP与应用密码的PowerShell Send-MailMessage失效求助

解决Outlook.com禁用基础认证后的PowerShell邮件通知问题

问题根源

Send-MailMessage cmdlet仅支持基础认证,而微软已全面禁用outlook.com的SMTP基础认证。你尝试的"应用密码"仅适用于本身支持现代认证但需适配旧设备的场景,并非用来给仅支持基础认证的工具绕过限制,因此无法解决问题。

解决方案

方案一:使用Microsoft Graph PowerShell模块(官方推荐)

这是微软官方支持的现代认证方案,无需依赖SMTP基础认证,步骤如下:

  1. 安装Microsoft Graph模块(仅需运行一次):
Install-Module -Name Microsoft.Graph -Scope CurrentUser -Force
  1. 首次运行授权(弹出浏览器登录你的Outlook账户,授予邮件发送权限,凭据会自动保存到本地):
Connect-MgGraph -Scopes "Mail.Send"
  1. 编写无人值守邮件脚本:
# 导入模块
Import-Module Microsoft.Graph.Mail

# 配置邮件内容
$mailParams = @{
    Message = @{
        Subject = "PC rebooted"
        Body = @{
            ContentType = "Text"
            Content = "PC has rebooted"
        }
        ToRecipients = @(
            @{
                EmailAddress = @{
                    Address = "NN@outlook.com"
                }
            }
        )
    }
    SaveToSentItems = $true
}

# 发送邮件
Send-MgUserMail -UserId "NN@outlook.com" -BodyParameter $mailParams

该脚本在无人值守环境下,会自动使用之前保存的授权凭据完成认证,无需手动输入密码。

方案二:使用.NET SmtpClient结合OAuth2(无需安装模块)

适合不想额外安装PowerShell模块的场景,需要先注册Azure AD公共客户端应用:

  1. 注册Azure AD公共客户端应用:
    • 登录Azure管理平台,搜索"应用注册"服务
    • 点击"新注册",填写自定义名称,支持账户类型选择"任何组织目录中的账户和个人Microsoft账户"
    • 重定向URI选择"公共客户端/本机"类型,填写http://localhost
    • 完成注册后,复制页面上的"应用程序(客户端)ID",这就是脚本中需要的clientId
  2. 编写脚本:
# 配置参数
$clientId = "你的Azure应用ID"
$tenantId = "consumers" # 个人Outlook账户固定填这个
$scopes = "https://outlook.office.com/SMTP.Send"
$smtpServer = "smtp.office365.com"
$smtpPort = 587
$fromAddr = "NN@outlook.com"
$toAddr = "NN@outlook.com"

# 获取OAuth2令牌(首次运行需按提示在浏览器完成授权)
$deviceCodeReq = @{ client_id = $clientId; scope = $scopes }
$deviceCodeResp = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/devicecode" -Method Post -Body $deviceCodeReq
Write-Host "请在浏览器打开提示链接并输入代码:`n$($deviceCodeResp.message)"

$tokenReq = @{
    client_id = $clientId
    grant_type = "urn:ietf:params:oauth:grant-type:device_code"
    device_code = $deviceCodeResp.device_code
}
do {
    Start-Sleep -Seconds $deviceCodeResp.interval
    try {
        $tokenResp = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" -Method Post -Body $tokenReq
        break
    } catch {
        $err = $_.ErrorDetails.Message | ConvertFrom-Json
        if ($err.error -ne "authorization_pending") { throw $err.error_description }
    }
} while ($true)

# 发送邮件
$mail = New-Object System.Net.Mail.MailMessage($fromAddr, $toAddr)
$mail.Subject = "PC rebooted"
$mail.Body = "PC has rebooted"

$smtp = New-Object System.Net.Mail.SmtpClient($smtpServer, $smtpPort)
$smtp.EnableSsl = $true
$smtp.UseDefaultCredentials = $false
$smtp.Credentials = New-Object System.Net.NetworkCredential($fromAddr, $tokenResp.access_token)
$smtp.Send($mail)

首次运行脚本会提示你在浏览器完成授权,后续无人值守运行时可自动复用令牌(令牌过期会自动刷新)。

内容的提问来源于stack exchange,提问作者ChrisHD

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 20:22:06