Automating VDI Template Creation with VMware Code Stream and HashiCorp Packer – Part 2: Installing the VDI Agents

In part 1 of this series, we built a Windows 10 desktop using HashiCorp Packer. Now we will script the installation of the VDI agents needed for our VMware Horizon environment. After this, we will patch the box with the latest updates, before applying the VMware OS Optimization Tool to produce a lean and clean image. In the last part, we will automate the solution using VMware Code Stream.

Other posts in this series:

  1. Building Windows
  2. Installing the VDI Agents
  3. Automating the Solution

Agents

As mentioned in part 1, our Windows 10 desktops are linked clones that do not require any software in the base image other than the AppVolumes, Dynamic Environment Manager and Horizon agents.

Here we go…

The astute amongst us will notice that each of the following scripts are nothing but subtle variations of each other. Each script is stored in the setup folder (see part 1) and referenced in the windows-10.json file.

Each script will need to pull the appropriate agent from a network file share. I store mine on an unauthenticated Intranet box, but please feel to use the storage host/protocol of your choice.

The first script is to import my trusted root and issuing CA certificates. As my AppVolumes server is secured with certificates issued from my in-house, two-tier certificate authority, I need these new (non-domain-joined at this point) desktops to trust this server. To do this I import my two certificates before they are joined to the domain as part of the Horizon provisioning process.

If this applies to you, then create a script called certs.ps1 and add the following. If not, then you can skip this section and modify the AppVolumes installation script accordingly:

$ErrorActionPreference = "Stop"

$webserver = "intranet.mdb-lab.com"
$url = "http://" + $webserver
$certRoot = "root64.crt"
$certIssuing = "issuing.crt"

# Verify connectivity
Test-Connection $webserver -Count 1

# Get certificates
ForEach ($cert in $certRoot,$certIssuing) {
  Invoke-WebRequest -Uri ($url + "/" + $cert) -OutFile C:\$cert
}

# Import Root CA certificate
Import-Certificate -FilePath C:\$certRoot -CertStoreLocation 'Cert:\LocalMachine\Root'

# Import Issuing CA certificate
Import-Certificate -FilePath C:\$certIssuing -CertStoreLocation 'Cert:\LocalMachine\CA'

# Delete certificates
ForEach ($cert in $certRoot,$certIssuing) {
  Remove-Item C:\$cert -Confirm:$false
}

Things to note:

  • Line 3: the location of your server hosting the certs
  • Line 4-5: the certs. In HobbitCloud we build everything with pukka certificates, no matter the pain…

Now when we install the App Volumes Agent, it will trust the certificate that secures the AppVolumes server without issue.

The Agents

As mentioned previously, the following are simply variations of one another. Create three PowerShell files called appvolumes.ps1, dem.ps1 and agent.ps1 (substitute accordingly):

appvolumes.ps1:

$ErrorActionPreference = "Stop"

$webserver = "intranet.mdb-lab.com"
$url = "http://" + $webserver
$installer = "App Volumes Agent.msi"
$appVolumesServer = "nl-utc-p-aps-01.nl.mdb-lab.com"
$listConfig = "/i ""C:\$installer"" /qn REBOOT=ReallySuppress MANAGER_ADDR=$appVolumesServer MANAGER_PORT=443"

# Verify connectivity
Test-Connection $webserver -Count 1

# Get AppVolumes Agent
Invoke-WebRequest -Uri ($url + "/" + $installer) -OutFile C:\$installer

# Unblock installer
Unblock-File C:\$installer -Confirm:$false

# Install AppVolumes Agent
Try 
{
   Start-Process msiexec.exe -ArgumentList $listConfig -PassThru -Wait
}
Catch
{
   Write-Error "Failed to install the AppVolumes Agent"
   Write-Error $_.Exception
   Exit -1 
}

# Cleanup on aisle 4...
Remove-Item C:\$installer -Confirm:$false

dem.ps1:

$ErrorActionPreference = "Stop"

$webserver = "intranet.mdb-lab.com"
$url = "http://" + $webserver
$installer = "VMware Dynamic Environment Manager 9.9 x64.msi"
$licence = "dem.lic"
$listConfig = "/i ""C:\$installer"" /qn /norestart ADDLOCAL=FlexEngine LICENSEFILE=dem.lic"

# Verify connectivity
Test-Connection $webserver -Count 1

# Get Files
ForEach ($file in $installer,$licence) {
   Invoke-WebRequest -Uri ($url + "/" + $file) -OutFile C:\$file
}

# Unblock installer
Unblock-File C:\$installer -Confirm:$false

# Install DEM Agent
Try 
{
   Start-Process msiexec.exe -ArgumentList $listConfig -PassThru -Wait
}
Catch
{
   Write-Error "Failed to install the DEM Agent"
   Write-Error $_.Exception
   Exit -1 
}

# Cleanup on aisle 4...
ForEach ($file in $installer,$licence) {
   Remove-Item C:\$file -Confirm:$false
}

agent.ps1:

$ErrorActionPreference = "Stop"

$webserver = "intranet.mdb-lab.com"
$url = "http://" + $webserver
$installer = "VMware-Horizon-Agent-x86_64-7.10.0-14590940.exe"
$listConfig = "/s /v ""/qn REBOOT=ReallySuppress ADDLOCAL=Core,RTAV,ClientDriveRedirection,VmwVaudio"""

# Verify connectivity
Test-Connection $webserver -Count 1

# Get Horizon Agent
Invoke-WebRequest -Uri ($url + "/" + $installer) -OutFile C:\$installer

# Unblock installer
Unblock-File C:\$installer -Confirm:$false -ErrorAction Stop

# Install Horizon Agent
Try 
{
   Start-Process C:\$installer -ArgumentList $listConfig -PassThru -Wait -ErrorAction Stop
}
Catch
{
   Write-Error "Failed to install the Horizon Agent"
   Write-Error $_.Exception
   Exit -1 
}

# Cleanup on aisle 4...
Remove-Item C:\$installer -Confirm:$false

The Horizon Agent script above looks weird in WordPress formatting, but I’m sure you get the gist.

Patching

Now that our template has all the agents it needs to be patched. To do this, create a PowerShell script called updates.ps1 and use the following:

# Get the provider
Get-PackageProvider -Name nuget -Force

# Install the module
Install-Module PSWindowsUpdate -Confirm:$false -Force

# Install updates
Get-WindowsUpdate -Install -AcceptAll -IgnoreReboot

# Sleepy time...
Start-Sleep -Seconds 600

# Run it again, as apparently it needs two attempts
Get-WindowsUpdate -Install -AcceptAll -IgnoreReboot

Optimization

One last thing we need to do is optimize the image. This process is highly fluid, an no “one size fits all” exists.

However, in the following example, I will demonstrate how to use the VMware OS Optimization fling to apply a pre-configured group of settings to optimize your image.

In order to get this working, download the ZIP file from the VMware Flings site above. Unzip it and you should get two files. Store these on your file server along with the agents you used above.

Before we can apply our template, we need to generate it. As mentioned, I plan to use the default Windows 10 image from VMware. However, depending on the version of the tool you have, you may need to download it first. To do so, follow these steps:

  • Run OSOT on another Windows 10 machine
  • Click Public Templates
  • Select the Windows 10 template, and then Download
  • Save this template as an XML file (I store mine as Windows10.xml)
  • Upload the template to your file server with the two other files

Obviously, you are free to create your own template and use that as you wish.

Create a script called osot.ps1, save in setup and consisting of the following:

$ErrorActionPreference = "Stop"

$webserver = "intranet.mdb-lab.com"
$url = "http://" + $webserver
$osot = "VMwareOSOptimizationTool.exe"
$osotConfig = "VMwareOSOptimizationTool.exe.config"
$template = "Windows10.xml"

# Verify connectivity
Test-Connection $webserver -Count 1

# Get Files
ForEach ($file in $osot,$osotConfig,$template) {
   Invoke-WebRequest -Uri ($url + "/" + $file) -OutFile C:\$file
}

# Run OSOT
C:\VMwareOSOptimizationTool.exe -o -t C:\$template

# Sleep before cleanup
Start-Sleep -Seconds 180

# Cleanup on aisle 4...
ForEach ($file in $osot,$osotConfig,$template) {
   Remove-Item C:\$file -Confirm:$false
}

When this script runs it will apply the Windows 10 template using OSOT.

Try it again…

Now we have added our scripts, run the build again to verify it installs all the agents as you expect. To do this use:

packer build -force -var-file variables.json windows-10.json

Coming up

In part 3 of this series will automate the entire process from start to finish using VMware Code Stream.

4 thoughts on “Automating VDI Template Creation with VMware Code Stream and HashiCorp Packer – Part 2: Installing the VDI Agents

  1. Pingback: Newsletter: October 12, 2019 – Notes from MWhite

  2. Pingback: Automating VDI Template Creation with VMware Code Stream and HashiCorp Packer – Part 3: Automating the Solution | virtualhobbit

  3. Pingback: Automating VDI Template Creation with VMware Code Stream and HashiCorp Packer – Part 1: Building Windows | virtualhobbit

  4. Pingback: Minimal Touch VDI Image Building With MDT, PowerCLI, and Chocolatey | The Virtual Horizon

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.