Installing open-vm-tools deployPkg plug-in for Ubuntu Guest Operating Systems

If you are installing the open source implementation of VMware Tools ‘open-vm-tools’ into your guest operating system and require to use the virtual machine as a template or leverage Site Recovery Manager to customize virtual machines after failover, then there is a requirement to install the ‘deployPkg Tools’ plug-in.

The below details installing the plug-in on an Ubuntu operating system, however steps for other operating systems can be found here.

Firstly, we will need to obtain and import the VMware Packaging Public keys which can be downloaded from here and the files are required to be saved into a directory on the guest operating system.  For each key downloaded, we will import the key on successful completion you should receive the below notification:

sudo apt-key add /tmp/keys/
sudo apt-key add /tmp/keys/

We will now create the file ‘/etc/apt/sources.list.d/vmware-tools.list’ to add the below package repository and update the package index.

deb precise main
sudo apt-get update

Once the package index has been updated we can invoke the following to install the ‘deployPKG’ plug-in. Once installed you should be able to customize your template or virtual machine for failover using Site Recovery Manager.

sudo apt-get install open-vm-tools-deploypkg

Component of the virtual machine is not accessible on the host when converting a template to a virtual machine

I was recently converting a template to a virtual machine for configuration when on performing the action to convert the template to a virtual machine using the vSphere Web Client I received the following error message:

A component of the virtual machine is not accessible on the host.

The cause of the above issue was due to due a component being attached to the virtual machine which was no longer available. in this case a virtual CD-ROM device connected to a Datastore ISO file. In order to resolve the issue I was required to modify the templates configuration file to remove the component that was no longer available. Firstly, from the vSphere Web Client I will remove the virtual machine template from the inventory and then connect to an ESXi host system which has access to the datastore to which the virtual machine is located using an SSH client.

Prior to modifying the configuration file, we will firstly create a backup of the configuration file in the existing folder in the event we need to roll back to the original configuration file.

cp /vmfs/volumes/54d9d092-5163b8c5-4ed9-5cf3fc946a28/deanvm1/deanvm1.vmtx /vmfs/volumes/54d9d092-5163b8c5-4ed9-5cf3fc946a28/deanvm1/deanvm1.vmtx.backup

Now we will be required to modify the configuration file using a text editor such, in this example ‘vi’.

vi /vmfs/volumes/54d9d092-5163b8c5-4ed9-5cf3fc946a28/deanvm1/deanvm1.vmtx

In this scenario we will need to modify the reference to the obsolete file being referenced and also modify the device type to the below and save the configuration file.

sata0:0.deviceType = "atapi-cdrom"
sata0:0.fileName = "

From the ESXi host system we will now register the virtual machine template, once the virtual machine template has been registered you will need to convert this from a virtual machine to a template using the vSphere Web Client.

vim-cmd solo/registervm /vmfs/volumes/54d9d092-5163b8c5-4ed9-5cf3fc946a28/deanvm1/deanvm1.vmx

Retrieving Virtual Machine Templates as vSphere View Objects

It is possible to retreive virtual machine template information using the Get-View cmdlet, by retrieving VirtualMachine type objects based on the property value that describes the object as a template to which the value is returned as a boolean value.

To retrieve VirtualMachine objects , the property value we require to retrieve is Config.Template where the value is ‘True’, which can be achieved as follows:

Get-View -ViewType VirtualMachine -Property Name, Config.Template | Where-Object {$_.Config.Template -eq "True"}

In my example, I required not to include virtual machine templates in the collection of VirtualMachine objects and there selecting only objects where the property value was not equal to ‘True’.

Get-View -ViewType VirtualMachine -Property Name, Config.Template | Where-Object {$_.Config.Template -ne "True"}

For the Property value I am specifying only the Name and Config.Template properties of the view object as this is only what I require, but in your use case you may want to extend the properties retrieved.

Waiting on virtual machine Guest OS customization to complete

I recently discovered a blog article from Vitali Baruh on the PowerCLI QE team in regards to waiting for the guest OS customization to complete following a deployment of a virtual machine from a template.

As Vitali discusses this process can be difficult to determine if this has completed in the guest operating system and if the task had completed successfully.

Previously, following the power on of a deployed virtual machine from a template I have performed a Do…Until loop to process a condition until the ‘Guest.HostName’ value retrieved from the Get-View cmdlet matches the name of the virtual machine as below:

    $GuestHostName = (Get-View $VM.Id).Guest.HostName
    Start-Sleep -Seconds 10
Until ($GuestHostName -eq $VM.Name)

Whilst I have received no issues from this, there is an argument agaisnt using this method as we are not retrieving the guest OS customization task status. Now, this is where Vitali has produced an excellent blog post to describe the steps of this function which is based on a number of virtual machine events generated by the vCenter server.

The script workflow, works as follows:

  • 1. For each VM we will look for the last VmStarting event, because the customization process starts after the VM has been powered on
    • 1.1. If such an event is found, change the status to “CustomizationNotStarted”
    • 1.2. If such an event is not found, change the status to “VmNotStarted”
  • 2. Start a loop
    • 2.1. For each VM with status “CustomizationNotStarted”
      • 2.1.1. Check for posted CustomizationStartedEvent after the last power-on operation
        • If such an event is found, change the status to “CustomizationStarted”
    • 2.2. For each VM with status “CustomizationStarted”
      • 2.2.1. Check for Succeded or Failed Event
        • If such an event is found, change the status to the corresponding “CustomizationSucceeded” or“CustomizationFailed” values
    • 2.3. Check is there more VMs with status “CustomizationNotStarted” or “CustomizationStarted” (we should continue to monitor these VMs)
      • 2.3.1. If no, break the loop
    • 2.4. Check whether the specified timeout has elapsed
      • 2.4.1. If yes, break the loop
  • 3. Return result

For those who are provisioning virtual machines to include a guest OS customization with PowerCLI, I would definitely recommend a read of this article.


Retrieve Template Information using PowerCLI

It is possible to retrieve template information using the Get-Template cmdlet to obtain a number of properties. In this example I will be looking to retrieve the following items and export to comma-separated values (CSV) file:

  • Name
  • vCPU
  • Memory
  • Number of Hard Disks
  • Size of Hard Disks

Firstly, we will connect to the VI Server and return a collection of templates using the Get-Template cmdlet.

If (-not (Get-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue)) 
    Add-PSSnapin VMware.VimAutomation.Core > $null

Connect-VIServer server1.domain.local
$Templates = Get-Template

For each template  in the collection we will retrieve the above items and store these in a variable for exporting to a CSV file. For the number of hard disks, these will count the number retrieved and for size join the values to a single string by invoking the Get-HardDisk cmdlet.

$Inventory= ForEach ($Template in$Templates)

"" | Select-Object -Property @{N="Name";E={$Template.Name}},
      @{N="Memory (MB)";E={$Template.ExtensionData.Config.Hardware.MemoryMB}},    
      @{N="Number of Hard Disks";E={($Template | Get-HardDisk | Measure-Object).Count}},
      @{N="Size of Hard Disks";E={[string]::Join(',',(($Template |Get-HardDisk).CapacityKB))}}

$Inventory | Export-Csv -NoTypeInformation -UseCulture -Path ("D:\Output\" + [guid]::NewGuid() + "-inv_template.csv")