开发者

How can I suspend a Hyper-V VM from a linux machine?

开发者 https://www.devze.com 2023-03-19 23:23 出处:网络
I\'ve set up an NMS system on a machine running Ubuntu that responds to various UPS events by calling a Perl script to go through all of our VMWare hosts and suspend all of the VMs. VMWare was smart a

I've set up an NMS system on a machine running Ubuntu that responds to various UPS events by calling a Perl script to go through all of our VMWare hosts and suspend all of the VMs. VMWare was smart and provided a set of Perl modules which made this relatively easy. We also have three Hyper-V hosts, however, and I can't seem to find a way to control them that isn't specific to some Microsoft technology (e.g. a PowerShell script).

I'm hoping somebody could suggest a way to control the Hyper-V hosts from a linux box. I'd rather it di开发者_Go百科dn't involve using Wine, but I'm willing to go that route if there's nothing else that will work.


I found an ugly way to do it, but at least it doesn't require anything to be installed or configured on the VM host.

First I got a utility called winexe, which lets you open a terminal connection to a windows machine.

Then I wrote a long an ugly Perl script to pipe some PowerShell code to the machine to suspend any running machines:

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
}

You might have to mess with this a bit to get it to work. I had to hack out some of the implementation-specific things, but I left in part of the output capturing code. This requires global variables named $win_user and $win_pass containing administrator account login info for the target VM host. It also requires that you use IPC::Run.


Hyper-V can be managed remotely using the WMI interfaces. There is a WMI Client for Linux, which should allow you to make the relevant API calls to manage Hyper-V. I have not had to do this myself, but the specific WMI calls are available at Microsoft: https://msdn.microsoft.com/en-us/library/hh850319%28v=vs.85%29.aspx

0

精彩评论

暂无评论...
验证码 换一张
取 消