JPatten
Enthusiast
Enthusiast

C# Sorting VI Object By Virtual Machine Name

I have some C# code that I use to generate a web page showing a list of VMs from a given ESX host. My current issue is that the results are returned in an order based on their MORef and not the VM name. I have found some code in Perl to do it, but my page is being built by C#.

I am currently pulling the Name of the Virtual Machine from the VirtualMachineConfigInfo object that is based on an object content item that is retrieving properties of the VMs. Here is a code snippet. Any help or sorting this object by Name would be appreciated.

#region Find VMs

                PropertySpec pSpec = new PropertySpec();
                pSpec.type = "VirtualMachine";
                pSpec.all = true;

                TraversalSpec folderTSpec = new TraversalSpec();
                folderTSpec.name = "traverseChild";
                folderTSpec.type = "Folder";
                folderTSpec.path = "childEntity";
                folderTSpec.skip = false;

                SelectionSpec traverseChild = new SelectionSpec();
                traverseChild.name = folderTSpec.name;
                
                TraversalSpec dc2VMTSpec = new TraversalSpec();
                dc2VMTSpec.name = "TraverseDC1";
                dc2VMTSpec.type = "Datacenter";
                dc2VMTSpec.path = "vmFolder";
                dc2VMTSpec.skip = false;
                dc2VMTSpec.selectSet = new SelectionSpec[] { traverseChild };
                folderTSpec.selectSet = new SelectionSpec[] { traverseChild, dc2VMTSpec };
                ObjectSpec oSpec = new ObjectSpec();
                oSpec.obj = rootFolder;
                oSpec.skip = false;
                oSpec.selectSet = new SelectionSpec[] { folderTSpec };

                PropertyFilterSpec spec = new PropertyFilterSpec();
                spec.propSet = new PropertySpec[] { pSpec };
                spec.objectSet = new ObjectSpec[] { oSpec };
                
                ObjectContent[] ocary =
                service.RetrieveProperties(
                propertyCollector, new PropertyFilterSpec[] { spec }
                );
                if (ocary != null)
                {

                    #region Display Properties
                    ObjectContent oc = new ObjectContent();
                    ManagedObjectReference mor = new ManagedObjectReference();
                    DynamicProperty[] pcary = null;
                    DynamicProperty pc = new DynamicProperty();
                    for (int oci = 0; oci < ocary.Length; oci++)
                    {
                        oc = ocary[oci];
                        mor = oc.obj;
                        pcary = oc.propSet;
                        #region PowerState
                        // Retrieve the "config" property
                        PropertyFilterSpec spec2 = new PropertyFilterSpec();
                        spec2.propSet = new PropertySpec[] { new PropertySpec() };
                        spec2.propSet[0].allSpecified = false;
                        spec2.propSet[0].type = mor.type;
                        spec2.propSet[http://0].pathSet = new string[|http://0].pathSet = new string[] { "runtime" };
                        spec2.objectSet = new ObjectSpec[] { new ObjectSpec() };
                        spec2.objectSet[0].obj = mor;
                        spec2.objectSet[0].skip = false;
                        ObjectContent[http://] oc2 = service.RetrieveProperties(propertyCollector, new PropertyFilterSpec[|http://] oc2 = service.RetrieveProperties(propertyCollector, new PropertyFilterSpec[] { spec2 });
                        Array.Sort(oc2);
                        VirtualMachineRuntimeInfo power = (VirtualMachineRuntimeInfo)oc2[0].propSet[0].val;
                        bool isOn = true;
                        if (power.powerState != VirtualMachinePowerState.poweredOn)
                        {
                            isOn = false;
                        }
                        #endregion
                        #region FindConfig
                        // Retrieve the "config" property
                        PropertyFilterSpec spec1 = new PropertyFilterSpec();
                        spec1.propSet = new PropertySpec[] { new PropertySpec() };
                        spec1.propSet[0].allSpecified = false;
                        spec1.propSet[0].type = mor.type;
                        spec1.propSet[http://0].pathSet = new string[|http://0].pathSet = new string[] { "config" };
                        spec1.objectSet = new ObjectSpec[] { new ObjectSpec() };
                        spec1.objectSet[0].obj = mor;
                        spec1.objectSet[0].skip = false;
                        ObjectContent[http://] oc1 = service.RetrieveProperties(propertyCollector, new PropertyFilterSpec[|http://] oc1 = service.RetrieveProperties(propertyCollector, new PropertyFilterSpec[] { spec1 });
                        VirtualMachineConfigInfo info = (VirtualMachineConfigInfo)oc1[0].propSet[0].val;
                    }
           }

0 Kudos
5 Replies
Steve_Jin
Expert
Expert

1. PropertyCollector does not sort the result for you. But you can easily get it done by using the SortedList as in:

2. To get the name of a virtual machine, you don't need to get hold of the VirtualMachineConfigInfo. The name is a property inherited from ManagedEntity. The line "pSpec.all = true" gets all the properties, which seems to me an overkill.

Steve JIN, VMware Engineering

Creator of VI Java API:

Steve JIN Author of VMware VI and vSphere SDK; Creator of open source VI Java API (http://vijava.sf.net); Blogger at http://www.doublecloud.org
0 Kudos
JPatten
Enthusiast
Enthusiast

I did not list all of my code, but I also use the VirtualMachineConfigInfo to retrieve the UUID and any Annotations.

Would you be able to throw a quick sample together of using the SortedList in conjunction wtih the VI?

0 Kudos
Steve_Jin
Expert
Expert

That makes sense.

There is a sample in the link on how to use the SortedList as follows:

using System;

using System.Collections;

public class SamplesSortedList {

public static void Main() {

// Creates and initializes a new SortedList.

SortedList mySL = new SortedList();

mySL.Add("First", "Hello");

mySL.Add("Second", "World");

mySL.Add("Third", "!");

// Displays the properties and values of the SortedList.

Console.WriteLine( "mySL" );

Console.WriteLine( " Count: {0}", mySL.Count );

Console.WriteLine( " Capacity: ", mySL.Capacity ); Console.WriteLine( " Keys and Values:" ); PrintKeysAndValues( mySL ); } public static void PrintKeysAndValues( SortedList myList ) { Console.WriteLine( "\t-KEY-\t-VALUE-" ); for ( int i = 0; i &lt; myList.Count; i++ ) { Console.WriteLine( "\t:\t", myList.GetKey(i), myList.GetByIndex(i) );

}

Console.WriteLine();

}

}

You can put the name of the virtual machine as key, and the VirtualMachineConfigInfo as the value.

Steve JIN, VMware Engineering

Creator of VI Java API:

Steve JIN Author of VMware VI and vSphere SDK; Creator of open source VI Java API (http://vijava.sf.net); Blogger at http://www.doublecloud.org
JPatten
Enthusiast
Enthusiast

So basically, I will have to create an array or list of all the VMs first from VI, then sort them, and then create my page based on the sorted object?

I was hoping that VI would return a sorted list some how, but if not, I can go the other route.

Thanks

0 Kudos
Steve_Jin
Expert
Expert

You are right.

NO. VI does not sort for you, and you have to do it by yourself.

Steve JIN, VMware Engineering

Creator of VI Java API: http://vijava.sf.net

Steve JIN Author of VMware VI and vSphere SDK; Creator of open source VI Java API (http://vijava.sf.net); Blogger at http://www.doublecloud.org
0 Kudos