VMware {code} Community
markvr80
Enthusiast
Enthusiast

Listing all VMs in a folder

Hi, I'm trying to power cycle all the VMs in a particular folder on a schedule. I'm trying to use PHP and the web service to do this but run into problems. Firstly, is there an easier way of doing it without learning Perl? (I'm trying to use PHP which I know).

I've got as far as logging in and being able to return a specific VM, but can't find a way of returning all the VMs in a folder, and then iterating through them.

The code I currently have is (note, this might get edited by the forum software so see attached file):

unset($soapmsg);

$soapmsg=new soapval('_this','SearchIndex','SearchIndex');

$soapmsg='Estates/vm/Servers/buar-srv001';

$result= $c->call("FindByInventoryPath",$soapmsg,$namespace);

I've been using the SDK docs and the MOB at but just can't work out how to iterate through a folder. Using the MOB to browse will list the VMs in a folder OK but I can find what SDK method will return these.

Any advice would be much appreciated!!!!

mark

Reply
0 Kudos
5 Replies
stumpr
Virtuoso
Virtuoso

Mark,

You would probably want to look at RetrieveProperties and traversal specs. The idea would be to get a Managed Object Reference to the starting folder, then do a RetrieveProperties for all Virtual Machines that exist as children of that folder or any sub-folders (or other managed objects).

Since you're using PHP, probably won't find a concrete PHP example but you should be able to convert a C++/Java/C# example from a lot of the forum posts.

                FolderTraversalSelectionSpec.name = new string("FolderTraversalSpec");
		 
		FolderTraversalSpec.name = new string("FolderTraversalSpec");
		FolderTraversalSpec.type = "Folder";
		FolderTraversalSpec.path = "childEntity";
		FolderTraversalSpec.skip = &xsd_true;

		FolderTraversalSpec.selectSet.push_back(&FolderTraversalSelectionSpec);
		
		PropertySpec.type = "VirtualMachine";
		PropertySpec.all = &xsd_false;
		PropertySpec.pathSet.push_back("name");
		
		ObjectSpec.obj = <managed object reference of your folder from FindByInventoryPath>;
		ObjectSpec.skip = &xsd_true;
		
		ObjectSpec.selectSet.push_back(&FolderTraversalSpec);

		PropertyFilterSpec.propSet.push_back(&PropertySpec);
		PropertyFilterSpec.objectSet.push_back(&ObjectSpec);
		

		RetrievePropertiesReq._USCOREthis = ServiceContent->propertyCollector;
		RetrievePropertiesReq.specSet.push_back(&PropertyFilterSpec);

Assuming your starting folder in ObjectSpec.obj was a vmFolder subfolder, should work (I'd have to check my TraversalSpec logic in a bit more detail to be confident).

As usual some work might be needed to get the PHP soap constructed to match the VIM objects from the snippet above. Then you'll make your RetrieveProperties call and get your array of results (objects with properties, in this case just the "name" property).

Reuben Stump | http://www.virtuin.com | @ReubenStump
markvr80
Enthusiast
Enthusiast

Thanks for the reply stumpr, I'm really struggling with the web services interface. I'm mainly a sysadmin, not a programmer and decided it was just too full on!!

So I'm trying the Perl SDK instead as it seems much simpler, although still struggling! All I'm trying to do is powercycle all the VMs in a particular folder. This is for a VDI deployment where the VMs are set to suspend when not in use, so they need to reboot automatically overnight so windows updates can take affect.

The Perl script I have now is:

use strict;
use warnings;

use VMware::VIRuntime;

# read/validate options and connect to the server
Opts::parse();
Opts::validate();
Util::connect();

my $folders =
    Vim::find_entity_views(view_type => 'Folder',
                           filter => { 'name' => qr/Desktops - Test/ });

foreach (@$folders) {      
   print $_->name . "\n";
}


my $vm_views =
    Vim::find_entity_views(view_type => 'VirtualMachine',
    						begin_entity => $folders 
                           );

foreach (@$vm_views) {      
   print $_->name . ": " . $_->config->guestFullName . "\n";
}



# disconnect from the server
Util::disconnect();                                  

which returns:

Desktops - Test
Can't call method "serialize" on unblessed reference at C:/Program Files/VMware/
VMware vSphere CLI/Perl/lib/VMware/VICommon.pm line 2116, <STDIN> line 2.

End Disconnect

What have I missed??

Reply
0 Kudos
lamw
Community Manager
Community Manager

You may want to take a look at this script: and you can easily modify for what you need to specify a specific folder from the command line.

=========================================================================

William Lam

VMware vExpert 2009

VMware ESX/ESXi scripts and resources at:

VMware Code Central - Scripts/Sample code for Developers and Administrators

If you find this information useful, please award points for "correct" or "helpful".

markvr80
Enthusiast
Enthusiast

I've finally got a script together that does most of what I want, for anybody else out there this may help :smileycool:

#!/usr/bin/perl -w
use strict;
use warnings;
use VMware::VIRuntime;

Opts::parse();
Opts::validate();

Util::connect();

my ($mo,$vm_view,$folder);


my $folder_views = Vim::find_entity_views(view_type => 'Folder',
                  				         filter => { 'name' => qr/Desktops - Test/ });

#Dirty bodge but I don't know how to do it better... 
foreach (@$folder_views) {      
   $folder = $_;
}


foreach $mo ( @{$folder->childEntity} ) {
	my $vm_view = Vim::get_view(mo_ref => $mo);

	print "Virtual Machine: " . $vm_view->name . " - " . $vm_view->runtime->powerState->val . "\n" ;

	if($vm_view->runtime->powerState->val eq 'suspended'){
		print "Powering on...\n";
		$vm_view -> PowerOnVM();
     }
}

Util::disconnect();
 

Reply
0 Kudos
cesarcesar
Contributor
Contributor

@, good job. Have you been able to port this to PHP yet?

Reply
0 Kudos