如何扩展PowerCLI脚本以获取已关机VM的关机日期?
扩展PowerCLI脚本以显示VM关机日期及时长
要实现这个需求,我们可以利用VMware PowerCLI访问VM的底层API属性获取关机时间,再通过PowerShell的日期计算功能得出关机时长。这里给你几个实用的实现方案:
基础扩展脚本
直接在原有脚本基础上添加关机时间和时长的计算逻辑,这是最直接的实现方式:
# 定义目标主机列表,支持多个主机逗号分隔 $targetHosts = "host1.domain.com", "host2.domain.com" # 获取指定主机上已关机的VM,并返回关机日期和时长 Get-VM -Location $targetHosts | Where-Object {$_.PowerState -eq "PoweredOff"} | Select-Object Name, PowerState, @{Label="关机日期"; Expression={$_.ExtensionData.Runtime.PowerOffTime}}, @{Label="关机时长"; Expression={ # 判断是否存在关机时间(避免从未开机的VM报错) if ($_.ExtensionData.Runtime.PowerOffTime) { (Get-Date) - $_.ExtensionData.Runtime.PowerOffTime } else { "未知(该VM可能从未开机)" } }}
关键细节说明:
$_.ExtensionData.Runtime.PowerOffTime:这是VMware vSphere API提供的原生属性,直接存储VM的精准关机时间戳,比任何间接推算的方法都可靠。- 关机时长计算:通过
(Get-Date) - 关机时间得到时间跨度对象,PowerShell会自动将其格式化为X天Y小时Z分钟的易读形式。 - 空值判断:如果VM是新建后从未开机的,
PowerOffTime会返回null,添加这个判断可以避免出现无效结果或报错。
优化:自定义友好格式显示
如果你希望结果更简洁直观,可以调整表达式,把日期和时长转换成更规整的格式:
$targetHosts = "host1.domain.com", "host2.domain.com" Get-VM -Location $targetHosts | Where-Object {$_.PowerState -eq "PoweredOff"} | Select-Object Name, PowerState, @{Label="关机日期"; Expression={$_.ExtensionData.Runtime.PowerOffTime.ToString("yyyy-MM-dd HH:mm:ss")}}, @{Label="关机时长"; Expression={ if ($_.ExtensionData.Runtime.PowerOffTime) { $duration = (Get-Date) - $_.ExtensionData.Runtime.PowerOffTime "{0}天 {1}小时 {2}分钟" -f $duration.Days, $duration.Hours, $duration.Minutes } else { "未知(从未开机)" } }}
这个版本会把关机日期统一格式化为2024-05-20 14:30:00,时长也更符合日常阅读习惯。
可选:导出结果到CSV文件
如果需要把结果保存下来用于后续分析,可以在脚本末尾添加导出逻辑:
$targetHosts = "host1.domain.com", "host2.domain.com" $outputPath = "C:\temp\ShutdownVMs.csv" Get-VM -Location $targetHosts | Where-Object {$_.PowerState -eq "PoweredOff"} | Select-Object Name, PowerState, @{Label="关机日期"; Expression={$_.ExtensionData.Runtime.PowerOffTime.ToString("yyyy-MM-dd HH:mm:ss")}}, @{Label="关机时长"; Expression={ if ($_.ExtensionData.Runtime.PowerOffTime) { $duration = (Get-Date) - $_.ExtensionData.Runtime.PowerOffTime "{0}天 {1}小时 {2}分钟" -f $duration.Days, $duration.Hours, $duration.Minutes } else { "未知(从未开机)" } }} | Export-Csv -Path $outputPath -NoTypeInformation -Encoding UTF8
执行后就能把结果导出到指定路径的CSV文件,方便用表格工具打开查看。
内容的提问来源于stack exchange,提问作者aztech




