PowerShell实现宿主机重启后按CSV记录的VM状态启停虚拟机
最简实现方案
你要的功能Hyper-V本身就带原生支持,根本不用自己写脚本采集状态:
- 打开Hyper-V管理器,右键需要配置的虚拟机进入「设置」
- 找到左侧「管理」分类下的「自动启动操作」
- 选择选项 如果服务停止时虚拟机正在运行,则自动启动它,保存配置即可。
这个选项开启后,Hyper-V服务会自己记录每个VM的运行状态:宿主机重启前正常运行的VM会在开机后自动拉起,你手动关停的VM重启后会保持停止状态,完全匹配你的需求。唯一的不足是宿主机异常断电崩溃的场景下,状态记录可能偶发不准,如果你需要更高的可控性,可以用下面的自定义脚本方案,和你最初的思路完全兼容。
自定义脚本方案(可控性更高)
你原来的定时采集CSV的逻辑完全可行,建议把采集触发时机从每12小时轮询改成宿主机正常关机时触发,能彻底避免采集间隔内手动操作VM导致状态记录不准的问题。
1. 状态采集脚本
将以下内容保存为D:\Hyper-V_Scripts\Save-VMStatus.ps1:
$storagePath = "D:\Hyper-V_Scripts\vm_status.csv" # 自动创建存储目录,避免路径不存在报错 if (-not (Test-Path (Split-Path $storagePath -Parent))) { New-Item -ItemType Directory -Path (Split-Path $storagePath -Parent) -Force | Out-Null } # 导出VM状态,指定UTF8编码避免中文VM名乱码 Get-VM | Select-Object VMName, State, Uptime | Export-Csv -Path $storagePath -NoTypeInformation -Encoding UTF8
如果担心异常关机没触发采集,可以额外给这个脚本加个每1小时执行一次的定时规则,对系统资源几乎无影响,做双重保险。
2. 开机恢复脚本
将以下内容保存为D:\Hyper-V_Scripts\Restore-VMStatus.ps1:
$statusFile = "D:\Hyper-V_Scripts\vm_status.csv" # 状态文件不存在直接退出,不执行任何操作 if (-not (Test-Path $statusFile)) { exit 0 } $recordedVMs = Import-Csv -Path $statusFile foreach ($vm in $recordedVMs) { # 跳过已经被删除的VM,避免报错 $existVM = Get-VM -Name $vm.VMName -ErrorAction SilentlyContinue if (-not $existVM) { continue } # 仅当记录状态为Running、且当前VM处于停止状态时,执行启动操作 if ($vm.State -eq "Running" -and $existVM.State -eq "Off") { Start-VM -Name $existVM.Name } }
3. 任务计划配置
打开系统任务计划程序,创建2个勾选「使用最高权限运行」的任务:
- 状态采集任务:触发条件选择「事件触发」,事件来源选
User32,事件ID填1074(对应系统正常发起关机/重启的系统事件),操作选择启动程序,程序路径填powershell.exe,添加参数为-ExecutionPolicy Bypass -File "D:\Hyper-V_Scripts\Save-VMStatus.ps1" - 状态恢复任务:触发条件选择「计算机启动时」,可设置30秒延迟触发(等Hyper-V相关服务完全启动),操作同样启动
powershell.exe,参数为-ExecutionPolicy Bypass -File "D:\Hyper-V_Scripts\Restore-VMStatus.ps1"
内容的提问来源于stack exchange,提问作者Chris Giles
相关产品推荐
相关产品推荐

