VMware {code}

 View Only
  • 1.  Add Host USB Device to VM via powercli script

    Posted Aug 15, 2022 01:10 PM

    Hi everyone,

    Summary:

    I'm facing the issue when: Trying to connect a specific (physical) USB device (USB token) to specific VM.
    In vCenter web-client everything works properly. Standard process is:

    • vCenter - Choose my VM - Edit Settings - Add new device - Host USB Device

    Automatically is created USB controller (USB 2) and under this controller is assigned USB device. The device connected that way is working properly.

    But what if I want do same thing via script?

    ------------------

    Some basic data first:

    We're running on: vCenter (7.0.3.00300) and ESXi (7.0.3, build: 19898904)

    We're using specific USB token, so here's the lsusb output

     

     

     

    lsusb 
    Bus 001 Device 001: ID 0e0f:8003 VMware, Inc. Root Hub
    Bus 001 Device 002: ID 0529:0003 Aladdin Knowledge Systems 
    Bus 001 Device 003: ID 0557:7000 ATEN International Co., Ltd Hub
    Bus 001 Device 004: ID 0557:2419 ATEN International Co., Ltd Virtual mouse/keyboard device

     

     

     

    Also there is the command for passthrough of USB devices, but in this case is useless.

     

     

     

    esxcli hardware usb passthrough device list

     

     

     

    I repeat, it works properly in when it's set via web-gui. 

    ------------------

    Power-Cli:

    So. powercli have a powerful module VMware.VimAutomation.Core which using following API calls to handling USB devices:

    • Data Object - VirtualUSB(vim.vm.device.VirtualUSB) - link

    So, in the powercli should be a possible determine the physical device which needs to be connected to VM by a several ways when you using DeviceBacking:

    • Data Object - VirtualUSBUSBBackingInfo(vim.vm.device.VirtualUSB.USBBackingInfo) - link
    • Data Object - VirtualUSBRemoteHostBackingInfo(vim.vm.device.VirtualUSB.RemoteHostBackingInfo) - link
    • Data Object - VirtualDeviceDeviceBackingInfo(vim.vm.device.VirtualDevice.DeviceBackingInfo) - link

    Which means that you can write deviceName like this:

     

     

     

    # by physical path
    path:0/1/0
    
    # by pid and vid which is vendor id and product id
    pid:0529 vid:0003
    
    # by combination of above listed
    pid:0529 vid:0003 hostId:00\ 00\ 00\ 00\ 00\ 00\ 00\ 00-00\ 00\ 3c\ ec\ ef\ 4b\ f0\ a4
    # or
    path:0/1/0 hostId:00\ 00\ 00\ 00\ 00\ 00\ 00\ 00-00\ 00\ 3c\ ec\ ef\ 4b\ f0\ a4

     

     

     

    However:

    Physical path on the bus not working! Because the path which is listed in vCenter is not same as the data listed in lsusb (see below).

    Path (same as in vCenter) should be writen into the vmkernel.log but is't not! Not even in gzipped logs which rotated out already. So I cannot catch the same address which vCenter requires.

    I was trying "re-build" the path from information which I can accessible now, so from lsusb because the command have some next interesting parameters. But honestly I have no clue how VMware generating the path from these information:

     

     

    lsusb -d 0529:0003 -v
    Bus 001 Device 002: ID 0529:0003 Aladdin Knowledge Systems 
    Device Descriptor:
      bLength                18
      bDescriptorType         1
      bcdUSB               2.00
      bDeviceClass            0 (Defined at Interface level)
      bDeviceSubClass         0 
      bDeviceProtocol         0 
      bMaxPacketSize0        64
      idVendor           0x0529 Aladdin Knowledge Systems
      idProduct          0x0003 
      bcdDevice            6.09
      iManufacturer           1 Gemalto
      iProduct                2 Sentinel HL
      iSerial                 0 
      bNumConfigurations      1
      Configuration Descriptor:
        bLength                 9
        bDescriptorType         2
        wTotalLength       0x0022
        bNumInterfaces          1
        bConfigurationValue     1
        iConfiguration          0 
        bmAttributes         0x80
          (Bus Powered)
        MaxPower               50mA
        Interface Descriptor:
          bLength                 9
          bDescriptorType         4
          bInterfaceNumber        0
          bAlternateSetting       0
          bNumEndpoints           1
          bInterfaceClass         3 Human Interface Device
          bInterfaceSubClass      0 No Subclass
          bInterfaceProtocol      0 None
          iInterface              0 
            HID Device Descriptor:
              bLength                 9
              bDescriptorType        33
              bcdHID               1.10
              bCountryCode            0 Not supported
              bNumDescriptors         1
              bDescriptorType        34 Report
              wDescriptorLength     116
             Report Descriptors: 
               ** UNAVAILABLE **
          Endpoint Descriptor:
            bLength                 7
            bDescriptorType         5
            bEndpointAddress     0x85  EP 5 IN
            bmAttributes            3
              Transfer Type            Interrupt
              Synch Type               None
              Usage Type               Data
            wMaxPacketSize     0x0040  1x 64 bytes
            bInterval             255
    can't get device qualifier: Resource temporarily unavailable
    Device Status:     0x0000
      (Bus Powered)

     

     

    Then I said: Maybe just pair bus and dev number from this output. No success.

     

     

    lsusb -t
    Bus#  1
    `-Dev#   1 Vendor 0x0e0f Product 0x8003
      |-Dev#   2 Vendor 0x0529 Product 0x0003
      `-Dev#   3 Vendor 0x0557 Product 0x7000
        `-Dev#   4 Vendor 0x0557 Product 0x2419

     

     

    So I definitely escape the idea that the "path" is detectable from anywhere from VMware.

    Funny thing is, that VMware, respectively ESXi, have a file /var/log/usb.log. Why the information about path isn't printed in this file? It would be so much more transparent.

    ------------------

    Only one option left: Identify device via pid and vid which can be discovered again via lsusb command.

    Output of command for device is:

     

     

    Bus 001 Device 002: ID 0529:0003 Aladdin Knowledge Systems

     

     

    ------------------

    So here's the powercli script, which should add USB controller to desired VM first and after that add physical device.

    First part of the script working fine:

     

     

    $spec = New-Object VMware.Vim.VirtualMachineConfigSpec 
    $deviceCfg = New-Object VMware.Vim.VirtualDeviceConfigSpec
    $deviceCfg.Operation = "add"
    $deviceCfg.Device = New-Object VMware.Vim.VirtualUSBController
    $deviceCfg.Device.Key = -1
    $deviceCfg.Device.Connectable = New-Object VMware.Vim.VirtualDeviceConnectInfo
    $deviceCfg.Device.Connectable.StartConnected - $true
    $deviceCfg.Device.Connectable.AllowGuestControl = $false
    $deviceCfg.Device.Connectable.Connected = $true
    $deviceCfg.Device.ControllerKey = 100
    $deviceCfg.Device.BusNumber = -1
    $deviceCfg.Device.autoConnectDevices = $true
    
    $spec.DeviceChange += $deviceCfg
    
    $vm_name = "vm-01"
    $vm = get-vm -Name $vm_name | Get-View
    $vm.ReconfigVM_Task($spec)

     

     

     USB 2.0 controller is successfully added.

    Second part of script:

     

     

    # cleaning the vars
    $spec = $null
    $deviceCfg = $null
    
    # define vm
    $vm_name = "vm-01"
    
    # define pid of phy device
    $devicePid = "0529"
    # define vid of phy device
    $deviceVid = "0003"
    
    $spec = New-Object VMware.Vim.VirtualMachineConfigSpec 
    $deviceCfg = New-Object VMware.Vim.VirtualDeviceConfigSpec[] (1)
    $deviceCfg[0] = New-Object VMware.Vim.VirtualDeviceConfigSpec
    $deviceCfg[0].Operation = "add"
    $deviceCfg[0].Device = New-Object VMware.Vim.VirtualUSB
    $deviceCfg[0].Device.backing = New-Object VMware.Vim.VirtualUSBUSBBackingInfo
    $deviceCfg[0].Device.backing.deviceName = "pid:$devicePid vid:$deviceVid"
    $deviceCfg[0].Device.backing.useAutoDetect = $null
    $deviceCfg[0].Device.connectable = $null
    $deviceCfg[0].Device.connected = $true
    $deviceCfg[0].Device.vendor = 3
    $deviceCfg[0].Device.vendor = 1321
    $deviceCfg[0].Device.SlotInfo = $null
    $deviceCfg[0].Device.family = "hid"
    $deviceCfg[0].Device.speed = "full"
    
    $vm = get-vm -Name $vm_name | Get-View
    $vm.ReconfigVM_Task($spec)

     

     

    Script exited correctly, but nothing's do. The task is processed in vCenter, but with no changes on the VM.

    This is output in vCenter in tasks:

     

     

    Reconfigured vm-01 on esxi-03 in pgr-dc. Modified: Added: Deleted:

     

     

    And when the USB device is added via vCenter, the output is:

     

     

    Reconfigured vm-01 on esxi-03 in prg-dc. Modified: config.hardware.device(7000).device: () -> (41000); config.extraConfig("usb.autoConnect.device0").value: "" -> "path:0/1/0 autoclean:1 virtPath:usb.autoConnect.device0 version:4"; Added: config.hardware.device(41000): (key = 41000, deviceInfo = (label = "USB 41001", summary = "Aladdin Knowledge Sentinel HL"), backing = (deviceName = "path:0/1/0", useAutoDetect = <unset>), connectable = null, slotInfo = null, controllerKey = 7000, unitNumber = 41000, numaNode = <unset>, connected = true, vendor = 1321, product = 3, family = ("hid"), speed = ("full")); Deleted:

     

     

     

    I missing something but I can't find it anymore. Or I just completely lost.

    Maybe it would be more readable for someone else.

    I would be grateful for any hint.

    Thanks,

    John



  • 2.  Re: Add Host USB Device to VM via powercli script

    Posted Aug 15, 2022 03:52 PM

    Is this a PowerCLI question or an API question?
    If you want I can move this thread to the VMware{code} Discussions





  • 3.  Re: Add Host USB Device to VM via powercli script

    Posted Aug 15, 2022 04:42 PM

    To me, it looks as if you using the API via the PowerCLI framework, so it is a bit of an in-between question.

    Let's see if in the {code} community someone can help, if not, we can always move the thread back here.

    Update: the move seems to have lost your last reply.



  • 4.  Re: Add Host USB Device to VM via powercli script

    Posted Aug 15, 2022 05:24 PM

    Yeah, it seems so. But it's okay. Thanks for moving post to correct section and I am sorry for posting to wrong.



  • 5.  RE: Add Host USB Device to VM via powercli script

    Posted 12 days ago

    I found some useful information in this file /dev/char/vmkdriver/usbdevices . (Port=12)

    T:  Bus=01 Lev=01 Prnt=01 Port=12 Cnt=04 Dev#=  5 Spd=480  MxCh= 0

    run--> vim-cmd vmsvc/device.connusbdev 20 "path:0/1/12"

    Successful attach usb drive to vm guest.




  • 6.  RE: Add Host USB Device to VM via powercli script

    Posted 11 days ago
    The vCenter task output gives an important clue.
     
    When you add the device through the GUI, VMware sets both the USB device controllerKey and a usb.autoConnect.device0 entry containing the physical path value.
     
    Your script creates the VirtualUSB object, but it doesn't appear to associate it with the USB controller or create the corresponding auto-connect configuration.
     
    I'd compare the complete VirtualMachineConfigSpec generated by the GUI operation with your PowerCLI spec, particularly controllerKey, unitNumber, and config.extraConfig.