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; } }
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
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?
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 < 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
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
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