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:
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.
Pingback: Newsletter: October 12, 2019 – Notes from MWhite
Pingback: Automating VDI Template Creation with VMware Code Stream and HashiCorp Packer – Part 3: Automating the Solution | virtualhobbit
Pingback: Automating VDI Template Creation with VMware Code Stream and HashiCorp Packer – Part 1: Building Windows | virtualhobbit
Pingback: Minimal Touch VDI Image Building With MDT, PowerCLI, and Chocolatey | The Virtual Horizon