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")

Create VM annotation based on deployed template name

I was recently looking to create a virtual machine annotation type to include the template name to which a virtual machine was deployed from.

I was able to achieve this by using the Get-VIEvent cmdlet to return a match for a virtual machine where the event was equal to “VmBeingDeployedEvent” and formatting the output string to only include the template name.

As I plan to run the above as a scheduled task, I will load the PowerCLI snap-in in the current powershell session and connect to a vcenter server (in this example, server1.domain.local).

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

Connect-VIServer server1.domain.local

Firstly, I wanted to return a collection of virtual machines and to check from the first virtual machine if the annotation ‘Template’ exists and if¬†not create this object

$VMS = Get-VM 
$VM = $VMs | Select -First 1
If (-not $vm.CustomFields.ContainsKey("Template")) 
   New-CustomAttribute -TargetType VirtualMachine -Name Template | Out-Null

Now, that we have created the annotation if this currently did not exist, we will now query each virtual machine in the collection to determine if an event is returned for “VmBeingDeployedEvent”.

ForEach ($VM in $VMs)
   $Event = $VM | Get-VIEvent -Types Info | Where-Object {$_.Gettype().Name-eq "VmBeingDeployedEvent"}

The FullFormatMessage property returned will have a string relating to the “VmBeingDeployedEvent” which will identity the template used for the VM, the string is expected as below:

"Deploying <virtual machine> on host <Host> in <Cluster> from template <template name>"

If the $Event.FullFormatMessage contains ‘template’ in the returned string, the string will be manipulated to only return characters after the word template, which will allow for the template name to be stored as a variable. The returned variable will then be used to set the value for the annotation using the Set-CustomField cmdlet.

If ($Event.FullFormattedMessage -like "*template*") 
   $Template = $Event.FullFormattedMessage  | select-string -pattern '(?<=template)(.*)'  |  select -expa matches | select -expa value |  % { $_.trim() }
   $VM | Set-CustomField -Name "Template" -Value $Template

Guest Customization of VM fails with “Error : Could not create file /etc/dhcp3/dhclient.conf!”

I was recently deploying VMs from a Ubuntu template using guest customisation, where guest customization fails and the IP address also fails to be updated with the following error:

An error occurred while customizing <VM>. For details, reference the log file /var/log/vmware-imc/toolsDeployPkg.log in the guest OS

On investigating the log file, the following error has been generated:

ERROR: Error : Could not create file /etc/dhcp3/dhclient.conf!

The cause of this issue is due to VMware Tools being unable to create a file in the /etc/dhcp3 directory as this does not exit.

In order to resolve the issue, you will need to create the directory by converting the template to a VM, making the below change and converting back to a template for deployment.

mkdir /etc/dhcp3