Guest Hardware

Working with VM Devices in PowerCLI

AlanFeb2012_thumb_thumb1_thumb_thumb[2]
Posted by
Alan Renouf
Technical Marketing

Recently I was asked if it was possible to list all VMs which had particular devices attached to them, and further to this, was there any way to remove the device from the VM or multiple VMs on mass.

To address this question lets look at the types of devices which can be used by a VM:

image

Some of these devices are more popular than others, most VMs will have a Hard Disk and an Ethernet Adapter but I rarely see a VM with a Parallel or Serial port, so lets see which of these items we support out of the box in PowerCLI.

Floppy Drives CD/DVD Drive USB Device Ethernet Adapter Hard Disk SCSI Device

Get-FloppyDrive
New-FloppyDrive
Remove-FloppyDrive
Set-FloppyDrive

Get-CDDrive
New-CDDrive
Remove-CDDrive
Set-CDDrive

Get-USBDevice
Remove-USBDevice

Get-NetworkAdapter
New-NetworkAdapter
Remove-NetworkAdapter
Set-NetworkAdapter

Copy-HardDisk
Get-HardDisk
New-HardDisk
Remove-HardDisk
Set-HardDisk

Get-ScsiController
New-ScsiController
Set-ScsiController

 

Using Device cmdlets

Lets take a look at the Floppy Drive cmdlets and how we might use these, starting with a list of our VMs which have a Floppy Drive attached, in this case I am showing my DemoVMs and their floppy details:

SNAGHTML57bc10a

We can also easily disconnect a floppy drive as seen below:

SNAGHTML57e7e30

And remember, this can be done for all virtual machines not just one. So what if we didn’t want the floppy drives at all, I mean how often do you use a floppy drive?

SNAGHTML5809b70

Notice the first VM gave us an error, this is of course because it was powered on, just as with the vSphere Client we must Power Off the VM before removing Floppy Drives.  You can see from the screenshot above that the floppy drives have been removed from our other machines, this can of course be confirmed by looking within the vSphere client.

What about the other devices ?

We have covered Floppy Drives in the above example but the other devices which have cmdlets will work in a similar way, remember if you cant work it out Get-Help is your friend, examples from any of the PowerCLI or PowerShell cmdlets can be seen by simply using Get-Help as below:

SNAGHTML586cccd

But what about the devices which don’t have cmdlets to work with them, what if you had a serial port or parallel port you wanted to remove on mass, I have seen this before when people have converted their physical hosts to virtual machines, sometimes they have not removed the serial and parallel ports which are no longer needed by the VMs.

We can use PowerCLI to look further into our VM objects and see which hardware devices are present on a virtual machine with a single line of code:

SNAGHTML59028f0

As you can see from the above example, each of the hardware devices listed under the Config.Hardware part of the virtual machine has a different type, and in this list we can see both the SerialPort and ParallelPort types.  Using this we can easily create some advanced functions which allow us to work with these devices.

Once the code at the bottom of this post is imported into our session we can list the serial ports attached to our virtual machines and also the parallel ports attached like so:

SNAGHTML5958c25

And of course we can remove these on mass as well by using the following:

SNAGHTML59764a8

Serial/Parallel port management scripts

Copy and paste the following code into your PowerCLI Console or PowerShell editor and run them to help you work with Serial and Parallel ports on mass.

Function Get-SerialPort {
    Param (
        [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)]
        $VM
    )
    Process {
        Foreach ($VMachine in $VM) {
            Foreach ($Device in $VMachine.ExtensionData.Config.Hardware.Device) {
                If ($Device.gettype().Name -eq "VirtualSerialPort"){
                    $Details = New-Object PsObject
                    $Details | Add-Member Noteproperty VM -Value $VMachine
                    $Details | Add-Member Noteproperty Name -Value $Device.DeviceInfo.Label
                    If ($Device.Backing.FileName) { $Details | Add-Member Noteproperty Filename -Value $Device.Backing.FileName }
                    If ($Device.Backing.Datastore) { $Details | Add-Member Noteproperty Datastore -Value $Device.Backing.Datastore }
                    If ($Device.Backing.DeviceName) { $Details | Add-Member Noteproperty DeviceName -Value $Device.Backing.DeviceName }
                    $Details | Add-Member Noteproperty Connected -Value $Device.Connectable.Connected
                    $Details | Add-Member Noteproperty StartConnected -Value $Device.Connectable.StartConnected
                    $Details
                }
            }
        }
    }
}

Function Remove-SerialPort {
    Param (
        [Parameter(Mandatory=$True,ValueFromPipelinebyPropertyName=$True)]
        $VM,
        [Parameter(Mandatory=$True,ValueFromPipelinebyPropertyName=$True)]
        $Name
    )
    Process {
        $VMSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
        $VMSpec.deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec
        $VMSpec.deviceChange[0] = New-Object VMware.Vim.VirtualDeviceConfigSpec
        $VMSpec.deviceChange[0].operation = "remove"
        $Device = $VM.ExtensionData.Config.Hardware.Device | Foreach {
            $_ | Where {$_.gettype().Name -eq "VirtualSerialPort"} | Where { $_.DeviceInfo.Label -eq $Name }
        }
        $VMSpec.deviceChange[0].device = $Device
        $VM.ExtensionData.ReconfigVM_Task($VMSpec)
    }
}

Function Get-ParallelPort {
    Param (
        [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)]
        $VM
    )
    Process {
        Foreach ($VMachine in $VM) {
            Foreach ($Device in $VMachine.ExtensionData.Config.Hardware.Device) {
                If ($Device.gettype().Name -eq "VirtualParallelPort"){
                    $Details = New-Object PsObject
                    $Details | Add-Member Noteproperty VM -Value $VMachine
                    $Details | Add-Member Noteproperty Name -Value $Device.DeviceInfo.Label
                    If ($Device.Backing.FileName) { $Details | Add-Member Noteproperty Filename -Value $Device.Backing.FileName }
                    If ($Device.Backing.Datastore) { $Details | Add-Member Noteproperty Datastore -Value $Device.Backing.Datastore }
                    If ($Device.Backing.DeviceName) { $Details | Add-Member Noteproperty DeviceName -Value $Device.Backing.DeviceName }
                    $Details | Add-Member Noteproperty Connected -Value $Device.Connectable.Connected
                    $Details | Add-Member Noteproperty StartConnected -Value $Device.Connectable.StartConnected
                    $Details
                }
            }
        }
    }
}

Function Remove-ParallelPort {
    Param (
        [Parameter(Mandatory=$True,ValueFromPipelinebyPropertyName=$True)]
        $VM,
        [Parameter(Mandatory=$True,ValueFromPipelinebyPropertyName=$True)]
        $Name
    )
    Process {
        $VMSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
        $VMSpec.deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec
        $VMSpec.deviceChange[0] = New-Object VMware.Vim.VirtualDeviceConfigSpec
        $VMSpec.deviceChange[0].operation = "remove"
        $Device = $VM.ExtensionData.Config.Hardware.Device | Foreach {
            $_ | Where {$_.gettype().Name -eq "VirtualParallelPort"} | Where { $_.DeviceInfo.Label -eq $Name }
        }
        $VMSpec.deviceChange[0].device = $Device
        $VM.ExtensionData.ReconfigVM_Task($VMSpec)
    }
}

 

Get notification of new blog postings and more by following VMware PowerCLI on Twitter: @PowerCLI