Hi,
I am using vSphere 5.5 SDK to retrieve hosts and vm's data from VMware ESXi 4. The application successfully fetches data for hosts but it fails with the below exception when I try to retrieve data for datastores or vm's
at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
at Vim25Api.VimService.RetrieveServiceContent(ManagedObjectReference _this)
It fails (at highlighted red line) when I try to use below get properties method. Any help to resolve this would be greatly appreciated.
public static Object[] getProperties(ManagedObjectReference moRef, String[] properties) {
// PropertySpec specifies what properties to retrieve and from type of Managed Object
PropertySpec pSpec = new PropertySpec();
pSpec.type = moRef.type;
pSpec.pathSet = properties;
// ObjectSpec specifies the starting object and any TraversalSpecs used to specify other objects for consideration
ObjectSpec oSpec = new ObjectSpec();
oSpec.obj = moRef;
// PropertyFilterSpec is used to hold the ObjectSpec and PropertySpec for the call
PropertyFilterSpec pfSpec = new PropertyFilterSpec();
pfSpec.propSet = new PropertySpec[] { pSpec };
pfSpec.objectSet = new ObjectSpec[] { oSpec };
// retrieveProperties() return the properties selected from PropertyFilterSpec
ManagedObjectReference _svcRef1 = new ManagedObjectReference();
_svcRef1.type = "Service Instance";
_svcRef1.Value = "Service Instance";
ServiceContent sic1 = null;
vim_svc.Timeout = 600000; //The value can be set to some higher value also.
sic1 = vim_svc.RetrieveServiceContent(_svcRef1);
ObjectContent[] ocs = new ObjectContent[20];
ocs = vim_svc.RetrieveProperties(sic1.propertyCollector, new PropertyFilterSpec[] { pfSpec });
// Return value, one object for each property specified
Object[] ret = new Object[properties.Length];
if (ocs != null) {
for (int i = 0; i < ocs.Length; i++) {
ObjectContent oc = ocs[i];
DynamicProperty[] dps = oc.propSet;
if (dps != null) {
for (int j = 0; j < dps.Length; ++j) {
DynamicProperty dp = dps[j];
//Find property path index
for (int p = 0; p < ret.Length; ++p) {
if (properties[p].Equals(dp.name)) {
ret[p] = dp.val;
}
}
}
}
}
}
return ret;
}
Without digging too deep, you'll get errors if you ask for properties from the property collector that aren't defined in an older version of the SDK. You'll have to write code logic to ask for 4.x properties only, if you ask for properties that weren't added until a later API version, it will error out.
But when I try to run the below code i.e to extract VM data only, I get no errors while running it.In this code, I am only extracting VM data. But when I use a code in which I extract Host, VM and Datastore data, i get error.
public class VMListing
{
static VimService service;
protected ManagedObjectReference _svcRef;
private UserSession _session;
ServiceContent _sic;
private void VMList(string url, string usid, string pwd, string dcName)
{
ManagedObjectReference _svcRef = new ManagedObjectReference();
//Gets service contents
_svcRef.type = "ServiceInstance";
_svcRef.Value = "ServiceInstance";
service = new VimService();
service.Url = url;
service.CookieContainer = new CookieContainer();
_sic = service.RetrieveServiceContent(_svcRef);
service.LoginCompleted += new LoginCompletedEventHandler(serviceLoginCompleted);
_session = service.Login(_sic.sessionManager, usid, pwd, null);
//ObjectContent[] ocs = null;
//ocs = getDatacenters(service, _sic);
// printObjectContent(ocs, "All DataCenters");
BuildVMLists();
Console.ReadKey();
}
private TraversalSpec buildTSpec()
{
TraversalSpec rpToRp = new TraversalSpec();
rpToRp.type = "ResourcePool";
rpToRp.path = "resourcePool";
rpToRp.skip = false;
rpToRp.name = "rpToRp";
rpToRp.selectSet = new SelectionSpec[] { new SelectionSpec(), new SelectionSpec() };
rpToRp.selectSet[0].name = "rpToRp";
rpToRp.selectSet[1].name = "rpToVm";
TraversalSpec rpToVm = new TraversalSpec();
rpToVm.type = "ResourcePool";
rpToVm.path = "vm";
rpToVm.skip = false;
rpToVm.name = "rpToVm";
rpToVm.selectSet = new SelectionSpec[] { };
TraversalSpec crToRp = new TraversalSpec();
crToRp.type = "ComputeResource";
crToRp.path = "resourcePool";
crToRp.skip = false;
crToRp.name = "crToRp";
crToRp.selectSet = new SelectionSpec[] { rpToRp, new SelectionSpec() };
crToRp.selectSet[1].name = "rpToVm";
TraversalSpec crToH = new TraversalSpec();
crToH.type = "ComputeResource";
crToH.path = "host";
crToH.skip = false;
crToH.name = "crToH";
crToH.selectSet = new SelectionSpec[] { };
TraversalSpec dcToHf = new TraversalSpec();
dcToHf.type = "Datacenter";
dcToHf.path = "hostFolder";
dcToHf.skip = false;
dcToHf.name = "dcToHf";
dcToHf.selectSet = new SelectionSpec[] { new SelectionSpec() };
dcToHf.selectSet[0].name = "visitFolders";
TraversalSpec dcToVmf = new TraversalSpec();
dcToVmf.type = "Datacenter";
dcToVmf.path = "vmFolder";
dcToVmf.skip = false;
dcToVmf.name = "dcToVmf";
dcToVmf.selectSet = new SelectionSpec[] { new SelectionSpec() };
dcToVmf.selectSet[0].name = "visitFolders";
TraversalSpec HToVm = new TraversalSpec();
HToVm.type = "HostSystem";
HToVm.path = "vm";
HToVm.skip = false;
HToVm.name = "HToVm";
HToVm.selectSet = new SelectionSpec[] { new SelectionSpec() };
HToVm.selectSet[0].name = "visitFolders";
TraversalSpec visitFolders = new TraversalSpec();
visitFolders.type = "Folder";
visitFolders.path = "childEntity";
visitFolders.skip = false;
visitFolders.name = "visitFolders";
visitFolders.selectSet = new SelectionSpec[] { new SelectionSpec(), dcToHf, dcToVmf, crToH, crToRp, HToVm, rpToVm };
visitFolders.selectSet[0].name = "visitFolders";
return visitFolders;
}
private void BuildVMLists()
{
TraversalSpec tSpec = buildTSpec();
//PropertySpec[] propSpecArray = new PropertySpec[] { new PropertySpec() };
Vim25Api.PropertySpec propSpecArray = new Vim25Api.PropertySpec();
propSpecArray.type = "VirtualMachine";
//propSpecArray[0].all = true;
//propSpecArray[0].allSpecified = true;
propSpecArray.pathSet = new string[] { "name",
"summary.config.guestFullName",
"summary.config.guestId",
"summary.config.memorySizeMB",
"summary.config.numCpu",
"summary.config.numVirtualDisks",
"summary.config.uuid",
"summary.config.vmPathName",
"summary.runtime.powerState",
"guest.hostName",
"guest.ipAddress",
"guest.toolsStatus",
"guest.toolsVersion",
"guest.net",
"config.hardware.device"
};
PropertyFilterSpec spec = new PropertyFilterSpec();
spec.propSet = new Vim25Api.PropertySpec[] { propSpecArray }; ;
spec.objectSet = new ObjectSpec[] { new ObjectSpec() };
spec.objectSet[0].obj = _sic.rootFolder;
spec.objectSet[0].skip = false;
spec.objectSet[0].selectSet = new SelectionSpec[] {tSpec} ;
ObjectContent[] ocArray =
service.RetrieveProperties(_sic.propertyCollector, new PropertyFilterSpec[]{ spec });
foreach (ObjectContent oc in ocArray)
{
DynamicProperty[] pcArray = oc.propSet;
foreach (DynamicProperty d in pcArray)
{
Console.WriteLine(d.name);
Console.WriteLine(d.val);
Console.ReadKey();
/*
if (d.name.Equals("name"))
{
String n = (String)d.val;
//lstVM.Items.Add(n);
System.Console.WriteLine("VM name:" + n);
Console.ReadKey();
*/
// }
}
}
}
public static Object[] getProperties(ManagedObjectReference moRef, String[] properties)
{
// PropertySpec specifies what properties to
// retrieve and from type of Managed Object
PropertySpec pSpec = new PropertySpec();
pSpec.type = moRef.type;
pSpec.pathSet = properties;
// ObjectSpec specifies the starting object and
// any TraversalSpecs used to specify other objects
// for consideration
ObjectSpec oSpec = new ObjectSpec();
oSpec.obj = moRef;
// PropertyFilterSpec is used to hold the ObjectSpec and
// PropertySpec for the call
PropertyFilterSpec pfSpec = new PropertyFilterSpec();
pfSpec.propSet = new PropertySpec[] { pSpec };
pfSpec.objectSet = new ObjectSpec[] {oSpec};
ManagedObjectReference _svcRef1 = new ManagedObjectReference();
_svcRef1.type = "ServiceInstance";
_svcRef1.Value = "ServiceInstance";
ServiceContent sic1 = service.RetrieveServiceContent(_svcRef1);
ObjectContent[] ocs = new ObjectContent[20];
ocs = service.RetrieveProperties(sic1.propertyCollector, new PropertyFilterSpec[] {pfSpec} );
// Return value, one object for each property specified
Object[] ret = new Object[properties.Length];
if (ocs != null)
{
for (int i = 0; i < ocs.Length; ++i)
{
ObjectContent oc = ocs[i];
DynamicProperty[] dps = oc.propSet;
if (dps != null)
{
for (int j = 0; j < dps.Length; ++j)
{
DynamicProperty dp = dps[j];
// find property path index
for (int p = 0; p < ret.Length; ++p)
{
if (properties[p].Equals(dp.name))
{
ret[p] = dp.val;
}
}
}
}
}
}
return ret;
}
public static void Main(String[] args)
{
VMListing Vmlst = new VMListing();
Vmlst.VMList(args[0], args[1], args[2], args[3]);
}
It all depends on what properties you're requesting. What properties are you requesting for the non-VM objects?
I am requesting the below properties for Host Systems. It throws error for the last two properties i.e. vm and datastore (highlighted in red)
"name",
"hardware.memorySize",
"hardware.systemInfo.model",
"hardware.systemInfo.uuid",
"hardware.systemInfo.vendor",
"hardware.biosInfo.biosVersion", //Since VI API 2.5
"hardware.biosInfo.releaseDate", //Since VI API 2.5
"hardware.cpuPkg",
"summary.hardware.memorySize",
"summary.hardware.model",
"summary.hardware.uuid",
"summary.hardware.vendor",
"summary.hardware.cpuMhz",
"summary.hardware.cpuModel",
"summary.hardware.numCpuCores",
"summary.hardware.numCpuPkgs",
"summary.hardware.numCpuThreads",
"config.storageDevice.scsiLun",
"config.network.pnic",
"config.product.fullName",
"config.product.version",
"config.service.service[\"vmware-vpxa\"].running",
"runtime.bootTime"
"datastore",
"vm"
Properties for VM:
"name",
"summary.config.guestFullName",
"summary.config.guestId",
"summary.config.memorySizeMB",
"summary.config.numCpu",
"summary.config.numVirtualDisks",
"summary.config.uuid",
"summary.config.vmPathName",
"summary.runtime.powerState",
"guest.hostName",
"guest.ipAddress",
"guest.toolsStatus",
"guest.toolsVersion",
"guest.net",
"config.hardware.device"
Datastore Properties:
"summary.capacity",
"summary.freeSpace",
"summary.name",
"summary.type",
"summary.url"
It's probably the property: config.service.service[\"vmware-vpxa\"].running. You'll need to request config.service and iterate them yourself to find the key vmware-vpxa.
No, that property works just fine. It fails for datasore and vm property. And I need them to find out the details of vm associated with each host. I am trying the below logic to handle these properties:
DynamicProperty[] pcary = null;
pcary = oc.propSet;
for (int i = 0; i < pcary.Length; i++)
{
pc = pcary[i];
if ((pc.val.GetType() == typeof(Vim25Api.ManagedObjectReference[])))
{
Vim25Api.ManagedObjectReference[] dsList = (ManagedObjectReference[])pc.val;
Vim25Api.ManagedObjectReference dsRef = null;
for (int j = 0; j < dsList.Length; j++)
{
dsRef = dsList[j];
if (dsRef.type.Equals("VirtualMachine"))
{
StringBuilder VM_Info2 = getvCenterVMsData(dsRef);
VM_Info.Append(VM_Info2).Append("<VM>");
}
else
{
//ManagedObject is a datastore
Object[] dsProps = getProperties(dsRef, new String[] { "summary.capacity",
"summary.freeSpace",
"summary.name",
"summary.type",
"summary.url"
});