PowerShell长文件路径检测脚本邮件功能故障排查求助
解决PowerShell长路径检测脚本的邮件功能异常问题
我来帮你排查下邮件功能异常的问题,顺便把脚本优化下,解决那些让你重复输入已配置字段的麻烦~
问题诊断
你的脚本邮件功能出问题,大概率是这几个原因:
- Office 365的SMTP服务器要求SSL加密和指定端口(587),默认的
Send-MailMessage调用没配置这些参数,导致连接失败或触发额外验证 - 脚本里的
Send-MailMessage可能因为缺少凭据参数,系统自动提示你输入(即使你已经配了From地址,Office365需要账号验证) - 用ADSI获取用户邮箱的方式不够可靠,容易出现SID解析失败的情况
修改后的完整脚本
# 配置参数 $limit = 90 $testpath = "\\server\share" # 改成你需要检测的UNC路径 $resultpath = "C:\test" $admins = "moh@test.com" $from = "moh@test.com" $smtpserver = "smtp.office365.com" $smtpPort = 587 # 确保结果目录存在 if (-not (Test-Path $resultpath)) { New-Item -ItemType Directory -Path $resultpath | Out-Null } # 检测长路径文件并按所有者生成报告 Get-ChildItem -Path $testpath -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.FullName.Length -gt $limit } | Select-Object FullName, @{n="Owner";e={ $_.GetAccessControl().GetOwner([System.Security.Principal.NTAccount]) }}, @{n="NameLength"; e={$_.FullName.Length}} | ForEach-Object { $ownerFileName = "Longfiles of $($_.Owner -replace "\\","-").txt" $outputPath = Join-Path $resultpath $ownerFileName "$($_.NameLength) - $($_.FullName)" | Out-File -FilePath $outputPath -Append -Encoding utf8 } # 获取凭据(Office365需要验证,第一次运行会提示输入,后续可以存储凭据) $credential = Get-Credential -Message "Enter your Office365 email credentials" -UserName $from # 发送邮件给所有者或管理员 Get-ChildItem $resultpath -Filter "Longfiles of *.txt" -ErrorAction SilentlyContinue | ForEach-Object { if ($_.Name -match 'Longfiles of (.+)\.txt') { $user = $matches[1] -replace "-","\" try { # 用Get-ADUser更可靠(需要安装RSAT Active Directory模块) $adUser = Get-ADUser -Filter { Name -eq $user.Split("\")[1] } -Properties EmailAddress -ErrorAction Stop $email = $adUser.EmailAddress } catch { # 如果Get-ADUser失败,尝试用ADSI回退 try { $ntacc = New-Object System.Security.Principal.NTAccount($user) $sid = $ntacc.Translate([System.Security.Principal.SecurityIdentifier]) $aduser = [ADSI]"LDAP://<SID=$sid>" $email = $aduser.Properties.mail.Value } catch { Write-Warning "Failed to get email for user $user : $_" $email = $null } } if ($email) { try { Send-MailMessage -Attachments $_.FullName ` -Body "Please change the filenames of the files listed in the attached file to shorter!" ` -From $from ` -SmtpServer $smtpserver ` -Port $smtpPort ` -UseSsl ` -Credential $credential ` -Subject "System notice: Long file paths detected" ` -To $email ` -Cc $admins ` -ErrorAction Stop Write-Host "Email sent successfully to $email" } catch { Write-Error "Failed to send email to $email : $_" # 发送失败时通知管理员 Send-MailMessage -Attachments $_.FullName ` -Body "Failed to send long file path notice to $user. Error: $_`n`nAttached are the affected files." ` -From $from ` -SmtpServer $smtpserver ` -Port $smtpPort ` -UseSsl ` -Credential $credential ` -Subject "System notice: Email delivery failed" ` -To $admins ` -ErrorAction Stop } } else { Send-MailMessage -Attachments $_.FullName ` -Body "Could not find email address for file owner $user. Attached are the long file paths detected." ` -From $from ` -SmtpServer $smtpserver ` -Port $smtpPort ` -UseSsl ` -Credential $credential ` -Subject "System notice: No email found for owner" ` -To $admins ` -ErrorAction Stop Write-Host "No email found for $user, notified admins instead" } } else { Write-Warning "Invalid report file name: $_" } }
关键修改说明
- Office365 SMTP配置:添加了
-Port 587和-UseSsl参数,这是Office365 SMTP的强制要求;同时加入了-Credential参数,解决系统重复提示输入的问题(第一次运行会要求输入密码,你也可以用Export-Clixml存储凭据实现自动登录) - UNC路径支持:把
$testpath改成了UNC路径示例,你可以直接替换成目标共享路径 - 可靠的AD用户查询:优先用
Get-ADUser获取邮箱(需要安装RSAT Active Directory模块,如果没有的话会自动回退到ADSI方式),减少邮箱获取失败的概率 - 错误处理:添加了
try/catch块捕获邮件发送和用户查询的异常,避免脚本崩溃,同时把错误信息通知管理员 - 编码优化:给
Out-File加上了-Encoding utf8,避免中文文件名或路径出现乱码
注意事项
- 如果你要自动运行脚本,可以用
Get-Credential | Export-Clixml -Path "C:\scripts\o365cred.xml"存储凭据,然后用$credential = Import-Clixml -Path "C:\scripts\o365cred.xml"加载,避免每次手动输入 - 确保运行脚本的账号有权限访问目标UNC路径,以及读取AD用户信息的权限
- Office365账号可能需要启用“允许应用使用密码登录”(如果是MFA账号,需要创建应用密码)
内容的提问来源于stack exchange,提问作者user2602460
相关产品推荐
相关产品推荐

