VMware

This Question is Answered

18 Replies Last post: Oct 10, 2009 10:35 AM by heyitspablo   1 2 Previous Next

Shutting down VMs on a host in some type of order posted: Jun 29, 2009 2:41 PM

Click to view caffine4lovers's profile Novice 12 posts since
Jun 23, 2009

I am trying to write a shutdown script in perl (new to perl
programming) my modifying the ghettoshudown script. What it does so far
is shutdown or suspend all virtual machines
on a host, but it does not shut them
down in a specific order (which is the end goal). Is there anyway to do
this in perl, possibly using an external file. Any help would be
greatly appreciated.
I have attached what I have thus far.
Attachments:
Click to view stumpr's profile Expert 451 posts since
Sep 26, 2007
You could add another option to the script for a text file, then just read it in by line and power off Virtual Machines in order. You'll have to change the logic of the script (I would probably just write another one to its not cluttered).

Did you mean in order of the host or of the VM? You could do both. Did you want a sample or were you looking just to get some inspiration to DIY?
Click to view stumpr's profile Expert 451 posts since
Sep 26, 2007
Well, nesting the order of hosts and their VMs would be a bit more work. But you can easily do a text file ordered shutdown of virtual machines.


#!/usr/bin/perl

use strict;
use warnings;

use VMware::VIRuntime;

my %opts = (
	vmfile => {
		type => "-s",
		variable => "VMFILE",
		help => "Path to file containing list of virtual machines, one per line, for ordered shutdown",
		required => 1,
	},
	
);


Opts::add_options(%opts);
Opts::parse;
Opts::validate();

my ($vm_view, $vm_name, @vm_list, $vm_file);

$vm_file = Opts::get_option('vmfile');
open (VMFILE, $vm_file) or die "Failed to open file, '$vm_file'";
@vm_list = <VMFILE>;
close(VMFILE);

Util::connect();

foreach $vm_name ( @vm_list ) {
	chomp ($vm_name);
	
	$vm_view = Vim::find_entity_view(
		view_type => "VirtualMachine",
		filter => "$vm_name",
		properties => \[ 'name' ], # remove backslash before '[', forum mangles this line without it.
	);
	
	unless( defined $vm_view ) { 
		warn "Unable to find virtual machine, '$vm_name'"; 
		next;
	}
	
	eval {
		$vm_view->PowerOffVM_Task();
	};
	
	if ($@) {
		print "Virtual Machine PowerOffVM_Task Error for $vm_name:\n$@ . "\n";
	}
	
}



So I just typed this out, no error checking or a run. Don't shoot me if it throws any errors. But it gives you an idea of how it would work. You can get as fancy or as simple as you like. For example, you could try to do a ShutdownGuest_Task first, if that fails, then retry with a PowerOffVM_Task. That way if the tools are installed and the guest can shutdown cleanly it will, if not, it'll just power it off forcibly.
Click to view stumpr's profile Expert 451 posts since
Sep 26, 2007
I should have explained that. VMware uses the Opts:: functions so you can add your own command line arguments.

If you run your script with --help it'll display the default perl toolkit arguments as well as any you add yourself, in this case VMFILE. Just add a parameter to your script --vmfile <file path>.
Click to view stumpr's profile Expert 451 posts since
Sep 26, 2007
What line number did it complain on?
Click to view stumpr's profile Expert 451 posts since
Sep 26, 2007
Can you paste the entire error as you see it? 985 must be falling into the VMware modules.
Click to view stumpr's profile Expert 451 posts since
Sep 26, 2007
Oh, can't believe I missed that. Sorry, stupid error on my side.
#!/usr/bin/perl

use strict;
use warnings;

use VMware::VIRuntime;

my %opts = (
	vmfile => {
		type => "-s",
		variable => "VMFILE",
		help => "Path to file containing list of virtual machines, one per line, for ordered shutdown",
		required => 1,
	},
	
);


Opts::add_options(%opts);
Opts::parse;
Opts::validate();

my ($vm_view, $vm_name, @vm_list, $vm_file);

$vm_file = Opts::get_option('vmfile');
open (VMFILE, $vm_file) or die "Failed to open file, '$vm_file'";
@vm_list = <VMFILE>;
close(VMFILE);

Util::connect();

foreach $vm_name ( @vm_list ) {
	chomp ($vm_name);
	
	$vm_view = Vim::find_entity_view(
		view_type => "VirtualMachine",
		filter => { 'name' => $vm_name },
		properties => \[ 'name' ], # remove backslash before '[', forum mangles this line without it.
	);
	
	unless( defined $vm_view ) { 
		warn "Unable to find virtual machine, '$vm_name'"; 
		next;
	}
	
	eval {
		$vm_view->PowerOffVM_Task();
	};
	
	if ($@) {
		print "Virtual Machine PowerOffVM_Task Error for $vm_name:\n$@ . "\n";
	}
	
}


Note the line filter => { 'name' => $vm_name }, for changes.
Click to view EXPRESS's profile Hot Shot 152 posts since
Dec 13, 2006
Hi All,

I like that. How can I apply that so it can work for me? I am not a programmer or developer so that should tell you that I don't know much about scripting, but I think I can play around with it enough to get it going. What I would like to do is a weekly ShutDown then a PowerOn afterwards. Any chance you guys can help me with this? Any help would be appreciated. The way I am doing it right now which is so time consuming is to setup a schedule task for each VM via Virtual Center for ShutDown then again for PowerOn. I just would like to simplify this as much as possible.

I just want to add that we are on an ESX 3.5.0 server and 2.5 VC.

Again any help will be appreciated.

Thank you,
Express

Developer Social Media

Communities