The VMware Workspace ONE Unified Access Gateway (UAG) has continued to ramp up for VMware customers everywhere. We all need them now for our WS1 infrastructure whether its Horizon, VMware Tunnel, SEG, or Content Gateway. I’ve continued to see many customers not fully understand the right way to deploy a UAG, which we will cover today.
We are going to discuss the OVF Tool and UAGDeploy Scripts, building the RIGHT template, and deploying that template. The UAG is not for those of the feint of heart and it MUST be done correctly. I continue to see more and more people using “Deploy OVF” in the GUI and it makes me die a little bit on the inside:

The Infrastructure Behind UAG Deployments
Many of you are familiar with some of my articles I’ve written about the UAG like my WS1 Deep Dive into the UAG, but I have never focused too heavily on the UAG deployment, but I think it’s now time because people don’t seem to get it. We’re going to start by discussing the OVF Tool.
The OVF Tool
The OVF Tool is the underpinning technology that powers the UAG deployment. My typical recommendation is to run the latest supported version, but you want to pay attention to any irregularities in your deployments. When you have issues, downgrade and don’t waste time.
You might wonder why do we use OVFs? Typically we have a few reasons for leveraging the OVF format:
- Much easier to use
- OVFs support fast and robust hardware validation
- Metadata can be packaged into the OVF e.g. EULAs
- Download optimization
We use the OVF tool because it is very effective with conversion to vSphere, tools integrate very well into the OVF tool, performs signature validation, performs optimized uploads and downloads via the API, and is very flexible in general. The UAG is another example as the UAG deployment works directly with the OVF tool to seamlessly deploy new UAGs using the exact resources and put in the exact location you need. Instead of reinventing the wheel, let’s check out an OVF tool deployment below.
Leveraging UAGDeploy PowerShell Scripts
Once you have deployed the OVF Tool, we download and copy the UAGDeploy scripts. You go to the typical place where you download the OVA here and download your UAG PowerShell scripts. Pretty simply, its a PowerShell script and some example .INI files.

The idea is relatively simple. You build an .INI aka configuration file and pass it as an argument to the UAGdeploy.ps1 script to build your UAGs seamlessly with zero post-configuration. Let’s talk about my sample UAG deployment script.
Building your UAG Deployment Template
Let’s dig into the UAG deployment template. You can find my example template here, but we will break down each part of the template to show you how to build the perfect deployment template that will make your UAG deployments zero touch.
General and vSphere Settings
The major roadblock you will run into is crafting the VI Path. Let’s look at the beginning of the example code:
[General]
#
# UAG virtual appliance unique name (between 1 and 32 characters).
# If name is not specified, the script will prompt for it.
#
name=uag.mobile-jon.com
#
# Full path filename of the UAG .ova virtual machine image
# The file can be obtained from VMware
#
source=C:\UAGDeploy\uag-2012.ova
#
# target refers to the vCenter username and address/hostname and the ESXi host for deployment
# Refer to the ovftool documentation for information about the target syntax.
# See https://www.vmware.com/support/developer/ovf/
# PASSWORD in upper case results in a password prompt during deployment so that passwords do not need
# to specified in this .INI file.
# In this example, the vCenter username is administrator@vsphere.local
# the vCenter server is 192.168.0.21 (this can be a hostname or IP address)
# the ESXi hostname is esx1.myco.int (this can be a hostname or IP address)
#
target=vi://DOMAIN\USERNAME:PASSWORD@VSPHERE/DATACENTER/FOLDER/ESXI
Your target VI path should be the username, followed by the word PASSWORD (so you can input the password yourself when prompted), followed by the vSphere server, followed by the datacenter name, followed by the folder path, followed by the esxi host, such as:
target=vi://administrator@vsphere.local:PASSWORD@vsphere01.mobile-jon.com/BostonDataCenter/Cluster1/esxi01.mobilejon.com
Something to point out is you “may” need to encode the password for your administrator account. A great article on this can be found here. I ran into this at one client, which required me to use %40 instead of the @ symbol, which can be found in an ASCII reference article.
One of the neat things about if you struggle with the VI path is it will provide you with possible values if you test with a minimal path e.g. target=vi://administrator@vsphere.local:PASSWORD@vsphere01.mobile-jon.com with responses like this:
target=vi://administrator@vsphere.local:PASSWORD@vsphere01.mobile-jon.com/BostonDataCenter
target=vi://administrator@vsphere.local:PASSWORD@vsphere01.mobile-jon.com/LondonDataCenter
One other area to focus on is the datastore and folder path:
ds=MobileJon01_1
folder=BostonDataCenter/WorkspaceONE
Typically, these are just the name of the datastore in the vSphere GUI and the logical folder path. If you keep getting “invalid VM folder” you should just try to keep it simple and specify the first folder name you see. Some trial and error might be needed there.
Network Settings
As you can see below, network settings aren’t too bad. You specify your virtual adapter names and configure your deployment type, network settings, etc. The main key here is to setup EXACTLY what you need. Don’t create manual process afterwards. That means routes, DNS, syslog, etc.
netInternet=VMNetwork
netManagementNetwork=VMNetwork
netBackendNetwork=VMNetwork
deploymentOption=onenic-large
ip0=192.168.1.50
netmask0=255.255.255.0
defaultGateway=192.168.1.1
routes0=192.168.1.0/24 192.168.0.1,
192.168.2.0/24 192.168.0.2
#deploymentOption=twonic
#ip0=192.168.0.90
#netmask0=255.255.255.0
#ip1=192.168.0.91
#netmask1=255.255.255.0
#deploymentOption=threenic
#ip0=192.168.0.90
#netmask0=255.255.255.0
#ip1=192.168.0.91
#netmask1=255.255.255.0
#ip2=192.168.0.92
#netmask2=255.255.255.0
dns=4.2.2.2 8.8.8.8
syslogUrl=syslog://syslog.mobile-jon.com:514
UAG General Settings
I typically recommend using the settings that I reference below. They’re pretty basic outside of make sure you enable TLS Port Sharing if you have multiple UEM services.
sshKeyAccessEnabled=false
fipsEnabled=false
sysLogType=UDP
uagName=uag.mobile-jon.com
clockSkewTolerance=600
locale=en_US
tls12Enabled=true
ipMode=STATICV4
requestTimeoutMsec=0
tls11Enabled=false
clientConnectionIdleTimeout=360
tls10Enabled=false
adminCertRolledBack=false
ntpServers=ntp.mobile-jon.com
cookiesToBeCached=*
snmpEnabled=false
healthCheckURL=/favicon.ico
quiesceMode=false
sshEnabled=true
sshPasswordAccessEnabled=true
isCiphersSetByUser=false
tlsPortSharingEnabled=true
ceipEnabled=false
bodyReceiveTimeoutMsec=0
monitorInterval=60
maxConnectionsAllowedPerSession=16
cipherSuites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
adminPasswordExpirationDays=0
httpConnectionTimeout=120
isTLS11SetByUser=false
sessionTimeout=36000000
ssl30Enabled=false
fallBackNtpServers=ntp2.mobile-jon.com
honorCipherOrder=true
Certificate Deployment
The more deployments that I do, the more I am leaning toward using PEM over PFX. There have been more issues with PFX as of late so as you can see below, I am using a Private Key and PEM certificate:
[SSLCert]
#
# From UAG 3.0 and newer, you can specify the name of a .pfx or .12 format certificate file containing the required certificate and private key and
# any required intermediate certificates. In this case there is no need to use openssl commands to convert the .pfx/.p12 file into the
# associated PEM certificates file and PEM private key file.
#
#pfxCerts=[CERTPATH]
#
# If there are multiple SSL certificates with private key in the .pfx file you also need to specify an alias name in order to select the required certificate.
# This is not necessary if there is only one SSL certificate with private key in the file
#
#pfxCertAlias=alias1
#
# The following pemCerts and pemPrivKey settings are only needed if you don't have a .pfx/.p12 file and want to directly use the two PEM format files.
#
# pemCerts refers to a PEM format file containing the SSL server certificate to be deployed. The file should also contain any
# required intermediate CA and root CA certificates.
#
pemCerts=C:\UAGDeploy\uag.pem
# pemPrivKey refers to a file containing the RSA PRIVATE KEY for the SSL server certificate in the above certificate file.
#
pemPrivKey=C:\UAGDeploy\uagkey.pem
#
# From UAG 3.2 and newer, you can specify a certificate for the admin interface on port 9443. It is in the same format as [SSLCert] above.
#
[SSLCertAdmin]
#pfxCerts=[CERTPATH]
pemCerts=C:\UAGDeploy\uag.pem
pemPrivKey=C:\UAGDeploy\uagkey.pem
Below, is the code you need to pull out the pem and key from your PFXs for my recommendation:
openssl pkcs12 -in uag.pfx -nocerts -out uagkey.pem -nodes
openssl pkcs12 -in uag.pfx -nokeys -out uag.pem
openssl rsa -in uagkey.pem -out uagkey.key
Workspace ONE UEM Configuration
You can see my example code below for the UEM services. A few things to point out:
- API passwords will always prompt you during the UAGDeploy so its pointless here.
- Make sure your trusted certificates for backend communication are present.
- Make sure your health check URLs are solid.
- “Airwatch” is for Tunnel.
[Airwatch]
tunnelGatewayEnabled=true
apiServerUrl=as420.awmdm.com
apiServerUsername=uagadmin
apiServerPassword=
organizationGroupCode=mobilejon
airwatchServerHostname=tunnel.mobile-jon.com
ntlmAuthentication=false
healthCheckURL=/favicon.ico
airwatchOutboundProxy=false
reinitializeGatewayProcess=false
trustedCert1=C:\UAGDeploy\root.cer
trustedCert2=C:\UAGDeploy\int.cer
[AirwatchSecureEmailGateway]
memConfigurationID=XXXXXXXX-XXXX-XXXX-XXX-XXXXXXXXXXX
apiServerUsername=uagadmin
trustedCert1=C:\UAGDeploy\root.cer
trustedCert2=C:\UAGDeploy\int.cer
ntlmAuthentication=false
healthCheckURL=/favicon.ico
apiServerUrl=as420.awmdm.com
airwatchOutboundProxy=
apiServerPassword=
reinitializeGatewayProcess=
airwatchServerHostname=seg.mobile-jon.com
[AirwatchContentGateway]
cgConfigId=
apiServerUsername=
trustedCert1=
ntlmAuthentication=false
apiServerUrl=
airwatchOutboundProxy=false
apiServerPassword=
reinitializeGatewayProcess=false
airwatchServerHostname=
UAG Deployment via UAG Deploy
The actual deployment is very simple once you have everything solid. You can see an example below:

The great thing about using private keys and PEM certificates is you eliminate 1/3 of the password prompts through deployments, which is never bad. You simply just:
.\uagdeploy.ps1 -iniFile mobilejon.ini
The idea is that you build something that is rinse and repeat. That means updating your config file when you make changes like disabling specific ciphers, modifying timeouts, etc. A few things to keep in mind when you deploy:
- Disable the NICs, power down the old UAG prior to deployment, and re-name it.
- Make sure you have your certificates, valid routes, and credentials ready when deploying so you can be successful.
- Don’t be a hero! Ask for help so you don’t spend 10 hours trying to figure it out.
- If you have issues, downgrade your OVF Tool right away instead of being stubborn.

Final Thoughts
UAG deployments can be intimidating, but they don’t have to be. Put in the time and effort to build a great template to make your upgrades seamless. You can take an upgrade from hours to minutes with strong design and a thorough template. The Unified Access Gateway is here to stay! It’s time to stop avoiding it and tackle it to deliver a great user experience. Many services run so MUCH better now on the UAG, such as the VMware Tunnel. Don’t be afraid to ask for help because once you build the foundation you will be rock solid!