PowerShell脚本问题排查:VM开机后重复发报告无法退出循环
问题排查与修正
核心问题分析
- 逻辑完全倒置:本该在VM未开机时循环等待检查,结果写成了开机后进入死循环
while ($true)无退出条件:一旦进入就会无限重复发送报告,无法终止Start-Sleep位置错误:放在while循环外部,完全起不到间隔检查的作用- 变量拼写错误:
$postcheckreportame少了字母r,会导致文件路径无效
修正后的逻辑实现
预期逻辑:
- 先检查VM状态
- 若已开机:执行一次报告,直接进入后续步骤
- 若未开机:每15分钟检查一次状态,直到开机后执行报告再退出
修正后的完整脚本
# 定义检查间隔(15分钟=900秒) $interval = 900 $postCheckReportName = "你的报告文件名" # 修正原变量拼写错误 # 循环检查VM状态,直到开机 while ($getvm.PowerState -ne "PoweredOn") { Write-Host "VM未开机,等待$($interval/60)分钟后再次检查..." Start-Sleep -Seconds $interval # 重新获取VM状态,避免缓存导致判断失效 $getvm = Get-VM -Name $getvm.Name } # 当VM开机后,执行一次报告生成与发送 $servername = $getvm.Name $osversion = $getvm.ExtensionData.Guest.GuestFullName $vmhost = $getvm.VMHost.Name $vmdatacenter = $vmhost.Substring(0, 4).ToUpper() $datacenter = Get-Datacenter -VM $getvm | Select-Object -ExpandProperty Name $Cluster = Get-Cluster -VM $getvm | Select-Object -ExpandProperty Name $vCPU = [int]$getvm.NumCpu $RAM = [int]$getvm.MemoryGB $vmnetwork = (Get-NetworkAdapter $getvm).Name $networkNames = [string]::Join(';', $vmnetwork) $details = [pscustomobject]@{ ServerName = $servername; 'OS Version' = $osversion; DataCenter = $vmdatacenter; Cluster = $Cluster; vCPU = $vCPU; RAM = $RAM; Network = $networkNames } # 简化CSV生成逻辑,直接导出对象 $details | Export-Csv -Path "$postCheckReportName.csv" -NoTypeInformation -Append $fromEmail = "你的发件邮箱" $smtpServer = "你的SMTP服务器地址" $toEmail = "收件邮箱" $toCCmail1 = "抄送邮箱" $body = @" <html> Hi Team, <br /><br /> ***This is an auto-generated email. Please do not respond*** </html> "@ # 启用邮件发送请取消注释,添加-BodyAsHtml确保HTML格式生效 # Send-MailMessage -From $fromEmail -To $toEmail -Cc $toCCmail1 -SmtpServer $smtpServer -Body $body -Subject "PostCheck report for $servername" -BodyAsHtml Write-Host "报告已生成,进入后续步骤..." # 此处添加后续执行的代码
关键改动说明
- 逻辑反转:将循环放在未开机的分支,开机后直接执行一次报告
- 状态刷新:每次循环重新获取VM状态,避免使用旧缓存值导致判断错误
- CSV生成优化:用
Export-Csv直接导出对象,替代原复杂的键值对转换逻辑 - 变量修正:修复原脚本中报告文件名的拼写错误
- 邮件优化:添加
-BodyAsHtml参数确保HTML格式的邮件正文正常显示
内容的提问来源于stack exchange,提问作者snehasish nandy
相关产品推荐
相关产品推荐

