Sunday, May 26, 2024

Sunday, October 2, 2022

Ansible playbook for Ubuntu automated customization

Setting up Linux as a virtual desktop for VMware Horizon could be a painful and very time consuming procedure. Few years ago VMware have published a prebuilt Ubuntu 18.04 virtual appliance with a shell script to automate multiple routine tasks to prepare a virtual desktop. You can download the script separately from the repository on GitHub:

Unfortunately, this project has not been updated for many years, and it is not suitable for the new versions of Ubuntu 20.04 and Ubuntu 22.04 without modifications.

So I prepared a small playbook for Ansible to automate Ubuntu 18.04 / 20.04 / 22.04 configuration for Horizon:

Linux-optimize4vdi is a simple Ansible playbook which performs basic configuration steps like updating OS, uninstalling/installing packages, setting GNOME desktop parameters, etc. Current version supports Ubuntu 22.04.

Automated features

This playbook performs multiple optimizations:
  1. Remove unnecessary Ubuntu apps (games, usb creator utility and transmission app).
  2. Update and upgrade packages with apt update && apt upgrade.
  3. Update installed apps with snap refresh.
  4. Install the latest version of Open-VM-Tools.
  5. Install new apps via apt (chromium, 7zip, vlc, telegram desktop client, and zoom client).
  6. Disable apt automatic updates and upgrades.
  7. Enable GRUB quiet boot.
  8. Disable system hibernation and sleep.
  9. Disable unnecessary services (bluetooth, thunderbolt, firmware update service).
  10. Join to the domain.
  11. Compile VHCI driver for Horizon USB redirection.
  12. Compile V4L2Loopback driver for Horizon RTAV.
  13. Install Horizon Agent with Audio redirection, USB redirection, and RTAV.
  14. Enable SSO for Horizon.
  15. Optimize GNOME desktop (disable animation, set default background to single color).
  16. Clean bash history.
  17. Reboot the virtual desktop.

How to use

Install Ubuntu 22.04 Guest OS on the virtual desktop VM with default parameters. Set the default user account with 'user' as username and sudoer permissions. If you user another username, please modify configuration steps and ansible.cfg accordingly.

Install OpenSSH server on the virtual desktop:
sudo apt get install openssh-server
Install Ansible on your workstation / client computer.

Generate ssh keys on your workstation with default settings:
Copy public key from your workstation to the virtual desktop:
ssh-copy-id -i ~/ user@virtual_desktop_ip_address
Modify inventory file and specify virtual desktop IP address and modify required variables.

Download and place required installation packages and archives to the files folder.

Run Ansible playbook with:
ansible-playbook --ask-become-pass optimize.yml


If you want to run only certain optimization you can run ansible-playbook with --tags "tag1, tag2, tag3" parameter. Currently this playbook supports tags:
  • horizon - install and configure VMware Horizon Agent on the virtual desktop.
  • domain - join to the domain with the parameters specified in inventory files.
  • gnome - perform GNOME desktop tweaks and optimizations.
  • reboot - reboot the virtual desktop after completing optimizations.
For example to run playbook with horizon and domain join optimization only enter:
ansible-playbook --ask-become-pass --tags "horizon, domain" optimize.yml


Inventory file contains variables, which are necessary to run the playbook:
  • horizon_agent - archive name with the horizon_agent installation package
  • vhci_driver - vhci driver archive name
  • v4l2loopback_driver - archive name with the v4l2loopback driver
  • domain_name - domain name to join
  • domain_user - domain account name to join to the domain
  • domain_password - password for domain-entry account
  • debug - set to True to display extended information from the commands that have been executed

Saturday, March 24, 2018

Self-preparation questions for VCP7-DTM exam

Recently I have passed the 2V0-751 exam to receive the certified status VMware Certified Professional 7 - Desktop & Mobility

To help prepare for the exam, I wrote down a pool of test questions for self-preparation (70 questions).

Some sample questions:

Question 1.7 Which optional components are selected by default during Horizon View Agent installation? (Select three)
A. USB Redirection
B. Real-Time Audio-Video
C. VMware Horizon View Composer
D. VMware Horizon Instant Clone
E. Client Drive Redirection
F. Scanner Redirection

Question 1.12 Which statement is true related to Instant Clones?
A. VMware Horizon Instant Clone component is required
B. View Composer is required
C. Datastore with VAAI is required
D. vSphere 5.5 or later is required

Question 2.9 An administrator is planning to upgrade desktops to the Windows 10 via Mirage Windows OS Migration feature. Which USMT file version must be imported?
C. USMT 6.3
D. USMT 10.0

Question 3.9 Which authentication profiles are supported for Web applications published through the Identity Manager? (Select three)
A. Kerberos 5
B. OAuth 1.0
C. OpenID 2.0
D. SAML 1.1
E. SAML 2.0
F. WS-Federation 1.2

Question 4.8 Which Machine Manager types are supported by App Volumes? (Select three)
A. VMware vCenter Server
B. ESXi Host
C. Citrix XenApp Farm
D. VMware Identity Manager
E. Horizon Published Apps
F. VHD In-Guest Services

Question 5.2 Which components are selected by default during User Environment Manager installation? (Select three)
A. FlexEngine
B. FlexMigrate
C. FlexProfilesSelfSupport
D. FlexManagementConsole
E. SyncTool
F. Helpdesk Support Tool

Question 6.2 An administrator is planning to configure vROps for Horizon to monitor View Connection Servers. What should the administrator install on View Connection Servers?
A. Install Horizon adapter on every View Connection Server in the Pod Federation.
B. Install Horizon adapter on one View Connection Server in every Pod.
C. Install broker agent on every View Connection Server in the Pod Federation.
D. Install broker agent on one View Connection Server in every Pod.

You could download the full document via the link:

Thursday, March 15, 2018

PCoIP Log Analyzer PowerShell cmdlets

For troubleshooting purposes I created a bunch of PowerShell cmdlets, which allows to analyzer PCoIP Log files generated by Horizon Agent v5.3 - 7.x. 

Cmdlets are available on the GitHub:

Cmdlets provides detailed information about PCoIP session.

Results could be exported in the .txt file, .csv file, or HTML report with graphs.

Cmdlets are packaged as a PowerShell module. To install the module simply copy the PCoIPLogAnalyzer.psm1 on the PC and run Import-Module PCoIPLogAnalyzer.psm1 to add cmdlets to the PowerShell.

The module contains cmdlets:
  • Get-PCoIPStatistics
  • Import-PCoIPLog
  • Show-PCoIPStatistics
  • Export-PCoIPStatistics
Get-PCoIPStatistics is used to analyze log file and create a report, and has some parameters.
Get-PCoIPStatistics -FilePath <string> [-ResultPath <string>] [-Format <string>] [-NoScreenOutput] [-MaxSamples <int>]
  • FilePath <string> - (mandatory) Specify path to the pcoip_server log file.
  • ResultPath <string> - (optional) Specify path to export results to the file.
  • Format <string> - (optional) Specify the report format. Supported values are: CSV, HTML or TEXT. By default data is saved in the TEXT format.
  • NoScreenOutput - (optional) Specify this parameter, if you want to skip output the result to the console.
  • MaxSamples <int> - (optional) Set the maximum number of rows to output. If not defined, the default value is 500.
#Analyze the log file and print results on the screen
Get-PCoIPStatistics -FilePath "C:\Temp\pcoip_server_2017_12_19_000034d0.txt"

#Analyze log file, generate the report and export it to the HTML file
Get-PCoIPStatistics -FilePath "C:\Temp\pcoip_server_2017_12_16_00000230.txt" -ResultPath "C:\Temp\report.html" -Format HTML
Current version has known limitations:
  1. Current version supports pcoip_server log files generated by VMware Horizon Agent version 5.3, 6.x or 7.x. Other versions could have some changes in log format and are not supported.
  2. Current version does not display some statistics from log files from desktops with PCoIP Hardware Host Card (Teradici Remote Workstation Card).
  3. To correctly display the styles and charts in the HTML report, your computer needs access to and to download additional java scripts and stylesheets.

Tuesday, March 13, 2018

VMware vSAN bootstrap with dedupe and compression

Many of you know about vSAN bootstrap configuration which allows you to configure vSAN on a single ESXi host without vCenter Server.

There are a lot of posts which contains detailed information about bootstrap vSAN configuration, but today I would like to provide you additional steps to enable vSAN deduplication and compression on a single host without vCenter Server.

First of all, you need a host with ESXi 6.0 U2 or newer (because we need vSAN 6.2 or higher to support dedupe and compression). Secondary, your host must have at least two flash devices/SSD drives (one - for caching, others - for capacity). It's better to use SSD drives from the VMware HCL, but due to light loads in the homelab you could use any cheap SSD drive with sufficient performance. Also you should remember that there are no data redundancy in such configuration, so any SSD failure will lead to the complete data loss.

Enable SSH and connect to the host.

Enable support for vSAN traffic on one of the VMKernle interface (even if you are planning to have only one host, you have to enable this setting):
esxcli vsan network ipv4 add -i vmk0
You could check the settings with command:
esxcli vsan network list
Using vdq -q command check that all SSD drives are detected by ESXi host and are available for claiming.
vdq -q
      "Name"     : "naa.6000c29f63422c9b752b4e16b0853303",
      "VSANUUID" : "",
      "State"    : "Ineligible for use by VSAN",
      "Reason"   : "Has partitions",
      "IsSSD"    : "0",
"IsCapacityFlash": "0",
      "IsPDL"    : "0",
      "Name"     : "naa.6000c2914ef142687a2ea87a31a4c207",
      "VSANUUID" : "522af0ce-c313-dbfb-21b7-ba8e0b509778",
      "State"    : "In-use for VSAN",
      "Reason"   : "None",
      "IsSSD"    : "1",
"IsCapacityFlash": "0",
      "IsPDL"    : "0",
      "Name"     : "naa.6000c29dc7b03388ce238783d25a085c",
      "VSANUUID" : "52964ee8-1ad3-51ee-8850-8315e0ebceb6",
      "State"    : "In-use for VSAN",
      "Reason"   : "None",
      "IsSSD"    : "1",
"IsCapacityFlash": "1",
      "IsPDL"    : "0",
If drive is not detected as SSD, you could mark it manually. Get the NAA and SATP values via the command:
esxcli storage nmp device list
Run the commands and replace --device and --satp parameters with the correct ones.
esxcli storage nmp satp rule add --satp=VMW_SATP_LOCAL --device naa.600508b1001cdb71c7edb8e80eb6abf3 --option "enable_ssd"
esxcli storage core claiming unclaim --type=device --device naa.600508b1001cdb71c7edb8e80eb6abf3
esxcli storage core claimrule load
esxcli storage core claimrule run
esxcli storage core claiming reclaim --device naa.600508b1001cdb71c7edb8e80eb6abf3
If drive is not marked as CapacityFlash you could use the command:
esxcli vsan storage tag add -d naa.6000c29dc7b03388ce238783d25a085c -t capacityFlash
Before configuring vSAN cluster you need to set the correct licensed features to enable vSAN deduplication and compression.
vsish -e set /config/VSAN/strOpts/LicensedFeatures vit,allflash,stretchedcluster,erasurecoding,storageefficiency,encryption
Create the new vSAN cluster.
esxcli vsan cluster new
Check that the host is added to the cluster:
esxcli vsan cluster get
Cluster Information
   Enabled: true
   Current Local Time: 2017-08-11T22:01:45Z
   Local Node UUID: 598e2050-a425-2c28-5426-005056aacefb
   Local Node Type: NORMAL
   Local Node State: MASTER
   Local Node Health State: HEALTHY
   Sub-Cluster Master UUID: 598e2050-a425-2c28-5426-005056aacefb
   Sub-Cluster Backup UUID:
   Sub-Cluster UUID: 598e2050-a425-2c28-5426-005056aacefb
   Sub-Cluster Membership Entry Revision: 0
   Sub-Cluster Member Count: 1
   Sub-Cluster Member UUIDs: 598e2050-a425-2c28-5426-005056aacefb
   Sub-Cluster Membership UUID: 05298e59-0555-5bb1-c414-005056aacefb
   Unicast Mode Enabled: true
   Maintenance Mode State: OFF
Edit storage policies and add forceProvisioning option. This option allows vSAN to ignore the requirements for hostFailuresToTolerate=1 which cannot be accomplished in a single node vSAN cluster:
esxcli vsan policy setdefault -c cluster -p "((\"hostFailuresToTolerate\" i1) (\"forceProvisioning\" i1))"
esxcli vsan policy setdefault -c vdisk -p "((\"hostFailuresToTolerate\" i1) (\"forceProvisioning\" i1))"
esxcli vsan policy setdefault -c vmnamespace -p "((\"hostFailuresToTolerate\" i1) (\"forceProvisioning\" i1))"
Check policies with the command:
esxcli vsan policy getdefault
Policy Class  Policy Value
------------  --------------------------------------------------------
cluster       (("hostFailuresToTolerate" i1) ("forceProvisioning" i1))
vdisk         (("hostFailuresToTolerate" i1) ("forceProvisioning" i1))
vmnamespace   (("hostFailuresToTolerate" i1) ("forceProvisioning" i1))
vmswap        (("hostFailuresToTolerate" i1) ("forceProvisioning" i1))
vmem          (("hostFailuresToTolerate" i1) ("forceProvisioning" i1))
Enable deduplication and compression before adding SSD drives to the vSAN disk group:
esxcli system settings advanced set -o "/VSAN/DedupScope" -i 2
Check settings:
esxcli system settings advanced list -o "/VSAN/DedupScope"
Add SSD drives to the disk group:
esxcli vsan storage add -d naa.6000c29dc7b03388ce238783d25a085c -s naa.6000c2914ef142687a2ea87a31a4c207
Verify that all drives are added and enabled for deduplication and compression:
esxcli vsan storage list
   Device: naa.6000c2914ef142687a2ea87a31a4c207
   Display Name: naa.6000c2914ef142687a2ea87a31a4c207
   Is SSD: true
   VSAN UUID: 522af0ce-c313-dbfb-21b7-ba8e0b509778
   VSAN Disk Group UUID: 522af0ce-c313-dbfb-21b7-ba8e0b509778
   VSAN Disk Group Name: naa.6000c2914ef142687a2ea87a31a4c207
   Used by this host: true
   In CMMDS: true
   On-disk format version: 5
   Deduplication: true
   Compression: true

   Checksum: 6910810568216580648
   Checksum OK: true
   Is Capacity Tier: false
   Encryption: false
   DiskKeyLoaded: false
   Device: naa.6000c29dc7b03388ce238783d25a085c
   Display Name: naa.6000c29dc7b03388ce238783d25a085c
   Is SSD: true
   VSAN UUID: 52964ee8-1ad3-51ee-8850-8315e0ebceb6
   VSAN Disk Group UUID: 522af0ce-c313-dbfb-21b7-ba8e0b509778
   VSAN Disk Group Name: naa.6000c2914ef142687a2ea87a31a4c207
   Used by this host: true
   In CMMDS: true
   On-disk format version: 5
   Deduplication: true
   Compression: true

   Checksum: 4407850188756192377
   Checksum OK: true
   Is Capacity Tier: true
   Encryption: false
   DiskKeyLoaded: false
If you are using unsupported drives disable the alarm which displays warnings in the Host Client interface:
esxcli system settings advanced set -o /LSOM/VSANDeviceMonitoring -i 0 
During working via Host Client I got a minor bug. In the Host Client the default name for the datastore is "vSAN Datastore" (with space) and in vCenter and from the CLI the name is "vSANDatastore" (without space) which leads to the errors during VM or virtual disk creation via Host Client. To fix this issue simply rename the datastore to the "vSANDatastore".

Unfortunately, Host Client does not provides information about storage efficiency, so the only way to evaluate this value is to compare VMs Used space and datastore used space values.

As for the numbers, on my homelab server I have more than 30 different VMs (mostly with Windows OS and some Linux appliances) and vSAN provides about 2,4 dedupe and compression ratio. So it's quite cost efficient solution.