Hello,
I'm trying to collect the diskmode from a virtual machine but with the code below i can't seem to get the value.
Is this string (in bold) the right setPath for this specific action.?
Thanks in advance.
Steve
Dim rp2Rp As TraversalSpec = New TraversalSpec()
rp2Rp.name = "rp2Rp"
rp2Rp.type = "ResourcePool"
rp2Rp.path = "resourcePool"
rp2Rp.skip = False
rp2Rp.selectSet = New SelectionSpec() {New SelectionSpec(), New SelectionSpec()}
rp2Rp.selectSet(0).name = "rp2Rp"
rp2Rp.selectSet(1).name = "rp2Vm"
Dim rp2Vm As TraversalSpec = New TraversalSpec()
rp2Vm.name = "rp2Vm"
rp2Vm.type = "ResourcePool"
rp2Vm.path = "vm"
rp2Vm.skip = False
rp2Vm.selectSet = New SelectionSpec() {}
Dim cr2Rp As TraversalSpec = New TraversalSpec()
cr2Rp.name = "cr2Rp"
cr2Rp.type = "ComputeResource"
cr2Rp.path = "resourcePool"
cr2Rp.skip = False
cr2Rp.selectSet = New SelectionSpec() {rp2Rp, New SelectionSpec()}
Dim cr2h As TraversalSpec = New TraversalSpec()
cr2h.name = "cr2h"
cr2h.type = "ComputeResource"
cr2h.path = "host"
cr2h.skip = False
cr2h.selectSet = New SelectionSpec() {}
Dim dc2hf As TraversalSpec = New TraversalSpec()
dc2hf.name = "dc2hf"
dc2hf.type = "Datacenter"
dc2hf.path = "hostFolder"
dc2hf.skip = False
dc2hf.selectSet = New SelectionSpec() {New SelectionSpec()}
dc2hf.selectSet(0).name = "traverseChild"
Dim dc2f As TraversalSpec = New TraversalSpec()
dc2f.name = "dc2f"
dc2f.type = "Datacenter"
dc2f.path = "vmFolder"
dc2f.skip = False
dc2f.selectSet = New SelectionSpec() {New SelectionSpec()}
dc2f.selectSet(0).name = "traverseChild"
Dim h2vm As TraversalSpec = New TraversalSpec()
h2vm.name = "h2vm"
h2vm.type = "HostSystem"
h2vm.path = "vm"
h2vm.skip = False
h2vm.selectSet = New SelectionSpec() {New SelectionSpec()}
h2vm.selectSet(0).name = "traverseChild"
Dim traversalSpec As TraversalSpec = New TraversalSpec()
traversalSpec.type = "Folder"
traversalSpec.name = "traverseChild"
traversalSpec.path = "childEntity"
traversalSpec.skip = False
traversalSpec.selectSet = New SelectionSpec() {New SelectionSpec(), dc2f, dc2hf}
traversalSpec.selectSet(0).name = traversalSpec.name
Dim pSpec As New PropertySpec
pSpec.type = "VirtualMachine"
pSpec.all = False
pSpec.pathSet = New String() {"config.hardware.device[2000].backing"}
Dim objSpec As New ObjectSpec
objSpec.obj = _rootFolder
objSpec.skip = False
objSpec.selectSet = New SelectionSpec()
Dim _pfSpec As New PropertyFilterSpec
_pfSpec.objectSet = New ObjectSpec()
_pfSpec.propSet = New PropertySpec()
Dim oCary() As ObjectContent
oCary = service.RetrieveProperties(propCol, New PropertyFilterSpec() )
Okay! let me try and articulate your overall requirement as I have understood till now. You need to browse through all the Virtual Machines in your inventory and find any VirtualDisk with the diskMode not equal to "independent_persistent" and then alter the Virtual Device to change the diskMode to "independent_persistent". Well I might be wrong in my above assumptions but hoping that they are correct you should follow the below approach:
1. Search for all the VMs and their device property.
2. For each VM iterate through the devices to get the VirtualDisk device.
3. Check for the diskMode and if it requires an alteration if not then move on to the next VM.
4. If the VM requires the change then get the VirtualDisk Object from the retrieved set of devices and set the diskMode as per your requirement.
5. Create the VirtualDeviceConfigSpec object and set the device to the VirtualDisk device object retrieved and edited in the step 4. If there are multiple Virtual Disks for a single VM then create as many VirtualDeviceConfigSpec as the number of devices that needs to change and add these VirtualDeviceConfigSpec to the VirtualMachineConfigSpec.
6. Once you have created a consolidated VirtualMachineConfigSpec object for a VM call the ReconfigVM_Task there itself as right now while iterating you also have the mor for the VMs.
I think you are already doing most of the steps apart from the way you edit the Virtual Devices. I could see that in your code you are creating a new device using new operator, then setting up all the values in the properties and then passing it to the VirtualDeviceConfigSpec. I would rather suggest you to use the Virtual Device Object retrieved from the ObjectContent to pass on in the VirtualDeviceConfigSpec as then you only need to edit the relevant properties of your interest.
~ Sidharth
Hi Steve,
You would need to set the pathSet till the "config.hardware.device" property. And then from the ObjectContent you need to filter the VirtualDisk type of the device to get the "backing" property.
pSpec.pathSet = New String() {"config.hardware.device[2000].backing"}
will not work as config.hardware.device[2000].backing is not a direct property of the Virtual Machine. The property "config.hardware.device" returns you an array, thus you would have to parse through the array for further filtering.
Your code should be
pSpec.pathSet = New String() {"config.hardware.device"}
Hope the above helps.
~ Sidharth
Hi Sidharth,
Thanks for the quick reply.
I already tried that but wasn't succesfull. But this morning with a clear mind I tried it again and Yippie it worked.
This is what i have so far. But my question now is, is this the best way to do it? or is there a beter one.
Code below for retrieving DiskMode.
Dim oc As ObjectContent = Nothing
Dim mor As ManagedObjectReference = Nothing
Dim pcary As DynamicProperty() = Nothing
Dim pc As DynamicProperty = Nothing
For oci As Integer = 0 To oCary.Length - 1
oc = oCary(oci)
mor = oc.obj
pcary = oc.propSet
'MessageBox.Show("Object Type : " + mor.type)
'MessageBox.Show("Reference Value : " + mor.Value)
If pcary IsNot Nothing Then
For pci As Integer = 0 To pcary.Length - 1
pc = pcary(pci)
'MessageBox.Show("Reference Value : " + mor.Value + " Property Name : " + pc.val.ToString)
If pc IsNot Nothing Then
If Not pc.val.GetType().IsArray Then
Debug.Print(" Property Value : " + pc.val.ToString)
Else
Dim ipcary As Array = DirectCast(pc.val, Array)
Debug.Print("Val : " + pc.val.ToString)
For ii As Integer = 0 To ipcary.Length - 1
Dim oval As Object = ipcary.GetValue(ii)
If oval.GetType().Name.IndexOf("ManagedObjectReference") >= 0 Then
Dim imor As ManagedObjectReference = DirectCast(oval, ManagedObjectReference)
Debug.Print("Inner Object Type : " + imor.type)
Debug.Print("Inner Reference Value : " + imor.Value)
Else
Debug.Print("Inner Property Value : " + oval.ToString)
Debug.Print("Inner Property Value : " + oval.deviceinfo.label.ToString)
If oc.propSet(0).val(ii).ToString = ("VimApi.VirtualDisk") Then
Debug.Print("Test 4 object : " + oval.backing.diskMode.ToString)
End If
End If
Next
End If
End If
Next
End If
Next
Else
MessageBox.Show("No Managed Entities retrieved!")
End If
End Code for retrieving DiskMode
Code Below For Changing the Diskmode to persistent
Dim disk As VirtualDisk = New VirtualDisk()
disk.key = "2000"
disk.controllerKey = "1000"
disk.controllerKeySpecified = True
disk.unitNumber = "0"
disk.unitNumberSpecified = True
Dim diskBacking As VirtualDiskFlatVer2BackingInfo = New VirtualDiskFlatVer2BackingInfo
diskBacking.diskMode = "independent_persistent"
diskBacking.fileName = ""
disk.backing = diskBacking
Dim disk_vm_configSpec As VirtualDeviceConfigSpec = New VirtualDeviceConfigSpec()
disk_vm_configSpec.device = disk
'disk_vm_configSpec.fileOperation = VirtualDeviceConfigSpecFileOperation.create
'disk_vm_configSpec.fileOperationSpecified = True
disk_vm_configSpec.operation = VirtualDeviceConfigSpecOperation.edit
disk_vm_configSpec.operationSpecified = True
Dim newSpec As VirtualMachineConfigSpec = New VirtualMachineConfigSpec()
newSpec.deviceChange = New VirtualDeviceConfigSpec()
Dim oChange As ManagedObjectReference = Nothing
oChange = X.Session.ReconfigVM_Task(VM, newSpec)
Debug.Print("Changed diskMode to Persistent")
End Code For Changing the Diskmode to persistent
Okay! let me try and articulate your overall requirement as I have understood till now. You need to browse through all the Virtual Machines in your inventory and find any VirtualDisk with the diskMode not equal to "independent_persistent" and then alter the Virtual Device to change the diskMode to "independent_persistent". Well I might be wrong in my above assumptions but hoping that they are correct you should follow the below approach:
1. Search for all the VMs and their device property.
2. For each VM iterate through the devices to get the VirtualDisk device.
3. Check for the diskMode and if it requires an alteration if not then move on to the next VM.
4. If the VM requires the change then get the VirtualDisk Object from the retrieved set of devices and set the diskMode as per your requirement.
5. Create the VirtualDeviceConfigSpec object and set the device to the VirtualDisk device object retrieved and edited in the step 4. If there are multiple Virtual Disks for a single VM then create as many VirtualDeviceConfigSpec as the number of devices that needs to change and add these VirtualDeviceConfigSpec to the VirtualMachineConfigSpec.
6. Once you have created a consolidated VirtualMachineConfigSpec object for a VM call the ReconfigVM_Task there itself as right now while iterating you also have the mor for the VMs.
I think you are already doing most of the steps apart from the way you edit the Virtual Devices. I could see that in your code you are creating a new device using new operator, then setting up all the values in the properties and then passing it to the VirtualDeviceConfigSpec. I would rather suggest you to use the Virtual Device Object retrieved from the ObjectContent to pass on in the VirtualDeviceConfigSpec as then you only need to edit the relevant properties of your interest.
~ Sidharth
sidharth,
thanks for the great tips. o \o/ o
I got most of it already working with the tips from your previous reply..
I'll try to modify the code so I edit the virtualdeviceconfigspec instead of creating a new one.
Ones again thanks for your help it got a lot of my questions answered.
With kind regards,
Steve