Contributor
Contributor

Where is the "Get-USBController" cmdlet? (Same with Remove- and New-)

Jump to solution

The command “get-usbdevice”(also “Remove-UsbDevice”) should retrieve the USB devices that could be located on a VM. The problem is that cmdlt only will display those USB devices, if a USB device is currently connected. It will not report anything if the VM has added USB hardware but it currently isn’t connected to anything (ie Just a USB controller).

Now there are other ways that I can go about finding if the VM has that unwanted hardware:

$unwantedhw = “floppy|serial|usb”

(Get-VM $VMname | Get-View).Config.Hardware.Device | Select -Expand DeviceInfo | Select Label, Summary | where {$_.Label –match $unwantedhw}

I just would of thought that instead of having to go back to some get-view shenanigans, I could do it directly with 1 command like the command “Get-UsbDevice” should do in my opinion. I could to try to write my own function (ie Get-USBController) for this and store it in my profile, but I dont have the time on hand atm.

Has anyone else created this function or know of any updates to the PowerCLI to include this in a later feature release??

Versions of PowerCLI:

   VMware vSphere PowerCLI 5.0.1 build 581491

   VMware AutoDeploy PowerCLI Component 5.0 build 544967

   VMware ImageBuilder PowerCLI Component 5.0 build 544967

   VMware vCloud Director PowerCLI Component 1.5 build 581492

   VMware License PowerCLI Component 5.0 build 544881

   VMware vSphere PowerCLI Component 5.0 build 581435

   VMware vSphere Update Manager PowerCLI 5.0 build 432001

0 Kudos
1 Solution

Accepted Solutions
Leadership
Leadership

Try this.

It's my quick-and-dirty Get-UsbController function.

function Get-UsbController{
  param(
  [CmdletBinding()]
  [parameter(Mandatory = $true, ValueFromPipeline = $true)]
  [PSObject[]]${VM}
  )

  process{
    foreach($vmObj in $vm){
      if($vmObj -is [System.String]){
        $vmObj = Get-VM -Name $vmObj
      }       $vmObj.ExtensionData.COnfig.Hardware.Device |
      where {$_ -is [VMware.Vim.VirtualUSBController]} | %{         New-Object PSOBject -Property @{           Name = $_.DeviceInfo.Label
          Summary = $_.DeviceInfo.Summary
         
AutoConnectDevices = $_.AutoCOnnectDevices
          EhciEnabled = $_.EhciENabled
          BusNumber = $_.BusNumber
         
UnitNumber = $_.UnitNumber
        }       }     }   } } Get-VM MyVM | Get-UsbController


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

0 Kudos
15 Replies
Leadership
Leadership

Try this.

It's my quick-and-dirty Get-UsbController function.

function Get-UsbController{
  param(
  [CmdletBinding()]
  [parameter(Mandatory = $true, ValueFromPipeline = $true)]
  [PSObject[]]${VM}
  )

  process{
    foreach($vmObj in $vm){
      if($vmObj -is [System.String]){
        $vmObj = Get-VM -Name $vmObj
      }       $vmObj.ExtensionData.COnfig.Hardware.Device |
      where {$_ -is [VMware.Vim.VirtualUSBController]} | %{         New-Object PSOBject -Property @{           Name = $_.DeviceInfo.Label
          Summary = $_.DeviceInfo.Summary
         
AutoConnectDevices = $_.AutoCOnnectDevices
          EhciEnabled = $_.EhciENabled
          BusNumber = $_.BusNumber
         
UnitNumber = $_.UnitNumber
        }       }     }   } } Get-VM MyVM | Get-UsbController


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

0 Kudos
Contributor
Contributor

Awesome, thanks Lucd. Like I said, I could of tried to work out the function, since I knew most of the backend calls. I just didnt have time to sit and troubleshoot and was hoping someone had already done this before.  o/\o

Any chance you already worked out a Remove-USBController function?

0 Kudos
Leadership
Leadership

I'll put it on my to-do list for this weekend Smiley Wink


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Enthusiast
Enthusiast

This works for me, but the VM have to be Powered Off.


$VMs = Get-VM MyVM

foreach ($VMimpl in $VMs){
$VM = Get-View $VMimpl.ID
$i = 0
$spec = new-object VMware.Vim.VirtualMachineConfigSpec

$HW = $VM.Config.Hardware.Device
  foreach($dev in $HW){
   if (($dev|where {$_ -is [VMware.Vim.VirtualUSBController]})-is [VMware.Vim.VirtualUSBController])
   {
    $spec.DeviceChange += New-Object VMware.Vim.VirtualDeviceConfigSpec
    $spec.DeviceChange[$i].device = New-Object VMware.Vim.VirtualDevice
    $spec.DeviceChange[$i].device.key = $dev.Key
    $spec.DeviceChange[$i].operation = "remove"
   
    $i++
   }
  }
  if ($i -gt 0) {$VM.ReconfigVM_Task($spec)}
}

0 Kudos
Contributor
Contributor

Thats roughly what I have atm, but I was looking to toss that into a function.

Also I find it odd that we can remove USB controllers/devices while the VM is online through the VI client, but I cant do it through powershell if that VM has other hardware that requires the VM to be offline during removal. When I used ONYX to capture the script calls of removing USB controllers, its the exact same script functionality wise to the one you and I are using. I posted about it here - http://communities.vmware.com/thread/403766

0 Kudos
Enthusiast
Enthusiast

Well,

To pass this code into a function is easy, but removing the hardware with the VM Powered On i think Luc could help us..


function Remove-UsbController{
param($VMs )

foreach ($VMimpl in $VMs){
$VM = Get-View $VMimpl.ID
$i = 0
$spec = new-object VMware.Vim.VirtualMachineConfigSpec

$HW = $VM.Config.Hardware.Device
  foreach($dev in $HW){
   if (($dev|where {$_ -is [VMware.Vim.VirtualUSBController]})-is [VMware.Vim.VirtualUSBController])
   {
    $spec.DeviceChange += New-Object VMware.Vim.VirtualDeviceConfigSpec
    $spec.DeviceChange[$i].device = New-Object VMware.Vim.VirtualDevice
    $spec.DeviceChange[$i].device.key = $dev.Key
    $spec.DeviceChange[$i].operation = "remove"
   
    $i++
   }
  }
  if ($i -gt 0) {$VM.ReconfigVM_Task($spec)}
}
}

Remove-UsbController (Get-VM MyVMs)

Contributor
Contributor

Here a shot at new-usbcontroller...

Function New-UsbController

{

  [CmdletBinding()]

  Param(

   [Parameter(Mandatory=$True,Position=1)]

    [string]$Name

  )

   

  #Get our VM then then ID

  $VM = Get-VM $Name 

  $Id = $VM.Id 

   

  #Create a new Virtual Machine Configuration Specification

  $newSpec = New-Object VMware.Vim.VirtualMachineConfigSpec 

  $newSpec.deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec[] (1) 

  $newSpec.deviceChange[0] = New-Object VMware.Vim.VirtualDeviceConfigSpec 

  $newSpec.deviceChange[0].operation = "add" 

  $newSpec.deviceChange[0].device = New-Object VMware.Vim.VirtualUSBController   

   

  $_this = Get-View -Id "$Id" 

  $_this.ReconfigVM_Task($newSpec) 

}

0 Kudos
Enthusiast
Enthusiast

Here is a tweaked version which checks for the newer type of USB Controllers too.

I created this while checking into VMSA-2017-0006​ as ESXi has a vulnerability in these newer types.

function Get-UsbController{   param(   [CmdletBinding()]   [parameter(Mandatory = $true, ValueFromPipeline = $true)]   [PSObject[]]${VM}   )    process{     foreach($vmObj in $vm){       if($vmObj -is [System.String]){         $vmObj = Get-VM -Name $vmObj
      }       $vmObj.ExtensionData.COnfig.Hardware.Device |
      where {($_ -is [VMware.Vim.VirtualUSBXHCIController]) -or ($_ -is [VMware.Vim.VirtualUSBController])} | %{         New-Object PSOBject -Property @{           Name = $_.DeviceInfo.Label
          Summary = $_.DeviceInfo.Summary
         
AutoConnectDevices = $_.AutoCOnnectDevices
          EhciEnabled = $_.EhciENabled
          BusNumber = $_.BusNumber
         
UnitNumber = $_.UnitNumber
        }       }     }   } }  Get-VM MyVM | Get-UsbController
0 Kudos
Contributor
Contributor

Any tips on commands or scripts to find virtual machines with all type of virtual USB controllers when you have large environments with multiple vCenters & ESXi?

There is a new exploit vulnerability as per of VMware Security Advisory VMSA-2019-0005 taking advantage of VMs with virtual USB 1.1 UHCI (a.k.a. vUSB)

We got this one-liner PowerCLI command from our own Technical Account Manager at VMware:

(get-vm |Get-View).Config.Hardware.Device|Select -Expand DeviceInfo | Select Label, Summary | where {$_.Label –match "USB Controller"}

0 Kudos
Leadership
Leadership

Try something like this

Get-View -ViewType VirtualMachine -Property Name, Config.Hardware.Device -PipelineVariable vm |

ForEach-Object -Process {

   $_.Config.Hardware.Device | where { $_ -is [VMware.Vim.VirtualUsb] -or

   $_ -is [VMware.Vim.VirtualUsbController] -or

   $_ -is [VMware.Vim.VirtualUSBXHCIController] } |

  select @{N = 'VM'; E = { $vm.Name } }, @{N = 'Label'; E = { $_.DeviceInfo.Label } }

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Contributor
Contributor

Hello,

could you help me with removing VirtualUSBController from VM's over script? I found a lot of VM's in our environments and we need to remove it from all VM's.

 

David

0 Kudos
Leadership
Leadership

I suggest you open a new thread for that question


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Contributor
Contributor

Ok. No problem. On the other hand this thread continue on your USB finder. Can I create new thread on this or you will create it?

David 

0 Kudos
Leadership
Leadership

That  function is quite old, in the meantime PowerCLI has the Get-UsbDevice and Remove-UsbDevice cmdlets.
Please create the thread


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos