Tuesday, May 8, 2012

Working with VM Devices in PowerCLI

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

ICT4PE&D

No comments:

Post a Comment

Thank's!