Building Virtual Appliances with OVF Properties and GuestInfo

March 4, 2026 0 By Allan Kjaer

I’m currently working on building virtual appliances that require configuration inputs during deployment.

There are several ways to create a virtual appliance (I’ll cover those methods in a future post). One simple and effective approach is:

  1. Create and configure a Virtual Machine
  2. Export it as an OVF/OVA using:
    • The vSphere UI
    • PowerCLI
    • The vSphere API

In this post, I’ll focus on how to add deployment-time inputs (OVF properties) and how to reliably read them inside a Linux guest.

Adding Inputs to the OVF File

To allow the guest operating system to access deployment properties via guestinfo, you must modify the .ovf file.

Inside the VirtualHardwareSection, add the following attribute:

      <VirtualHardwareSection ovf:transport="com.vmware.guestInfo">

Understanding OVA vs OVF

An OVA file is simply a packaged version of the OVF format.

  • .ovf → XML descriptor file
  • .vmdk → Disk files
  • .mf → Manifest (checksum file)
  • .ova → A single archive containing all of the above

Technically, an .ova is just a TAR archive (often described as similar to a zip file).

To modify it:

  1. Extract the OVA file
  2. Edit the .ovf file
  3. Update or remove the .mf file

Important Note About the .mf File

The .mf file contains checksums for validation.

If you modify the .ovf, you must:

Delete the .mf file (this disables integrity validation — not recommended for production use)

  • Recalculate and update the checksum in the .mf file or
  • Delete the .mf file (this disables integrity validation — not recommended for production use)

Adding OVF Deployment Properties

Deployment inputs are added inside a <ProductSection> in the OVF file.

Example:

    <ProductSection ovf:required="true">
      <Info>Information about the installed software</Info>
      <Product>Allan Kjaer Virtual Appliance (AKVA)</Product>
      <Vendor>Virtuel-Allan.com</Vendor>
      <Version>v0.0.1</Version>
      <ProductUrl>https://github.com/</ProductUrl>
      <VendorUrl>https://www.virtual-allan.com/
      <Category>Config</Category>
        <Property ovf:key="akva.hostname" ovf:type="string" ovf:userConfigurable="true" >
            <Label>Input hostname (FQDN)</Label>
            <Description>Hostname for the Appliance</Description>
        </Property>
        <Property ovf:key="akva.function" ovf:type="string" ovf:userConfigurable="true" ovf:qualifiers="ValueMap{&quot;1&quot;,&quot;2&quot;}">
            <Label>Appliance fuction</Label>
            <Description>Function (1. Server, 2 Client)</Description>
        </Property>
        <Property ovf:key="akva.password" ovf:type="string" ovf:password="true" ovf:userConfigurable="true">
            <Label>root Password</Label>
        </Property>
        <Property ovf:key="akva.debug" ovf:type="boolean" ovf:userConfigurable="true"  ovf:value="false">
            <Label>Use Debug looging</Label>
            <Description>Enabling Debug logging will create a lot of log files</Description>
        </Property>
    </ProductSection>

Reading OVF Properties in Linux

There are some great blog posts about this topic, including one by William Lam:

However, there’s an important caveat.

The Problem: vCenter vs Standalone ESXi

The format of guestinfo.ovfEnv differs depending on how the appliance is deployed:

Deployment Targetguestinfo Format
vCenterFormatted XML
Standalone ESXiSingle-line XML

William Lam’s example works well when deploying through vCenter, but when deploying directly to a standalone ESXi host, the returned XML is a single line. That breaks parsing logic that expects formatted XML.

A More Robust Script

Below is a script that works in both scenarios by explicitly formatting the XML before parsing it.

get-ova-property()
{
    cat /tmp/guestinfoformatted.xml | grep $1 | awk '{print $3}' | sed -E 's/oe:value=\"//' | sed -E 's/\"\/>//'
}

read-ova-property()
{	 
	while [ `/bin/guestinfosd --cmd 'info-get guestinfo.ovfEnv' > /tmp/guestinfo.xml 2>/tmp/guestinfo_err.log; echo $?` -ne 0 ]
	  do
		sleep 30
		if [ $retry -gt 1 ]
		then
		  echo "guestinfosd not running properly" >> /tmp/guestinfo_err.log
		  break
		else
		  retry=$(($retry+1))
		fi
	  done
	 
	xmllint --format  /tmp/guestinfo.xml > /tmp/guestinfoformatted.xml
}

read-ova-property
HOSTNAME=$(get-ova-property akva.hostname)

Final Thoughts

When building virtual appliances using OVF properties:

  • Always enable ovf:transport="com.vmware.guestInfo"
  • Be aware of deployment differences between vCenter and ESXi
  • Handle XML formatting differences in your parsing scripts
  • Maintain checksum integrity when modifying OVF files

This approach makes your appliance more flexible and production-ready across different deployment scenarios.

Please share this page if you find it usefull: