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
相关产品推荐
相关产品推荐

