ControlUp loves Horizon Session Recording!

Ok maybe it’s more me than ControlUp but the usual audience on this blogs knows that I work for ControlUp and that I love the VMware flings. Recently we received the question from several South-America based customers if we where able to start the Horizon Session Recordings using a Script Based Action. Technically we would have been able to but with the current version we would have to add the user to an ad group that was configured for this and than would be at the mercy of AD replication for the recording to actually start. Que Trentent Tye who reached out to the one and only Andrew Morgan (imho king of the VMware Horizon related flings) if it would be possible to add an API or PowerShell module to start the recordings. I guess Andrew’s reaction was that he saw the use case for this and within no-time he had a beta version ready for us that had a Powershell module. By the time you read this the new version has been added to the flings site that includes all of these goodies and you can find it here.

<I wanted to insert a picture of Andrew here wearing a crown but that was too much>

The Horizon Session Recording fling

First let’s look at what the Horizon Session Recording fling actually does.

VMware Horizon Session Recording allows administrators of a VMware Horizon environment to record their users activity in their Blast Extreme virtual desktop and application sessions. Recordings are uploaded from the agent devices to the central web service, for central storage and ease of viewing.

The Session Recordings are stored as MP4 files for watching via the web console or downloading to play in a local player.

So we have an agent> server application where the videos are stored on the server. During the setup I found that this was very easy but configuring a proper SSL certificate makes things a lot easier as you otherwise need to supply the thumbprint of the self-signed certificate during installation of the agent or in the registry.

The server interface is easy enough with the standard dashboard showing recent recordings while on the Recordings tab you can search for for specific recordings.

The agent is a plain installer that only asks for the server location and the SSL certificate thumbprint. The last one is only needed when the certificate itself is not trusted, if you used a VA signed certificate for the server there’s no need to enter the thumbprint.

Starting a recording

As said in the previous versions of the recorder it was required to configure an ad group and add users to that group to record their sessions. With this version we get a powershell module installed with the agent. It gets even better because if you copy the entire /api folder from the agent installation folder to another system you’re perfectly able to start recordings from there.

Starting a recording using powershell is a matter of importing the proper dll

import-module Horizon.SessionRecording.PowerShell.dll

And now the user can start the recording themselves if they have too many rights by using Start-HSRSessionRecording -SessionID %sessionid%. The session ID can be found as a metric in ControlUp or in the task manager if you add the column under users.

Start-HSRSessionRecording -SessionID 1

My user clearly didn’t have enough rights on the system so I got an error, actually not a bad thing so users can’t easily overload the server this way.

Update: Andrew confirmed this is by design to stop users from recording each other.

Starting the recording remote is a matter of adding the computername to the command

Start-HSRSessionRecording -ComputerName pod02-2001 -SessionID 1

Here you also see in the bottom right corner the message that the user receives when a recording is started.

And stopping is a matter of this command.

Stop-HSRSessionRecording -ComputerName pod02-2001 -SessionID 1

Other Cmdlets in the PS module

Integrating with ControlUp

To integrate the Horizon session recording with ControlUp I have created two basic Script Actions. both use three arguments, besides the required SessionId I add the username and machine name in the output so it’s obvious for whom the recording was started.

$sessionId=$args[0]
$username=$args[1]
$computer=$args[2]

try{
    $InstallDir = Get-ItemPropertyValue -path "hklm:\SOFTWARE\VMware, Inc.\VMware Blast\SessionRecordingAgent" -Name installdir
}
catch{
    write-host "Error determining the Horizon Session recording installation location. Please make sure the Horizon Sesison recording Agent is Installed."
}
try{
    import-module "$($InstallDir)\api\horizon.sessionrecording.powershell.dll"
}
catch{
    write-host "Error loading the Horizon Session Recording PowerShell Module. Make sure the latest vesrion of the Horizon Session Recording Agent is installed"
}
try{
    Start-HSRSessionRecording -SessionID $sessionId
}
Catch{
    write-host "Error starting the recording"
}

write-host "Started session recording for $username on $computer"
$sessionId=$args[0]
$username=$args[1]
$computer=$args[2]

try{
    $InstallDir = Get-ItemPropertyValue -path "hklm:\SOFTWARE\VMware, Inc.\VMware Blast\SessionRecordingAgent" -Name installdir
}
catch{
    write-host "Error determining the Horizon Session recording installation location. Please make sure the Horizon Sesison recording Agent is Installed."
}
try{
    import-module "$($InstallDir)\api\horizon.sessionrecording.powershell.dll"
}
catch{
    write-host "Error loading the Horizon Session Recording PowerShell Module. Make sure the latest vesrion of the Horizon Session Recording Agent is installed"
}
try{
    stop-HSRSessionRecording -SessionID $sessionId
}
Catch{
    write-host "Error stopping the recording"
}

write-host "Stopped session recording for $username on $computer"

Both these script will get better error handling and notifications in the future but you still see the old error in the background but with the notification that the recording was started.

And stopping the recording

And that shows how easy it is to control the Horizon Session Recording using a Script Based Action. If you combine this with a trigger, cpu usage for example you might be able to capture what is causing that spike, just remember to also create a trigger than stops it after the cpu goes down again.

Changelog

Version 2.2.0

Server Changes:

  • Added the ability to import server settings easily from another running server.
  • Added the ability to filter searches based on farm / pool.
  • Added the ability to lock and unlock sessions from the session view page.

Agent Changes:

1: Misc bugfixes.
2: PowerShell API to interact with the Recording agent, to perform such tasks as:

  • Start a session recording.
  • Stop a session recording.
  • Troubleshoot connectivity issues.
  • View machine configuration
  • Add a trusted certificate.

The VMware Labs flings monthly for October 2020

First of all I hope that everyone is staying safe en sound and keeping their social distance. Over here we’ve been back to a light lockdown again but at least most of the shops are still open. I just opened the flings site and the VMware engineers have been dam busy! This are the tabs I had after opening all of them.

If I count it right I have six new flings and another eight received updates, I can’t remember the last time we had so much activity on the flings front. The new flings include one of the most anticipated VMware products for the last years: ESXi on Arm!

New Releases

Sample Data Platform on VMware Cloud Foundation with VMware Tanzu for Kubernetes Provisioning

vSphere Pod Autoscaler

Workspace ONE Discovery

ESXi Arm Edition

Horizon Peripherals Intelligence

Storage Performance Tester

Updating Flings

vRealize Build Tools

VMCA Certificate Generator

USB Network Native Driver for ESXi

Demo Appliance for Tanzu Kubernetes Grid

Workspace ONE App Analyzer for macOS

App Volumes Migration Utility

True SSO Diagnostic Utility

HCIBench

New Releases

Sample Data Platform on VMware Cloud Foundation with VMware Tanzu for Kubernetes Provisioning

With this Fling, you will leverage your VMware Cloud Foundation 4.0 deployment and stand a sample data platform on a Tanzu Kubernetes Grid guest cluster in less than 20-minutes comprising of Kafka, Spark, Solr, and ELK.

Additionally, this Fling comes with a market data sample application (using real market data from dxFeed) that shows how all these data platform components work together.

vSphere Pod Autoscaler

This Fling is useful for vSphere PodVM users who want to perform auto-scaling on vSphere PodVMs based on memory utilization.

This python script is intended to implement the Horizontal Pod Autoscaler algorithm for podVM for the vSphere 7.0 with Kubernetes. The implementation follows the algorithm from the official Kubernetes documents: https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/

This script will automatically scale the number of PodVMs in the environment. The script will perform the following actions:

  1. The script will retrieve the memory utilization of PodVMs in the environment
  2. The script will then allow users to provide the memory threshold for PodVMs
  3. The script will then calculate the desired number of replicas based on the memory threshold and utilization
  4. The script will automatically scale the PodVMs to the desired number of replicas calculated in step #3

Workspace ONE Discovery

VMware Workspace ONE UEM is used to manage Windows 10 endpoints, whether it be Certificate Management, Application Deployment or Profile Management. The Discovery Fling enables you to view these from the device point of view and review the Workspace ONE related services, which applications have been successfully deployed, use the granular view to see exactly what has been configured with Profiles, view User & Machine certificates and see which Microsoft Windows Updates have been applied.

Discovery provides you a view of the Managed device and can be used to help with troubleshooting.

ESXi Arm Edition

Hello ESXi-Arm Fling participants!

Over the past several years, you’ve seen us demonstrate our virtualization technology on the Arm platform across several use cases, everything from running mission critical workloads on a windmill, to running on the SmartNIC, to running on AWS Graviton in the cloud. We realized that the resilient platform created for the datacenter can be equally valuable in non-traditional environments. We’ve learned a lot from exploratory discussions with customers and Arm Silicon Partners.

Now we’d like to give our customers a chance to evaluate this technology in their own environments. This evaluation program is for the enterprise architects who are considering the viability of virtualizing Arm workloads, for the test/dev team looking for a way to spin up Arm environments, and for the tinkerers who simply want to explore running ESXi-Arm in a small form factor Edge environment. We’re interested to understand what features you will find most valuable, and how you will want to deploy this technology.

As there has been an update for this fling already here’s the changelog:

Changelog

October 22, 2020 – v1.1

Note: Upgrade is NOT possible, only fresh installation is supported. If you select “Preserve VMFS” option, you can re-register your existing Virtual Machines.

  • Fix for https://flings.vmware.com/esxi-arm-edition/bugs/1098 (PSOD adding to VDS)
  • Support for Arm N1 SDP platform
  • Support for VMs on Neoverse N1 CPU
  • Pass-thru stability improvements to LS1046A and LX2160A platforms
  • Fix for vCenter/DRS incorrect CPU usage
  • Fix for VM crash when VM storage fills up
  • Stability fix for non-coherent DMA device support
  • Installer: tolerate RAM size within 4% of 4GB instead of 3.125 (for the otherwise unsupported RK3399 boards)
  • Serial port handling improvements (for unsupported/unknown boards, to be a bit more resilient of firmware configuration errors)
    • Documentation Updates:
      Moved and expanded iSCSI doc for Pi doc to main ESXi-Arm Fling doc
    • Added LS1046ARDB docs (including ref to it from main ESXi-Arm doc and Fling website)
    • Fixed Ampere server name and links (its HR330A/HR350A, not SR-something)
    • Added Arm N1SDP document (including ref to it from main ESXi-Arm doc)
    • Updated GuestOSes known to work with ESXi-Arm including new “Verified” section
    • Updated instruction to update EEPROM for Pi doc

Build 17068872
VMware-VMvisor-Installer-7.0.0-17068872.aarch64.iso

October 06, 2020 – v1.0 (Initial Release)

Build 16966451

VMware-VMvisor-Installer-7.0.0-16966451.aarch64.iso

Horizon Peripherals Intelligence

Horizon Peripherals Intelligence is an online self-serviced diagnosis service that can help increase the satisfaction when using peripheral devices with Horizon product by both the end users and the admin user. Currently, we support diagnosis for the following device categories – USB storage devices, USB printers, USB scanners, Cameras. We will continue to cover more device categories in the future.

Storage Performance Tester

Storage Performance Tester is a one-click storage performance test tool, which is able to collect IOPS, latency and CPU cycles per I/O for ESXi storage stack. This tool automates all the testing steps including the customized VMs deployment, I/O workload running, and storage performance analysis. It displays the performance metrics through multiple visualized graphical charts. The only thing that users need to do is enter one command and wait for the performance report of your server.

This tool is designed to be a developer-friendly tool help troubleshoot and identify storage performance issues. It could be used to validate the maximum performance of new storage hardwares/drivers and setups of vSphere/vSAN. For more details please check the guild located in the instructions

Updated Flings

VMCA Certificate Generator

The VMCA Certificate Generator is useful to create your own certificates using the VMCA in vCenter if you don’t have access to a purpose build system in your network.

Changelog

Version 1.0 Update

  • Added the open source license file.

vRealize Build Tools

vRealize Build Tools provides tools to development and release teams implementing solutions based on vRealize Automation (vRA) and vRealize Orchestrator (vRO). The solution targets Virtual Infrastructure Administrators and Solution Developers working in parallel on multiple vRealize-based projects who want to use standard DevOps practices.

Changelog

Version 2.8.8 Update

  • [MVN] Support SHA1 checksum generation for JS,TS,XML,vRA,vRANG project types.
  • [MVN] Include the pom.xml description content as description of the built vRO package artifact
  • [TS-AutoGen] Define a property for storing the version of the API for which this project is generated.
  • [TS-AutoGen] Store the API version as part of the vRO package description.
  • [vRA-NG] Adds support for import/export of custom resources and resource actions.
  • [TS] Typescript projects for vRO, now support syntax for specifying a description for a configuration element attribute.
  • [vRA-NG] Adds support for using project name when managing vRA-NG content.
  • [vROps] Adds support for vROps 8.1
  • [vROps] Change default authentication provider to Token-based Authentication
  • [TS] Extend vropkg tool to support Polyglot bundle
  • [TS] Support for skipping unmapped dependencies, e.g. –skipUnmappedDeps
  • [TS] Bumped up Typescript version to 3.8.3
  • [TS] Added support for tsconfig file override using the project option of the tsc executable.
  • [MVN] Updated vRBT infrastructure project with latest dependencies and improved installation robustness
  • [vROps] Fixes a problem with resource kind during alert definition import
  • [TS] Use fixed node package versions
  • [vROps] Support for policy assignment to custom groups
  • [vRA] Fixes a problem with vra-ng authentication always setting System Domain and users not being able to authenticate with different domain
  • [vROps] Removed sshHost from Installer. Use host instead.
  • [TS] Make dependency:go-offline execution conditional
  • [TS] All version of Node are supported from 10.x and above
  • [TS] npm repository is no longer needed [TS] Support for RequireJS imports/exports
  • [TS] Support for yaml configurations
  • [TS] Improved workflows and policy templates transpilation
  • [TS] Improved diagnostic messages
  • [TS] Improved handling of cycle references
  • [TS] Extended workflow support
  • [TS] Support for ES2017.String

USB Network Native Driver for ESXi

USB has become one the most widely adopted connection type in the world & USB network adapters are also popular among Edge computing platforms. In some platforms, there is either limited or no PCI/PCIe slots for I/O expansion & in some cases, an Ethernet port is not even available. Another advantage of a USB-based network adapter is that it can be hot-plugged into an system without a reboot which means no impact to the workload, same is true for hot-remove.

This Fling supports the most popular USB network adapter chipsets found in the market. The ASIX USB 2.0 gigabit network ASIX88178a, ASIX USB 3.0 gigabit network ASIX88179, Realtek USB 3.0 gigabit network RTL8152/RTL8153 and Aquantia AQC111U. These are relatively inexpensive devices that many of our existing vSphere customers are already using and are familiar with.

Changelog

October 26, 2020 – v1.7

  • Added support for ESXi 7.0 Update 1
  • USB NIC Bindings are now automatically persistent
  • 5GbE USB NICs now properly show Full vs Half Duplex

Note: This is ONLY for ESXi 7.0 Update 1, for ESXi 7.0/6.7/6.5, please ensure you are using the correct version of driver.

ESXi701-VMKUSB-NIC-FLING-40599856-component-17078334.zip

Demo Appliance for Tanzu Kubernetes Grid

The Demo Appliance for Tanzu Kubernetes grid includes all the things needed tolearn about and run a Tanzu Kubernetes Grid.

Changelog

Oct 28, 2020 – v1.2.0

  • Support for latest TKG 1.2.0 release
  • Support for TKG Workload Cluster upgrade workflow from K8s 1.18.8 to 1.19.1
  • Updated to latest version of Harbor (1.10.5), Docker Compose (1.27.4), Kubectl (1.18.10), Octant (0.16.1), TMC (6867ad54), TKG Crashd (0.3.1) CLI in appliance

TKG-Demo-Appliance-1.2.0.ova
MD5: 0f0c60358a867b432698144820f8e8b0

Workspace ONE App Analyzer for macOS

The Workspace ONE macOS App Analyzer will determine any Privacy Permissions, Kernel Extensions, or System Extensions needed by an installed macOS application, and can be used to automatically create profiles in Workspace ONE UEM to whitelist those same settings when deploying apps to managed devices.

Changelog

Version 1.1 Update

  • 10/27/2020 – Fixed bug that prevented Privacy Preferences from loading when default shell was set to zsh.

App Volumes Migration Utility

App Volumes Migration Utility allows admins to migrate AppStacks managed by VMware App Volumes 2.18, to the new application package format of App Volumes 4. The format of these packages in App Volumes 4 have evolved to improve performance and help simplify application management.

Changelog

1.0.6 Version Update

  • Create meta_json.zip in migrated appstacks.

HCIBench

HCIBench is THE tool to test the performance of your VSAN cluster. Always use your own metrics based on the actual requirements for your environment.

HCIBench stands for “Hyper-converged Infrastructure Benchmark”. It’s essentially an automation wrapper around the popular and proven open source benchmark tools: Vdbench and Fio that make it easier to automate testing across a HCI cluster. HCIBench aims to simplify and accelerate customer POC performance testing in a consistent and controlled way. The tool fully automates the end-to-end process of deploying test VMs, coordinating workload runs, aggregating test results, performance analysis and collecting necessary data for troubleshooting purposes.

HCIBench is not only a benchmark tool designed for vSAN, but also could be used to evaluate the performance of all kinds of Hyper-Converged Infrastructure Storage in vSphere environment.

Changelog

Version 2.5.1 Update

  • Fixed non vSAN cluster testing issue
  • Fixed pre-validation storage policy issue
  • Added in-place upgrading capability, to do so, you can also upgrade HCIBench to the latest version by running the following command in HCIBench: tdnf install -y git && git clone https://github.com/cwei44/HCIBench.git && sh HCIBench/upgrade.sh
    MD5 Checksum: 1d14426f92b353e90469a8623ade2bc1 HCIBench_2.5.1.ova

Version 2.5.0 Update

  • Added support vSAN HCI Mesh testing, now you can test both local and remote vSAN datastores at the same time
  • Added support local storage including VMFS and vSAN-Direct testing
  • Added vSAN Debug Mode, allow user to collect vm-support bundle and vmkstats automatically when running testing against vSAN
  • Changed guest VMs name convention to {vm_prefix}-{datastore_id}-batch_num-sequence_num
  • Enhanced testing report format
  • Allow user to specify customized IP addresses for guest VMs
  • Allow user to configure CPU and Memory for guest VMs
  • Added best practice and network troubleshooting guide in the user manual
  • Bug fixes
  • MD5 Checksum: 817c2c788364f252e728d4253b3b96da HCIBench_2.5.0.ova

True SSO Diagnostic Utility

The True SSO Diagnostic Utility allows for validation of the various components needed for True SSO.

Horizon View True SSO uses Microsoft Enterprise Certificate Servers to issue certificates that are used when the user logs on to the desktop. The Horizon View Enrollment Server (ES) is responsible for sending a certificate request to certificate servers, and for monitoring the PKI configuration settings in the Active Directory.

Changelog

Version 2.2

  • The tool has been updated to allow performance-testing of the enrollment-server.

[HorizonAPI] Disabling Provisioning and/or disabling entire Desktop Pools and RDS Farms

Today I saw the question on the VMware{Code} Slack Channel if anyone ever managed to disabled Desktop Pools using PowerCLI. I was like yeah I have done that and you might need to user the helperservice for that. I offered to create q fast and quick blog post about it so here we go.

First as always I connect to my Connection Server and use a query to retrieve the Pool that I am going to disable.

$creds=import-clixml creds.xml
$hvserver=connect-hvserver pod1cbr1.loft.lab -Credential $creds
$hvservice=$hvserver.ExtensionData
$poolqueryservice=new-object vmware.hv.queryserviceservice
$pooldefn = New-Object VMware.Hv.QueryDefinition
$filter = New-Object VMware.Hv.QueryFilterEquals -Property @{ 'memberName' = 'desktopSummaryData.name'; 'value' = "Pod01_Pool01" }
$pooldefn.filter=$filter
$pooldefn.queryentitytype='DesktopSummaryView'
$pool = ($poolqueryService.QueryService_Create($hvservice, $pooldefn)).results

With this object I can show you the details of the desktop pool

($hvservice.Desktop.Desktop_Get($pool.id)).base
($hvservice.Desktop.Desktop_Get($pool.id)).desktopsettings

Like I said to actually change things I need the helper service so this is what you do to initialize that.

$desktopservice=new-object vmware.hv.DesktopService
$desktophelper=$desktopservice.read($HVservice, $pool.id)
$desktophelper.getdesktopsettingshelper() | gm

As we saw in the second screenshot I need the desktopsettings and than Enabled

$desktophelper.getdesktopsettingshelper().getenabled()

To change the setting in the helper I need to use sethelper($False)

$desktophelper.getdesktopsettingshelper().setEnabled($False)

Now this has not been changed yet on the desktop pool itself, to do that we need to use desktopservice.update and I also show the result of the change.

$desktopservice.update($hvservice, $desktophelper)
($hvservice.Desktop.Desktop_Get($pool.id)).desktopsettings

And to reverse this

$desktophelper.getdesktopsettingshelper().setEnabled($True)
$desktopservice.update($hvservice, $desktophelper)
($hvservice.Desktop.Desktop_Get($pool.id)).desktopsettings

Disabling provisioning uses the same methodology just in another spot.

To disable provisioning ( the | gm is not needed, it’s just there to show you whats’s in there):

($hvservice.Desktop.Desktop_Get($pool.id)).automateddesktopdata.virtualcenterprovisioningsettings
$desktophelper.getAutomatedDesktopDataHelper().getVirtualCenterProvisioningSettingsHelper() | gm
$desktophelper.getAutomatedDesktopDataHelper().getVirtualCenterProvisioningSettingsHelper().getenableprovisioning()
$desktophelper.getAutomatedDesktopDataHelper().getVirtualCenterProvisioningSettingsHelper().setenableprovisioning($False)
$desktopservice.update($hvservice, $desktophelper)
($hvservice.Desktop.Desktop_Get($pool.id)).automateddesktopdata.virtualcenterprovisioningsettings

And to revert it

$desktophelper.getAutomatedDesktopDataHelper().getVirtualCenterProvisioningSettingsHelper().setenableprovisioning($True)
$desktopservice.update($hvservice, $desktophelper)
($hvservice.Desktop.Desktop_Get($pool.id)).automateddesktopdata.virtualcenterprovisioningsettings

For RDSH farms the process is similar some of the naming is just different. First to get the farm object

$farmqueryservice=new-object vmware.hv.queryserviceservice
$farmdefn = New-Object VMware.Hv.QueryDefinition
$filter = New-Object VMware.Hv.QueryFilterEquals -Property @{ 'memberName' = 'data.name'; 'value' = "Pod01-Farm01" }
$farmdefn.filter=$filter
$farmdefn.queryentitytype='FarmSummaryView'
$farm = ($farmqueryservice.QueryService_Create($hvservice, $farmdefn)).results
($hvservice.Farm.farm_get($farm.id)).data

And to create the helper and disable the farm

$farmservice=New-Object VMware.Hv.FarmService
$farmhelper=$farmservice.read($hvservice,$farm.id)
$farmhelper.getDataHelper().setenabled($False)
$farmservice.update($hvservice,$farmhelper)
($hvservice.Farm.farm_get($farm.id)).data

And in reverse 🙂

$farmhelper.getDataHelper().setenabled($True)
$farmservice.update($hvservice,$farmhelper)
($hvservice.Farm.farm_get($farm.id)).data

And now the provisioning part

($hvservice.Farm.farm_get($farm.id)).automatedfarmdata.virtualcenterprovisioningsettings
$farmhelper.getAutomatedFarmDataHelper().getvirtualcenterprovisioningsettingshelper().setenableprovisioning($False)
$farmservice.update($hvservice,$farmhelper)
($hvservice.Farm.farm_get($farm.id)).automatedfarmdata.virtualcenterprovisioningsettings

Guess what?

$farmhelper.getAutomatedFarmDataHelper().getvirtualcenterprovisioningsettingshelper().setenableprovisioning($True)
$farmservice.update($hvservice,$farmhelper)
($hvservice.Farm.farm_get($farm.id)).automatedfarmdata.virtualcenterprovisioningsettings

The VMware Labs flings monthly for July 2020- Reach is back!

A couple of days late but I had  good excuse: I was away on a holiday. I needed it and enjoyed it and have a week left before I start work again. This month there was one new release and nine flings received an update. Overall it’s a EUC rich overview since no less than seven of those are Horizon / App Volumes related.

New Releases

App Volumes Packaging Utility

Updated flings

HCIBench

App Volumes Migration Utility

Horizon Session Recording

Power vRA Cloud

Horizon Reach

Desktop Watermark

App Volumes Entitlement Sync

vSphere Mobile Client

VMware OS Optimization Tool

New Releases

App Volumes Packaging Utility

This App Volumes Packaging Utility helps to package applications. With this fling, packagers can add the necessary metadata to MSIX app attach VHDs so they can be used alongside existing AV format packages. The MSIX format VHDs will require App Volumes 4, version 2006 or later and Windows 10, version 2004 or later.

Updated Flings

HCIBench

HCIBench is a VMware wrapper around VdBench or Fio to test the capabilities of your HCI environement. I would recommend always to test with your own settings so you can do an honest comparison.

Changelog

Version 2.4.0

  1. Fixed tvm deployment bug when specifying host
  2. enabled easy run to support stretched cluster
  3. fixed timezone issue on pdf report, and added more vSAN info into PDF report
  4. set testname and testcase as variables in grafana
  5. added CPU workload into fio config page
  6. updated rbvmomi to support vsphere 7.0+
  7. enhanced fio and vdbench graphite dashboards

MD5 Checksum: 0cfd6cc852e33e5ce32022a66539b4c9 HCIBench_2.4.0.ova

App Volumes Migration Utility

The App Volumes Migration Utility helps the users in moving from App Volumes 2.18 to App VOlumes 4 so app stacks don’t need to be reprovisioned.

Changelog

Version 1.0.3 Update

  • Field “uniqueId” is added in the metadata JSON for migrated appstacks.

Version 1.0.2 Update

  • Fix for fling bug 983.
  • The customer bug on the fling, exposed an un handled scenario.
  • Prior to migration if the appstacks registry database contained registry keys with embedded NUL
  • (\0) chars in their name, Migration fails.
  • This scenario has now been addressed with this update.

Horizon Session Recording

The Horizon Session Recording is a usefull tool when an Horizon Admin wants to be able to record sessions and see what the users are doing exactly when a problems happens.

Changelog

Version 2.1 Update

  • Many bugfixes in agent side

Power vRA Cloud

PowervRA Cloud is a PowerShell module that abstracts the VMware vRealize Automation Cloud APIs to a set of easily used PowerShell functions. This tool provides a comprehensive command line environment for managing your VMware vRealize Automation Cloud environment.

Changelog

Version 1.3

  • 4 x New Cmdlets for VMC
  • 5 x New Cmdlets for AWS
  • Powershell 7 on Windows Support
  • Bugfixes

Horizon Reach

If you don’t have any other 3rd partly tooling (like ControlUp, sorry gotta plug my employer 😛 ) to manage your Horizon environment than Reach is a very useful tool. This is not an update but a re-release, read below why.

Warning: Horizon Versions 7.10 through 7.12 have a known issue which can cause Horizon Reach to trigger a low memory issue on the Horizon Connection Server.

For Horizon 7.10, ensure to deploy Horizon 7.10.2. For 7.11 and 7.12, please refer to the following document here.

Desktop Watermark

The Desktop Watermark fling gives you the option to visible and unvisible mark the desktop that you are using.

Changelog

v1.2 – Build 20200713-signed Version Update

  • Added support for multiple displays.

App Volumes Entitlement Sync

The App Volumes Entitlement Sync flings helps an APp VOlumes admin to sync various App Volumes Environments like test/dev/prod or different pod’s for example.

Changelog

Version 4.1 Update:

  • Get App Volumes version from an API value which always returns the build number.
  • App Volumes 2006 and later has a problem with version 4.0 of the Fling in returning a string value.

vSphere Mobile Client

Manage vSphere from your phone or tablet with the vSphere Mobile Client fling, do I need to say more?

Changelog

Version 1.13.2 Update:

New:

  • Datastore details page (link from VM details page)

Improvements:

  • Fixed issues related to connecting to standalone ESXi VM console
  • Fixed issues when switching between servers

VMware OS Optimization Tool

Do you build golden images or templates? Than use the VMware OS Optimization Tool to optimize them!

Changelog

August, 2020, b1170 Update

Templates

  • New combined template for all versions of Windows 10 and Windows Server 2016 and 2019. Optimizations can have optional parameters to filter the version that a setting is applied to.

Optimizations

  • Turn off NCSI is no longer selected by default as this was shown to cause issues with some applications thinking they did not have internet connectivity.
  • New Optimizations added and some removed, For details see: https://techzone.vmware.com/resource/vmware-operating-system-optimization-tool-guide#Template_Updates

Bug Fixes

  • Fixed issues with re-enabling Windows Update functionality on Server 2016 and 2019.
  • Fixed issue that was preventing Windows Antimalware from being disabled properly.

Common Options

  • Changed interface and language on the Common Options page for Windows Update to remove confusion. This option can only be used to disable Windows Update as part of an optimization task. To re-enable Windows Update functionality, use the Update button on the main menu ribbon.

Guides

[HorizonAPI] Getting started with the Horizon REST api

Until now all of my blogging about the Horizon api’s was about consuming the SOAP api using PowerCLI. Since a couple of releases Horizon also has a REST api and since 7.12 we are also able to change some settings using that. So now it’s time for me to dive into the Horizon REST api’s. I will consume them using Powershell since I am the most comfortable using that but you can use whatever method you prefer..

The REST api is just like the soap api documented at the VMware{CODE} api explorer.

First of all we need to create an accesstoken, we can do this by using some code that I simply stole from Andrew Morgan because why would I re-invent the wheel? From his git repository I grabbed three basic functions: get-HRHeader, Open-HRConnection and close-hrconnection. there’s also a refresh-hrconnection but I won’t need that for now.

function Get-HRHeader(){
    param($accessToken)
    return @{
        'Authorization' = 'Bearer ' + $($accessToken.access_token)
        'Content-Type' = "application/json"
    }
}

function Open-HRConnection(){
    param(
        [string] $username,
        [string] $password,
        [string] $domain,
        [string] $url
    )

    $Credentials = New-Object psobject -Property @{
        username = $username
        password = $password
        domain = $domain
    }

    return invoke-restmethod -Method Post -uri "$url/rest/login" -ContentType "application/json" -Body ($Credentials | ConvertTo-Json)
}

function Close-HRConnection(){
    param(
        $accessToken,
        $url
    )
    return Invoke-RestMethod -Method post -uri "$url/rest/logout" -ContentType "application/json" -Body ($accessToken | ConvertTo-Json)
}
$accessToken = Open-HRConnection -username $username -password $password -domain $Domain -url $url

But we can’t do anything with only these functions, somehow we also need to supply username and password

$url = read-host -prompt "Connection server url"
$username = read-host -prompt "Username"
$password = read-host -prompt "Password" -AsSecureString
$Domain = read-host -Prompt "Domain"

$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($password)
$UnsecurePassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)

(I am grabbing it from the command line here but when I run the scripts I have my creds hardcoded to make my life for the duration of this blog post a bit easier)

Next up is actually getting some data. The first thing that I wil do is show the connection servers. This can be done with the following API call. The part after -uri “$url/rest/ is what you can find int he api explorer. The method is the method also shown in the api explorer.

Invoke-RestMethod -Method Get -uri "$url/rest/monitor/connection-servers" -ContentType "application/json" -Headers (Get-HRHeader -accessToken $accessToken)

and the result:

Since one of the few things that you can already change using the rest api’s are the general settings I will take those as the next example

Invoke-RestMethod -Method Get -uri "$url/rest/config/v1/settings" -ContentType "application/json" -Headers (Get-HRHeader -accessToken $accessToken)

This works but I can’t say that it’s really usable. Now this is not the first time I do something with REST api’s (haven’t done it a lot though to be honest) so I know this can easily be converted to json to make it visible. What I will do is that I put it in a variable first.

$settings=Invoke-RestMethod -Method Get -uri "$url/rest/config/v1/settings" -ContentType "application/json" -Headers (Get-HRHeader -accessToken $accessToken)
$settings | ConvertTo-Json

Now this DOES look usable! Let’s take a look what is under general_settings

$settings.general_settings

Let’s say I want to change the forced logoff message

$settings.general_settings.forced_logoff_message="Get lost, the Bastard Operator From Hell is here."

Now my variable has the change but I need to send this to the server. This can be done using a put method and the settings variable has to be added as json. The second line is to pull the new settings from my connection server showing it directly in a json format.

 

Invoke-RestMethod -Method Put -uri "$url/rest/config/v1/settings" -ContentType "application/json" -Headers (Get-HRHeader -accessToken $accessToken) -body ($settings | ConvertTo-Json)
Invoke-RestMethod -Method Get -uri "$url/rest/config/v1/settings" -ContentType "application/json" -Headers (Get-HRHeader -accessToken $accessToken) | ConvertTo-Json

and in the admin interface:

That’s it for my 1ste blog post about the horizon REST api’s hopefully it’s useful! Below is an example of the script that I used.

$url = read-host -prompt "Connection server url" 
$username = read-host -prompt "Username" 
$password = read-host -prompt "Password" -AsSecureString 
$Domain = read-host -Prompt "Domain" 

#$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($password) 
#$UnsecurePassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)

function Get-HRHeader(){
    param($accessToken)
    return @{
        'Authorization' = 'Bearer ' + $($accessToken.access_token)
        'Content-Type' = "application/json"
    }
}
function Open-HRConnection(){
    param(
        [string] $username,
        [string] $password,
        [string] $domain,
        [string] $url
    )

    $Credentials = New-Object psobject -Property @{
        username = $username
        password = $password
        domain = $domain
    }

    return invoke-restmethod -Method Post -uri "$url/rest/login" -ContentType "application/json" -Body ($Credentials | ConvertTo-Json)
}

function Close-HRConnection(){
    param(
        $accessToken,
        $url
    )
    return Invoke-RestMethod -Method post -uri "$url/rest/logout" -ContentType "application/json" -Body ($accessToken | ConvertTo-Json)
}

$accessToken = Open-HRConnection -username $username -password $password -domain $Domain -url $url

Invoke-RestMethod -Method Get -uri "$url/rest/monitor/connection-servers" -ContentType "application/json" -Headers (Get-HRHeader -accessToken $accessToken)

[Update 23-04-2020]Adding vCenter server to Horizon View using the api’s

Update

I don’t know since what version but somewhere this script stopped working because VMware change some things. In 7.8 there was a change about the thumbprint algorithm to DER_BASE64_PEM so it might have started there. Another change is that in the sslcertthumbprint field they stopped using the thumbprint but actually add the entire certificate.

What is needed to fix this?

Replace:

$spec.CertificateOverride=($services.Certificate.Certificate_Validate($spec.serverspec)).thumbprint

with

$spec.CertificateOverride.SslCertThumbprint=($services.Certificate.Certificate_Validate($spec.serverspec)).certificate
$spec.CertificateOverride.sslCertThumbprintAlgorithm = "DER_BASE64_PEM"

and you should be good. I have already updated the version of the script below.

A big thank you to Mark Brookfield for asking me about this

/update

Yesterday Sean Massey (https://thevirtualhorizon.com/) asked me if it was possible to add a vCenter server + some other things to Horizon View using the api’s. With a quick look at the api explorer I confirmed this should be possible. The other things he asked I will put in a separate blogpost.

It looks like a simple matter of building the spec and I should be good. In the end it turned out to be a bit more work then expected. Some items are not required according to the api explorer but should at least be called in the spec (set them to something empty) while others can safely be left away. The automatic generated ssl certs in my lab also turned out to be a pita. First I copied them from a current spec and later I downloaded the certificate on the Connection server itself and read that cert. Andrew Morgan (http://andrewmorgan.ie/)from VMware helped me out with this by showing their internal script that they use. It turned out that except for the SSL certs I was on the right path. As usual I will add this functionality to the vmware.hv.helper but since that might take a while I decided to create a useful script

$hvServer = $global:DefaultHVServers[0]
$services=  $hvServer.ExtensionData

# Create required objects

$spec=new-object VMware.Hv.VirtualCenterSpec
$spec.serverspec=new-object vmware.hv.serverspec
$spec.viewComposerData=new-object VMware.Hv.virtualcenterViewComposerData

$spec.Certificateoverride=new-object vmware.hv.CertificateThumbprint
$spec.limits=new-object VMware.Hv.VirtualCenterConcurrentOperationLimits
$spec.storageAcceleratorData=new-object VMware.Hv.virtualcenterStorageAcceleratorData

# vCenter Server specs

$spec.ServerSpec.servername="pod2vcr1.loft.lab"        # Required, fqdn for the vCenter server
$spec.ServerSpec.port=443                                 # Required
$spec.ServerSpec.usessl=$true                             # Required
$spec.ServerSpec.username="administrator@vsphere.local"   # Required user@domain
$vcpassword=read-host "vCenter User password?" -assecurestring
$temppw = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($vcPassword)
$PlainvcPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($temppw)
$vcencPassword = New-Object VMware.Hv.SecureString
$enc = [system.Text.Encoding]::UTF8
$vcencPassword.Utf8String = $enc.GetBytes($PlainvcPassword)
$spec.ServerSpec.password=$vcencPassword
$spec.ServerSpec.servertype="VIRTUAL_CENTER"

# Description & Displayname, neither is required to be set

#$spec.description="description"              # Not Required
#$spec.displayname="virtualcenterdisplayname" # Not Required
$spec.CertificateOverride=($services.Certificate.Certificate_Validate($spec.serverspec)).thumbprint
$spec.CertificateOverride.SslCertThumbprint=($services.Certificate.Certificate_Validate($spec.serverspec)).certificate
$spec.CertificateOverride.sslCertThumbprintAlgorithm = "DER_BASE64_PEM"


# Limits
# Only change when you want to change the default values. It is required to set these in the spec

$spec.limits.vcProvisioningLimit=20
$spec.Limits.VcPowerOperationsLimit=50
$spec.limits.ViewComposerProvisioningLimit=12
$spec.Limits.ViewComposerMaintenanceLimit=20
$spec.Limits.InstantCloneEngineProvisioningLimit=20

# Storage Accelerator data

$spec.StorageAcceleratorData.enabled=$false
#$spec.StorageAcceleratorData.DefaultCacheSizeMB=1024   # Not Required

# Cmposer
# most can be left empty but they need to be set otherwise you'll get a xml error

$spec.ViewComposerData.viewcomposertype="STANDALONE"  # DISABLED for none, LOCAL_TO_VC for installed with the vcenter and STANDALONE for s standalone composer


if ($spec.ViewComposerData.viewcomposertype -ne "DISABLED"){
    $spec.ViewComposerData.ServerSpec=new-object vmware.hv.serverspec
    $spec.ViewComposerData.CertificateOverride=new-object VMware.Hv.CertificateThumbprint
    $cmppassword=read-host "Composer user password?" -assecurestring
    $temppw = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($cmpPassword)
    $PlaincmpPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($temppw)
    $cmpencPassword = New-Object VMware.Hv.SecureString
    $enc = [system.Text.Encoding]::UTF8
    $cmpencPassword.Utf8String = $enc.GetBytes($PlaincmpPassword)
    $spec.ViewComposerData.ServerSpec.password=$cmpencPassword
    $spec.ViewComposerData.ServerSpec.servername="pod2cmp1.loft.lab"
    $spec.ViewComposerData.ServerSpec.port=18443
    $spec.ViewComposerData.ServerSpec.usessl=$true
    $spec.ViewComposerData.ServerSpec.username="m_wouter@loft.lab"
    $spec.ViewComposerData.ServerSpec.servertype="VIEW_COMPOSER"

    $spec.ViewComposerData.CertificateOverride=($services.Certificate.Certificate_Validate($spec.ViewComposerData.ServerSpec)).thumbprint
    $spec.ViewComposerData.CertificateOverride.sslCertThumbprint = ($services.Certificate.Certificate_Validate($spec.ViewComposerData.ServerSpec)).certificate
    $spec.ViewComposerData.CertificateOverride.sslCertThumbprintAlgorithm = "DER_BASE64_PEM"
}


# Disk reclamation, this is required to be set to either $false or $true
$spec.SeSparseReclamationEnabled=$false 

# This will create the connection
$services.VirtualCenter.VirtualCenter_Create($spec)

 

Looking at the output it will only ask for the vCenter user’s password and if a Composer server is set for that user’s password.

 

[HorizonAPI] Creating Entitlements

So last week I created a blog about gathering Horizon entitlements using the api’s. At the end I promised that my next blog post would be about creating entitlements and guess what: that’s this post 🙂

First a short explanation about what UserEntitlements actually are in Horizon. When you pull the entitlement info the base property has the needed information.

So in short an entitlement is a link between the userorgroup object id and a resource object id. The resource object can be: Application, Desktop, Global Application Entitlement, Global Desktop Entitlement and URLRedirection.

Let’s first grab the id’s that we need, I use 2 queries for that bur first I put the names of the group and the desktop in variables:

$groupname = "example_group"
$poolname = "pod01_pool01"

Than I create two objects called $group and $pool using queries.

$queryService = New-Object VMware.Hv.QueryServiceService
$defn = New-Object VMware.Hv.QueryDefinition
$defn.queryEntityType = 'ADUserOrGroupSummaryView'
$defn.Filter = New-Object VMware.Hv.QueryFilterEquals -property @{'memberName'='base.name'; 'value' = "$groupname"}
$group= ($queryService.queryService_create($HVService, $defn)).results
$queryService.QueryService_DeleteAll($HVService)

$queryService = New-Object VMware.Hv.QueryServiceService
$defn = New-Object VMware.Hv.QueryDefinition
$defn.queryEntityType = 'DesktopSummaryView'
$defn.Filter = New-Object VMware.Hv.QueryFilterEquals -property @{'memberName'='desktopSummaryData.displayName'; 'value' = "$Poolname"}
$pool= ($queryService.queryService_create($HVService, $defn)).results
$queryService.QueryService_DeleteAll($HVService)

Next we create the object to link them together.

$userentitlement= new-object VMware.Hv.UserEntitlementBase
$userentitlement.UserOrGroup = $group.id
$userentitlement.Resource = $pool.id

And we create the actual entitlement, since the output we get from this is the id of the entitlement object I store this in a variable to show you the entitlement in the next step.

and to show the entitlement

($hvservice.UserEntitlement.UserEntitlement_Get($newentitlement)).base

If you want to create entitlements for other resource you’ll need to use the either of the following to build your query:

Name Data object property to filter on
Application ApplicationInfo data.displayName
Desktop DesktopSummaryView DesktopSummaryData.displayName
Global Application Entitlement GlobalApplicationEntitlementInfo base.displayName
Global Desktop Entitlement GlobalEntitlementInfo base.displayName

There is no query for the URLRedirection so you’ll need to use URLRedirection.URLRedirection_List() to get the entire list and select the right one from that.

This is a complete example script that you could use to create a desktop entitlement:

Import-Module VMware.VimAutomation.HorizonView
Import-Module VMware.VimAutomation.Core

$cs = 'pod1cbr1.loft.lab'
$groupname = "example_group"
$poolname = "pod01_pool01"

$hvServer = Connect-HVServer -Server $cs 

$HVService= $hvServer1.ExtensionData

$queryService = New-Object VMware.Hv.QueryServiceService
$defn = New-Object VMware.Hv.QueryDefinition
$defn.queryEntityType = 'ADUserOrGroupSummaryView'
$defn.Filter = New-Object VMware.Hv.QueryFilterEquals -property @{'memberName'='base.name'; 'value' = "$groupname"}
$group= ($queryService.queryService_create($HVService, $defn)).results
$queryService.QueryService_DeleteAll($HVService)

$queryService = New-Object VMware.Hv.QueryServiceService
$defn = New-Object VMware.Hv.QueryDefinition
$defn.queryEntityType = 'DesktopSummaryView'
$defn.Filter = New-Object VMware.Hv.QueryFilterEquals -property @{'memberName'='desktopSummaryData.displayName'; 'value' = "$Poolname"}
$pool= ($queryService.queryService_create($HVService, $defn)).results
$queryService.QueryService_DeleteAll($HVService)

$userentitlement= new-object VMware.Hv.UserEntitlementBase
$userentitlement.UserOrGroup = $group.id
$userentitlement.Resource = $pool.id
$hvservice.UserEntitlement.UserEntitlement_Create($userentitlement)

[HorizonAPI] Configuring the Horizon event database in code

Last week Mark Brookfield asked the question if it is possible to configure the event database in code. My answer was that I thought it should be possible until Stephen Jesse pointed me to the the vmware.hv.helper where there is the set-hveventdatabase cmdlet for this. When looking at the code I noticed something familiar:

.NOTES
Author                      : Wouter Kursten
Author email                : wouter@retouw.nl
Version                     : 1.0

===Tested Against Environment====
Horizon View Server Version : 7.4
PowerCLI Version            : PowerCLI 10
PowerShell Version          : 5.0

So that’s why I knew it was possible! A good reason to create a quick blogpost though. Mark made a nice script for himself with variables and all those fancy things but I just want to quickly show how you can do it.

$hvedbpw=read-host -AsSecureString
$temppw=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($hvedbpw)
$PlainevdbPassword=[System.Runtime.InteropServices.Marshal]::PtrToStringAuto($temppw)
$dbupassword=New-Object VMware.Hv.SecureString
$enc=[system.Text.Encoding]::UTF8
$dbupassword.Utf8String=$enc.GetBytes($PlainevdbPassword)
$eventservice=new-object vmware.hv.eventdatabaseservice
$eventservicehelper=$eventservice.getEventDatabaseInfoHelper()
$eventsettings=new-object VMware.Hv.EventDatabaseEventSettings
$eventdatabase=new-object VMware.Hv.EventDatabaseSettings
$eventsettings.ShowEventsForTime="TWO_WEEKS"
$eventsettings.ClassifyEventsAsNewForDays=2
$eventdatabase.Server="labsql01.magneet.lab"
$eventdatabase.type="SQLSERVER"
$eventdatabase.port=1433
$eventdatabase.name="pod1_events"
$eventdatabase.username="sa_view"
$eventdatabase.password=$dbupassword
$eventservicehelper.setDatabase($eventdatabase)
$eventservicehelper.setsettings($eventsettings)
$eventservice.update($hvservice,$eventservicehelper)

The first three line make it possible to not use a plaintext password. If you don’t care about that you can remove those and declare something for $plainevdbpassword.

For the $eventsettings.ShowEventsForTime for time there are several options (same as in the gui) these are:

ONE_WEEK,TWO_WEEKS,THREE_WEEKS,ONE_MONTH,TWO_MONTHS,THREE_MONTHS,SIX_MONTHS
Yes, they are all in capitals!

To show how this works I will first clear the current database.

$hvservice.EventDatabase.EventDatabase_Clear()
$hvservice.EventDatabase.EventDatabase_Get()

Yes this is one of those exceptions where a service_get doesn’t need an id.

Now I run the script with a new _get to show the results.

If you are interested in the details:

[HorizonAPI] Working with UAG’s

Something that was added in the last few versions of the Horizon API is the option to handle UAG’s. Since I had to add an uag to my lab for another project I decided to find out what api calls are possible. First I’ll check what services there are.

$hvservice | Select-Object gateway*

I will ignore the GatewayAccessUserOrGroup since that was already in there so we are left with Gateway and GatewayHealth. Let’s see what methods are available under Gateway.

$hvservice.Gateway | gm

I Gateway_Get and Gateway_List will show the same information as always but with _Get you will need a gateway ID and it only shows the information about one gateway. WIth _List you will get the information about all registered gateways.

$hvservice.Gateway.Gateway_List()
$gw=$hvservice.Gateway.Gateway_List() | select-object -First 1
$hvservice.Gateway.Gateway_Get($gw.id)

Let’s see what’s in that GeneralData (Spoiler: not a lot!)

$gwdata=$hvservice.Gateway.Gateway_Get($gw.id)
$gwdata.GeneralData

To remove a gateway we use Gateway_Unregister with the gatewayid

$hvservice.Gateway.Gateway_Unregister($gw.id)

Now i need to register the Gateway again let’s see what we need for that.

$hvservice.Gateway.Gateway_Register

So we need an object of the type VMware.Hv.GatewaySpec. Let’s define that and see what it looks like.

$gwspec=New-Object VMware.Hv.GatewaySpec
$gwspec

So we only need the GatewayName, please use the exact name that was used to configure the UAG otherwise it can be added but it won’t be showing any data.

$gwspec.GatewayName="pod1uag1"

Now to register the UAG

$hvservice.Gateway.Gateway_Register($gwspec)

So with this we did everything we could with the Gateway service. Next is the GatewayHealth service.

$hvservice.GatewayHealth | Get-Member

as usual there’s only a get and a list so let’s see what data is in there.

$hvservice.GatewayHealth.GatewayHealth_List()
($hvservice.GatewayHealth.GatewayHealth_List()).ConnectionData

Sadly nothing more than the admin interface gives us but enough to build an health check like I did for the vCheck already (that can be found here)

For the type there are several options and those can be found in the API Explorer.

VALUE DESCRIPTION
“AP” AP type is for UAG.
“F5” F5 type is for F5 server.
“SG” SG type is for Security Server.
“SG-cohosted” SG-cohosted type is for Cohosted CS as gateway.
“Unknown” Unknown type is for unrecognized gateway type.

I was told by a VMware employee that SG-cohosted is fancy wording for a connection server.

And that’s everything we can do with UAG’s using the Horizon API’s!

[HorizonAPI] Changing the amount of desktops or RDS hosts in a pool/farm

Sometimes there is a need to change the amount of desktops/rds hosts in a pool/farm. Since doing this in the GUI sucks (although that seems to have gotten slightly better with 7.11) I prefer to do it using the API’s. Let’s start with a Desktop pool.

The easiest way to change pool settings is to use the helper function of a service. After connecting to the connection server we first need to query for the ID of the desktoppool that we need to change.

[VMware.Hv.QueryServiceService]$queryService = New-Object VMware.Hv.QueryServiceService
[VMware.Hv.QueryDefinition]$defn = New-Object VMware.Hv.QueryDefinition
$defn.queryEntityType = 'DesktopSummaryView'
$defn.Filter = New-Object VMware.Hv.QueryFilterEquals -property @{'memberName'='desktopSummaryData.name'; 'value' = "Pod01_Pool01"}
[array]$queryResults= ($queryService.queryService_create($HVservice, $defn)).results
$hvpoolid=$queryResults.id

To actually change the pool it’s the best to use the helper function of a service so we first put the desktopservice into an object

$desktopservice=new-object vmware.hv.DesktopService

The next step is to read the current settings into another object.

$desktophelper=$desktopservice.read($HVservice, $HVPoolID)

If you want to see what’s in here we’ll just do this

$desktophelper | get-member

With the get helper method’s it’s possible to get things while you can change them with their set counterpart. Don’t forget to use brackets when you want to go deeper.

$desktophelper.getAutomatedDesktopDataHelper() | get-member

And we can go on and on with this but I happen to already have found where the amount of desktops is listed.

$desktophelper.getAutomatedDesktopDataHelper().getVmNamingSettingsHelper().getPatternNamingSettingsHelper() | get-member

Let’s take a look at the getMaxNumberOfMachines method.

$desktophelper.getAutomatedDesktopDataHelper().getVmNamingSettingsHelper().getPatternNamingSettingsHelper().getMaxNumberOfMachines()

And we can actually use this with setMaxNumberOfMachines

$desktophelper.getAutomatedDesktopDataHelper().getVmNamingSettingsHelper().getPatternNamingSettingsHelper().setMaxNumberOfMachines(10)

But nothing has changed yet (and yes I am lazy so I will show it using the vmware.hv.helper module.

(get-hvpool -PoolName pod01_pool01).automateddesktopdata.VmNamingSettings.PatternNamingSettings

To apply the change to 10 vm’s we need to apply the helper using the update method

$desktopservice.update($hvservice, $desktophelper)

And when we check this with get-hvpool.

And we can do almost the same for RDS farms just a few details that are different in the naming of various objects.

[VMware.Hv.QueryServiceService]$queryService = New-Object VMware.Hv.QueryServiceService
[VMware.Hv.QueryDefinition]$defn = New-Object VMware.Hv.QueryDefinition
$defn.queryEntityType = 'FarmSummaryView'
$defn.Filter = New-Object VMware.Hv.QueryFilterEquals -property @{'memberName'='data.name'; 'value' = "pod1_rds_IC"}
[array]$queryResults= ($queryService.queryService_create($HVservice, $defn)).results
$hvfarmid=($queryResults).id
(Get-HVFarm -FarmName pod1_rds_ic).automatedfarmdata.RdsServerNamingSettings.PatternNamingSettings
[VMware.Hv.FarmService]$farmservice=new-object vmware.hv.FarmService
$farmhelper=$farmservice.read($HVservice, $HVFarmID)
$farmhelper.getAutomatedFarmDataHelper().getRdsServerNamingSettingsHelper().getPatternNamingSettingsHelper().setMaxNumberOfRDSServers(3)
$farmservice.update($HVservice, $farmhelper)