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

PowerShell脚本未发送密码过期提醒邮件排查求助

排查密码过期通知邮件未发送问题

结合你的脚本和环境情况,从以下几个方向逐一排查:

1. 密码过期天数计算逻辑存在精度丢失

你将过期时间转换为短日期字符串后再计算剩余天数,这会丢失时间精度,导致daysToExpire计算偏差,错过触发14天或3天的通知条件:

$expires = $lastSet.AddDays($maxDays).ToShortDateString()
$daysToExpire = [math]::Round((New-TimeSpan -Start (Get-Date) -End $expires).TotalDays)

例如,若密码过期时间是2024-10-20 00:00:00,当前时间为2024-10-06 15:00:00,实际剩余13.375天,四舍五入后为13天,无法触发14天通知;只有当剩余天数的小数部分≥0.5时才会被进位,导致大量符合条件的用户被遗漏。

修复方案:保留DateTime类型直接计算,避免转换为字符串:

$expires = $lastSet.AddDays($maxDays)
$daysToExpire = [math]::Round((New-TimeSpan -Start (Get-Date) -End $expires).TotalDays)

2. SMTP客户端静默失败(无报错但实际未发送)

你使用的System.Net.Mail.SmtpClient是已弃用的类,且O365租户大概率已禁用SMTP基本认证(用户名+密码),这会导致邮件发送失败但脚本无异常抛出。同时脚本缺少错误捕获机制,无法定位发送时的具体问题。

排查&修复:

  • 改用Send-MailMessage并添加错误捕获,同时验证认证方式:
    # 替换原SMTP发送逻辑
    try {
        $securePassword = ConvertTo-SecureString $smtpPassword -AsPlainText -Force
        $credential = New-Object System.Management.Automation.PSCredential($smtpUsername, $securePassword)
        Send-MailMessage -From $emailFrom -To $user.Mail -Subject $subject -Body $body `
          -SmtpServer $smtpServer -Port $smtpPort -UseSsl -Credential $credential
        Write-Host "邮件已发送至:$($user.Mail)"
    }
    catch {
        Write-Error "发送邮件至 $($user.Mail) 失败:$_"
    }
    
  • 若租户禁用SMTP基本认证,需为发送账户启用应用密码(针对MFA账户),或配置OAuth认证替代基本认证。

3. AD用户筛选逻辑不准确

你使用的PowerShell语法过滤器{PasswordNeverExpires -eq $false}依赖AD计算属性,部分场景下LDAP解析会出现偏差,导致筛选出不符合条件的用户或遗漏目标用户。

修复方案:改用LDAP语法过滤器,直接基于userAccountControl位掩码精准筛选:

$filter = "(&(Enabled=True)(!(userAccountControl:1.2.840.113556.1.4.803:=65536))(mail=*))"

该过滤器明确排除PASSWORD_NEVER_EXPIRES(对应位掩码65536)的用户,同时确保用户已启用且配置了有效邮箱。

4. 缺少调试日志,无法确认执行流程

脚本无任何输出,无法判断是否有用户符合通知条件,也无法确认邮件发送步骤是否被触发。

添加调试输出:在循环中加入日志,追踪每个用户的处理状态:

foreach ($user in $users) {
    $lastSet = [System.DateTime]::FromFileTimeUtc($user.pwdLastSet)
    $expires = $lastSet.AddDays($maxDays)
    $daysToExpire = [math]::Round((New-TimeSpan -Start (Get-Date) -End $expires).TotalDays)
    $firstName = $user.Name

    Write-Host "处理用户:$($user.Name) ($($user.Mail)) | 密码过期剩余天数:$daysToExpire"

    if ($daysToExpire -eq 14) {
        Write-Host "触发14天通知,准备发送邮件"
        # 邮件发送代码
    }
    elseif ($daysToExpire -eq 3) {
        Write-Host "触发3天通知,准备发送邮件"
        # 邮件发送代码
    }
}

5. O365账户权限或路由限制

  • 确认发送账户myaccount@domain.com未被O365限制发送邮件(如处于隔离状态、发送配额耗尽);
  • 验证用户Mail属性是否为有效邮箱地址,避免发送至不存在的邮箱导致邮件被静默丢弃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 11:07:10