如何将PowerShell循环结果存入变量并通过SMTP发送邮件?
嘿,我帮你捋清楚这个问题!你现在的核心问题是直接把WMI查询返回的PowerShell对象塞进了$message变量,SMTP发送邮件时没法把这些对象自动转换成可读的文本内容。下面给你两种可行的解决方案,还有一些关键的细节处理:
问题分析
你原代码里的$message = foreach(...) { Get-WmiObject ... }得到的是一堆Win32_Processor对象的集合,直接把这个集合作为邮件正文的话,SMTP客户端只会输出对象的类型名称,完全看不到实际的服务器和负载数据。我们需要先把这些对象转换成可读的文本或HTML格式,再塞进邮件里。
解决方案1:纯文本格式邮件(简单直接)
这个方案会把查询结果转换成格式化的纯文本表格,适合快速查看:
# 读取服务器列表 $Servers = Get-Content C:\Server\server.txt # 邮件基础配置 $To = "test@test.com" $From = "test@test.com" $SMTPserver = "mail.mail.com" $Subject = "Server CPU Load Status Report" # 循环获取服务器CPU负载,同时处理连接失败的情况 $reportContent = foreach ($server in $Servers) { try { # 尝试连接服务器并获取CPU负载 Get-WmiObject Win32_Processor -ComputerName $server -ErrorAction Stop | Select-Object SystemName, LoadPercentage } catch { # 如果连接失败,返回自定义的错误信息 [PSCustomObject]@{ SystemName = $server LoadPercentage = "连接失败:$($_.Exception.Message)" } } } | Out-String # 把对象集合转换成格式化的纯文本 # 构建完整的邮件对象 $mailMessage = New-Object System.Net.Mail.MailMessage($From, $To) $mailMessage.Subject = $Subject $mailMessage.Body = $reportContent $mailMessage.BodyEncoding = [System.Text.Encoding]::UTF8 # 避免中文乱码 # 初始化SMTP客户端并发送邮件 $smtpClient = New-Object System.Net.Mail.SmtpClient($SMTPserver) # 如果你的SMTP服务器需要身份验证,取消下面注释并填写信息 # $smtpClient.Credentials = New-Object System.Net.NetworkCredential("你的用户名", "你的密码") # $smtpClient.Port = 587 # 常用TLS端口,根据服务器要求调整 # $smtpClient.EnableSsl = $true # 服务器要求SSL/TLS时启用 try { $smtpClient.Send($mailMessage) Write-Host "邮件发送成功!" } catch { Write-Host "邮件发送失败:$($_.Exception.Message)" }
解决方案2:HTML格式邮件(更美观易读)
如果想要更美观的排版,比如带样式的表格,可以生成HTML格式的邮件:
# 读取服务器列表 $Servers = Get-Content C:\Server\server.txt # 邮件基础配置 $To = "test@test.com" $From = "test@test.com" $SMTPserver = "mail.mail.com" $Subject = "Server CPU Load Status Report" # 生成HTML格式的报告内容 $reportContent = foreach ($server in $Servers) { try { Get-WmiObject Win32_Processor -ComputerName $server -ErrorAction Stop | Select-Object SystemName, LoadPercentage } catch { [PSCustomObject]@{ SystemName = $server LoadPercentage = "连接失败:$($_.Exception.Message)" } } } | ConvertTo-Html -Title "服务器CPU负载报告" -Body "<h2>服务器CPU负载统计</h2>" | Out-String # 构建HTML邮件对象 $mailMessage = New-Object System.Net.Mail.MailMessage($From, $To) $mailMessage.Subject = $Subject $mailMessage.Body = $reportContent $mailMessage.BodyEncoding = [System.Text.Encoding]::UTF8 $mailMessage.IsBodyHtml = $true # 标记邮件正文为HTML格式 # 初始化SMTP客户端并发送(同上,需要验证的话取消对应注释) $smtpClient = New-Object System.Net.Mail.SmtpClient($SMTPserver) try { $smtpClient.Send($mailMessage) Write-Host "HTML邮件发送成功!" } catch { Write-Host "邮件发送失败:$($_.Exception.Message)" }
关键注意事项
- 错误处理:加入
try/catch是为了避免某个服务器离线/无法连接时,整个脚本直接崩溃,而是把错误信息写入报告。 - SMTP配置:如果你的邮件服务器需要身份验证(比如大多数企业邮箱、公共邮箱),必须填写
Credentials、Port和EnableSsl参数,否则会发送失败。 - 编码问题:设置
BodyEncoding = UTF8可以避免邮件正文出现乱码,尤其是包含中文的时候。
内容的提问来源于stack exchange,提问作者user2363377
相关产品推荐
相关产品推荐

