我有一台运行 Hyper-V 的 Windows Server 2019 工作站,配有 Ubuntu 20.04 VM。我可以ssh
远程进入 VM,因此我很少登录主机操作系统。
因此(除非我完全禁用睡眠功能),Windows 会在一段时间后让工作站进入睡眠状态,不管客户虚拟机的状态。理想情况下,工作站应该仅在以下情况下进入睡眠状态:
- 主机操作系统已处于非活动状态X分钟,和
- 没有任何客户虚拟机正在运行。
但是,我在 Windows 的控制面板中以及 Hyper-V 的设置中找不到与此问题相关的任何内容。
有什么方法可以实现这个目的吗?
答案1
这可以通过组合 Windows 中的几个内置工具来实现。您需要:
- 两种电力计划
- 妨碍睡眠
- 另一个可以让人睡觉
- PowerShell 脚本
- 计划任务
该解决方案已经过测试,目前正在我的 Microsoft Windows 11 Enterprise build 22621 上使用。对我来说非常有效,但您的情况可能会有所不同。
解决方案
电源计划
在主机中创建两个电源计划。将其命名为始终开启和均衡。分别配置它们。第二个可能已经存在。这些名称在以下脚本中是硬编码的,因此,如果您选择其他名称,则必须在下一步中相应地编辑脚本。
Powershell 脚本
接下来,将此 PowerShell 代码粘贴到名为Hyper-V-PowerPlan.ps1在你的视窗目录。如果您想选择其他目录或文件名,则必须在最后一步相应地调整路径。
# Hyper-V-PowerPlan.ps1
Import-Module Hyper-V
# 'Off', 'Saved', 'OffCritical', 'SavedCritical'
$offstates = [Microsoft.HyperV.PowerShell.VMState[]](3, 6, 32786, 32788)
if ($(@(Get-VM).ForEach({$_.State -in $offstates})) -contains $false) {
$desired = 'Always on'
} else {
$desired = 'Balanced'
}
$plans = Get-CimInstance -Namespace ROOT\cimv2\power -ClassName Win32_PowerPlan |
Group-Object -Property ElementName -AsHashTable -AsString
if ($plans.ContainsKey($desired) -and -not $plans[$desired][0].IsActive) {
$plans[$desired] | Invoke-CimMethod -MethodName Activate
}
计划任务
最后,使用以下命令创建新的计划任务创建任务...菜单选项(不要选择基本版本)并输入以下设置:
一般的标签
- 运行任务时,使用以下用户帐户:系统
- 以最高权限运行:[已检查]
触发器标签
- 创建新触发器
- 开始任务:在一次活动中
- 日志:Microsoft-Windows-Hyper-V-Worker/Admin
- 来源:Hyperver-V-Worker 简介
- 事件 ID:(留空)
- 已启用:[已检查]
操作标签
- 创建新动作
- 操作:启动程序
- 程序/脚本:%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\powershell.exe
- 添加参数(可选):-NoProfile -NonInteractive -ExecutionPolicy 绕过 -文件“%SYSTEMROOT%\Hyper-V-PowerPlan.ps1”
设置标签
- 以下两项是可选的:
- 如果任务运行时间超过以下时间则停止任务:1分钟(您必须手动输入“分钟”)
- 如果正在运行的任务没有在请求时结束,则强制其停止:[已检查]
- 如果任务已在运行,则适用以下规则:将新实例加入队列
保存计划任务,您就大功告成了!每当您运行虚拟机时,主机的电源计划都会自动切换到防止其休眠的电源计划,并在最后一个虚拟机关闭时恢复平衡。
这一切是如何运作的
当您在 Hyper-V 上的虚拟机上启动、停止或执行其他操作时,事件会被写入Microsoft-Windows-Hyper-V-Worker/Admin事件日志。每次发生这种情况时,您创建的计划任务都会收到有关该事件的通知,并触发计划任务操作。该操作将运行您创建的 PowerShell 脚本。
脚本通过枚举主机上找到的所有虚拟机来工作。如果任何虚拟机处于以下状态以外“Off”、“Saved”、“OffCritical”、“SavedCritical”,则主机的所需电源计划名称设置为“Always on”。否则设置为“Balanced”。确定所需电源计划名称后,将枚举主机上找到的所有电源计划。如果当前活动的电源计划名称与所需名称不同,并且找到了具有所需名称的电源计划,则Activate
调用所需电源计划对象的 CIM 实例方法。这相当于您手动切换电源计划。
答案2
Invoke-CimMethod
将导致 Win10 21H2 上出现错误。
Invoke-CimMethod : This method is not implemented in any class
At C:\Scripts\Hyper-V-PowerPlan.ps1:13 char:24
+ $plans[$desired] | Invoke-CimMethod -MethodName Activate
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : MetadataError: (Win32_PowerPlan...d-445e-4ebe...):CimInstance) [Invoke-CimMethod], CimException
+ FullyQualifiedErrorId : HRESULT 0x80041055,Microsoft.Management.Infrastructure.CimCmdlets.InvokeCimMethodCommand
来源:xPowerPlan:尝试在 Windows 10 上使用它失败,没有激活方法错误关联