我发现了一种丑陋的方法,但至少它不需要在 VM 主机上安装或配置任何东西。
首先,我有一个名为winexe的实用程序,它可以让您打开与 Windows 机器的终端连接。
然后我写了一个很长的丑陋的 Perl 脚本,将一些 PowerShell 代码通过管道传输到机器以暂停任何正在运行的机器:
sub hv_suspend_host {
my $host = $_[0];
my $code = <<'END';
echo '===BEGIN'
$query = "SELECT * FROM Msvm_ComputerSystem WHERE EnabledState != 3 AND EnabledState != 32769" #Exclude off and saved VMs
$VMs = get-wmiobject -query $query -namespace "root\virtualization" -computername "."
foreach ($VM in $VMs) {
if ($VM.name -ne $VM.ElementName) { # Exclude the host itself
if ($VM.RequestStateChange(32769).ReturnValue -eq 4096) { # Put the VM in a saved state
# It worked, log success
} else {
# It didn't, log failure
}
}
}
echo '===END'
exit
END
my $recv;
run(["winexe", '-U', "DOMAIN/$win_user%$win_pass", '--interactive=0', "//$host", 'powershell -command -'], \$code, \$recv);
$recv =~ tr/\r//d; # Convert to UNIX line endings
$recv =~ /===BEGIN\n(.+)===END/s; # Now recv contains anything you logged
}
您可能需要稍微处理一下才能使其正常工作。我不得不修改一些特定于实现的东西,但我留下了部分输出捕获代码。这需要名为 $win_user 和 $win_pass 的全局变量,其中包含目标 VM 主机的管理员帐户登录信息。它还要求您use IPC::Run
.