Hello,
currently I have a problem, which involves vSphere/VCenter. I have a VCenter with many USB devices connected to different ESXi and I have to connect an USB device to a specific VM on demand. Now I need to know the USB path to these devices. The one that looks like this
deviceName = "path:1/0/3/3/2/5/1 version:2"
I can connect to the ESXi and get this path for device that are already connected to VMs with this command. The second command gives me the ID of the VM, which replaces XXXX in the first command
vim-cmd vmsvc/device.getdevices XXXX | grep path vim-cmd vmsvc/getallvms
Now the problem is that I do not get the paths for USB devices, that are not connected to a VM. I know that I can connect a device with the device ID, that i get with lsusb, but the problem here is that all my device have the same VendorID and ProductID, because there are the same product and from the same vendor. So the vSphere Client can differentiate between all USB devices and knows which are connected to which ESXi etc. But I did not find any way to get this information via vSphere Web API or some ESXi vim-cmd.
Are there any ways to get this information?
I am using vSphere 5.5
Kind regards
Update:
So i found a solution for this
I used python for this and you need these two libs for it pyVim and pyVmomi. These are used to communicate with the vSphere Server and everything
Here is the code
from pyVim import connect from pyVmomi import vmodl from pyVmomi import vim service_instance = connect.SmartConnect(host=<Ip of your vSphere server>, user=<userName>, pwd=<password>, port=<your port>) si = service_instance.content.searchIndex atexit.register(connect.Disconnect, si) # get your datacenter content = service_instance.RetrieveContent() dc = None for datacenter in content.rootFolder.childEntity: if datacenter.name != <name of datacenter>: continue dc = datacenter break if dc is None: print("did not find the datacenter") return 0 viewType = [vim.HostSystem] # object types to look for recursive = True # whether we should look into it recursively containerView = content.viewManager.CreateContainerView(dc, viewType, recursive) children = containerView.view containerView.Destroy() # get the compute resource and vm list container = content.viewManager.CreateContainerView(dc, [vim.ComputeResource], True) containerVM = content.viewManager.CreateContainerView(dc, [vim.VirtualMachine], True) vmList = [] for vm in containerVM.view: vmList.append(vm) containerVM.Destroy() # get my current agent/VM on which i am running IP = socket.gethostbyname(socket.gethostname()) myself = None myself = si.FindByIp(None, IP, True) hosts = {} devices = [] keysAlreadyConnected = {} print("--------------------") print("searching for all USB devices available in the datacenter") print("--------------------") with open("log", 'w') as f: for child in children: if len(child.vm) < 1: print("no vms, so no key checking for {0}".format(child.name)) continue if <specific esxi name> not in child.name: continue f.write("host: {0}".format(child.name)) hosts[child.name] = child # get a compute resource to get the environmentBrowser to be able to run QueryConfigTarget obj = None for c in container.view: if c.name == child.parent.name: obj = c break if obj is None: print("no compute resource found") continue envBrowser = obj.environmentBrowser if envBrowser is None: print("no env browser") return 0 result = envBrowser.QueryConfigTarget(child) # end of workaround if result is not None: f.write("no usb devices: {0}\n".format(len(result.usb))) for usbDevice in result.usb: deviceName = usbDevice.description f.write("\n\n" + usbDevice.description + "\n") f.write(usbDevice.physicalPath+ "\n") f.write(usbDevice.name+ "\n") f.write(str(usbDevice.configurationTag)+ "\n") if <my specific device name> in deviceName: # this only works for VMs that are turned on if usbDevice.summary is not None: connectedVM = usbDevice.summary if connectedVM is not None: f.write("connected to {0}\n".format(connectedVM.config.name)) vmName = connectedVM.config.name # this is only for debugging and is for using only specific agents/VMs if <specific VM name> in vmName: devices.append(usbDevice.physicalPath) print("will check {0} from vm {1}".format(deviceName, vmName)) else: devices.append(usbDevice.physicalPath) print(usbDevice.summary) print("will check {0} that is not connected".format(deviceName)) # check vms to look for connected usb devices on powered off VMs for vm1 in vmList: if vm1.name == myself.name: continue for device in vm1.config.hardware.device: if not isinstance(device, vim.vm.device.VirtualUSB): continue if device.backing.deviceName in devices: keysAlreadyConnected[device.backing.deviceName] = vm1 else: print ("did not find {0}".format(uuid))
This works for me. I think these Python libs are also available for Java and this solution should work there too.
The indention is probably messed up but I hope this will help everyone with the same problem.
Here is the code to add or remove a usb device
def addOrRemoveAllDevicesFromCurrentAgent(vm, deviceList, remove = False): vm_spec = vim.vm.ConfigSpec() usb_changes = [] for device in deviceList: usb_spec = vim.vm.device.VirtualDeviceSpec() if remove: usb_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.remove else: usb_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add usb_spec.device = device usb_changes.append(usb_spec) vm_spec.deviceChange = usb_changes e = vm.ReconfigVM_Task(spec=vm_spec) x = 0 while not e.info.completeTime and x < 30: time.sleep(1) x = x + 1
This should be understandable and is pretty straight forward.