VMware {code} Community
hypermx
Contributor
Contributor

Get every vm inside folder

Hello.

Im trying to locate a folder on my vCenter, and then list all the VM's thats inside that folder.

I took some code from the SimpleClient, however the recurse are really hard to understand for me.

I managed to modify the code, to find the folder "MKN".

Now all i need to do is to loop through every object/vm inside the folder. (Theres only gonna be VM's inside the folder.)

And this is the part where im stuck.

How can i define the path "MKN" is on, and then get all its content and loop through?

my code:

public void GetPowerStatus(string vName)
        {

            #region defines
            // Create a Filter Spec to Retrieve Contents for...

            TraversalSpec rpToVm = new TraversalSpec();
            rpToVm.name = "rpToVm";
            rpToVm.type = "ResourcePool";
            rpToVm.path = "vm";
            rpToVm.skip = false;


            // Recurse through all ResourcePools

            TraversalSpec rpToRp = new TraversalSpec();
            rpToRp.name = "rpToRp";
            rpToRp.type = "ResourcePool";
            rpToRp.path = "resourcePool";
            rpToRp.skip = false;

            rpToRp.selectSet = new SelectionSpec[] { new SelectionSpec(), new SelectionSpec() };
            rpToRp.selectSet[0].name = "rpToRp";
            rpToRp.selectSet[1].name = "rpToVm";


            // Traversal through ResourcePool branch
            TraversalSpec crToRp = new TraversalSpec();
            crToRp.name = "crToRp";
            crToRp.type = "ComputeResource";
            crToRp.path = "resourcePool";
            crToRp.skip = false;
            crToRp.selectSet = new SelectionSpec[] { new SelectionSpec(), new SelectionSpec() };
            crToRp.selectSet[0].name = "rpToRp";
            crToRp.selectSet[1].name = "rpToVm";


            // Traversal through host branch
            TraversalSpec crToH = new TraversalSpec();
            crToH.name = "crToH";
            crToH.type = "ComputeResource";
            crToH.path = "host";
            crToH.skip = false;


            // Traversal through hostFolder branch
            TraversalSpec dcToHf = new TraversalSpec();
            dcToHf.name = "dcToHf";
            dcToHf.type = "Datacenter";
            dcToHf.path = "hostFolder";
            dcToHf.skip = false;
            dcToHf.selectSet = new SelectionSpec[] { new SelectionSpec() };
            dcToHf.selectSet[0].name = "visitFolders";


            // Traversal through vmFolder branch
            TraversalSpec dcToVmf = new TraversalSpec();
            dcToVmf.name = "dcToVmf";
            dcToVmf.type = "Datacenter";
            dcToVmf.path = "vmFolder";
            dcToVmf.skip = false;
            dcToVmf.selectSet = new SelectionSpec[] { new SelectionSpec() };
            dcToVmf.selectSet[0].name = "visitFolders";


            // Recurse through all Hosts
            TraversalSpec HToVm = new TraversalSpec();
            HToVm.name = "HToVm";
            HToVm.type = "HostSystem";
            HToVm.path = "vm";
            HToVm.skip = false;
            HToVm.selectSet = new SelectionSpec[] { new SelectionSpec() };
            HToVm.selectSet[0].name = "visitFolders";


            // Recurse thriugh the folders
            TraversalSpec visitFolders = new TraversalSpec();
            visitFolders.name = "visitFolders";
            visitFolders.type = "Folder";
            visitFolders.path = "childEntity";
            visitFolders.skip = false;
            visitFolders.selectSet = new SelectionSpec[] { new SelectionSpec(), new SelectionSpec(), new SelectionSpec(), new SelectionSpec(), new SelectionSpec(), new SelectionSpec(), new SelectionSpec() };
            visitFolders.selectSet[0].name = "visitFolders";
            visitFolders.selectSet[1].name = "dcToHf";
            visitFolders.selectSet[2].name = "dcToVmf";
            visitFolders.selectSet[3].name = "crToH";
            visitFolders.selectSet[4].name = "crToRp";
            visitFolders.selectSet[5].name = "HToVm";
            visitFolders.selectSet[6].name = "rpToVm";
            SelectionSpec[] selectionSpecs = new SelectionSpec[] { visitFolders, dcToVmf, dcToHf, crToH, crToRp, rpToRp, HToVm, rpToVm };

            PropertySpec[] propspecary = new PropertySpec[] { new PropertySpec() };
            propspecary[0].all = false;
            propspecary[0].allSpecified = true;
            propspecary[0].pathSet = new string[] { "name" };
            propspecary[0].type = "ManagedEntity";

            PropertyFilterSpec spec = new PropertyFilterSpec();
            spec.propSet = propspecary;
            spec.objectSet = new ObjectSpec[] { new ObjectSpec() };
            spec.objectSet[0].obj = rootFolder;
            spec.objectSet[0].skip = false;
            spec.objectSet[0].selectSet = selectionSpecs;

            // Recursively get all ManagedEntity ManagedObjectReferences
            // and the "name" property for all ManagedEntities retrieved
            ObjectContent[] ocary =
               service.RetrieveProperties(
                  propCol, new PropertyFilterSpec[] { spec }
               );

            #endregion defines


            ObjectContent oc = null;
            ManagedObjectReference mor = null;
            DynamicProperty[] pcary = null;
            DynamicProperty pc = null;

            for (int oci = 0; oci < ocary.Length; oci++)
            {
                oc = ocary[oci];
                pcary = oc.propSet;
                mor = oc.obj;

                /*ListBox1.Items.Add("Object Type : " + mor.type);
                ListBox1.Items.Add("Reference Value : " + mor.Value);*/

                foreach (DynamicProperty value in pcary)
                {
                   
                    //ListBox1.Items.Add(value.val.ToString());
                    if (value.val.ToString() == "MKN")
                    {
                        ListBox1.Items.Add(value.name.ToString());
                        ListBox1.Items.Add(value.val.ToString());
                    }
                }
                /*if (pcary != null)
                {
                    for (int pci = 0; pci < pcary.Length; pci++)
                    {
                        pc = pcary[pci];
                        if (pc != null)
                        {
                            if (!pc.val.GetType().IsArray)
                            {
                                ListBox1.Items.Add(pc.val.ToString());
                            }
                        }
                    }
                }*/

            }
        }

0 Kudos
6 Replies
stumpr
Virtuoso
Virtuoso

I don't have a code blob, but basically the short answer is to fetch all folders (with just their name property for example), then you have the parent object.  Then you can create a ContainerView object with that Folder.  From that you can get a list of objects in that container.  That would be the simpler method. 

If you do a full retrieval spec like this, you'll have to do you own parent-child tree searches to find your VMs.  For example, what if the folder has children folders: MKN/Folder1 and MKN/Folder2 both with VMs below those?

I'd look into the ContainerView as a way to simplify the search.

Reuben Stump | http://www.virtuin.com | @ReubenStump
0 Kudos
BenN
Enthusiast
Enthusiast

First of all, if you're only interested in VM folders, you don't really want any of these selection specs: dcToHf, crToH, crToRp, rpToRp, HToVm, rpToVm. They search down the physical side of vSphere's hierarchy, so you'll end up getting false positives if someone has a Host folder named "MKN" (not that many vCenter installations use host folders).

As far as your actual question, doing it all in a single retrieveProperties call is a pain. You include a PropertySpec for ManagedEntity types to capture their 'parent' and 'name' properties, then you make two passes through the ObjectContent array returned by the PropertyCollector: once to find your Folder object by name, then again to find any VirtualMachine objects whose parent property matches that Folder object (and so on recursively if your Folder can contain Folders instead of just VMs). It's a lot of book-keeping.

Really, it's simpler to make 2 calls. Call retrieveProperties to find your Folder, and then call Folder.getChildEntities to look at its (direct) child VMs.

0 Kudos
hypermx
Contributor
Contributor

Hey.

Thanks for the answers.

You mention that I can call the retrieveProperties to find my folder. However I can't find no such function?

I'm guessing I need to include something in order to get that function.

0 Kudos
stumpr
Virtuoso
Virtuoso

Bear in mind that just using getChildEntities() won't return nested folders unless you recurse through them.  That's why I suggested a ContainerView.  RetreivePropertiesEx() is the method call name, but it's deprecated in favor of WaitForUpdatesEx().  In the dotNET/Java kits some of the get* functions abstract this for you of course.

Reuben Stump | http://www.virtuin.com | @ReubenStump
0 Kudos
hypermx
Contributor
Contributor

Hey Stumpr.

Thanks for the quick answer.

Is there anywere where I can see an example of the containerView in action?

0 Kudos
stumpr
Virtuoso
Virtuoso

Not in dotNET or Java.  I attached a quick Perl example.  Just getting your containerView will return a list of ManagedObjectReferences that you can use for further API operations.

You can also pass that container view to your WaitForUpdatesEx() call as well, instead of your traversal specs.

Here is an example in Perl, there might be some way to use the utility functions in Java/dotNET that I'm not familiar with to avoid the lower level operations.

perl container_view_example.pl --server=172.16.254.50 --username=administrator@vlab --password=VMware1! --datacenter=DC01 --folder=vm

Entities in this folder:

  Folder:group-v262

  VirtualMachine:vm-122

--

Folder:group-v262 = Templates

VirtualMachine:vm-122 = recovery-tmpl

Reuben Stump | http://www.virtuin.com | @ReubenStump
0 Kudos