解决方案

解决方案

我有一台运行 Hyper-V 的 Windows Server 2019 工作站,配有 Ubuntu 20.04 VM。我可以ssh远程进入 VM,因此我很少登录主机操作系统。

因此(除非我完全禁用睡眠功能),Windows 会在一段时间后让工作站进入睡眠状态,不管客户虚拟机的状态。理想情况下,工作站应该仅在以下情况下进入睡眠状态:

  1. 主机操作系统已处于非活动状态X分钟,
  2. 没有任何客户虚拟机正在运行。

但是,我在 Windows 的控制面板中以及 Hyper-V 的设置中找不到与此问题相关的任何内容。

有什么方法可以实现这个目的吗?

答案1

这可以通过组合 Windows 中的几个内置工具来实现。您需要:

  1. 两种电力计划
    • 妨碍睡眠
    • 另一个可以让人睡觉
  2. PowerShell 脚本
  3. 计划任务

该解决方案已经过测试,目前正在我的 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 上使用它失败,没有激活方法错误关联

相关内容