Horizon View Api’s: back to basics part 1: Connecting

Intro

I have done a lot of deep dives but just like the VMware{Code} session I did at VMworld I think it’s time to go back to the basics on how to work with the Horizon api’s from PowerCLI. First up is connecting to a Connection server and disconnecting. I will be showing various ways to do but the new and secure one is the best for me since that’s also usable when you want to schedule scripts.

The easy way

The easiest wat to connect is by using the connect-hvserver SERVERNAME

connect-hvserver pod1cbr1

This will give you a nice credentials popup.

The Unsecure way

The previous way that I used was by using the -user, -pass and maybe the -domain parameters.

connect-hvserver pod1cbr1 -user m_wouter@magneet -pass Password

The ‘new’ and secure way

Since one of the latest updates it is also possible to use a credential object. We found this out during the Hackathon @VMworld US that it is possible. It will use the good old credentials function from Powershell like in this post from 2008. First you’ll need to make a file with the encrypted password. Big thanks to Ariel & Edgar 🙂 check this for the vDocumentation script.

 read-host -assecurestring | convertfrom-securestring | out-file password.txt

The next two lines I will combine into one, just because I can.

$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist "magneet\m_wouter",(get-content .\password.txt | ConvertTo-SecureString)

Doing it in two lines is also possible and might make it a bit easier to read

$pass= get-content .\password.txt | ConvertTo-SecureString
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist "magneet\m_wouter", $pass

And then it’s time to connect

connect-hvserver -server pod1cbr1 -cred $cred

That’s easy right?

Connect to the api’s

There’s a little bit more to it so you can actually use the api’s. First we need to put the session into a variable. I always use a number so it’s easy to separate my various pods.

$hvserver1=connect-hvserver -server pod1cbr1 -cred $cred

Next up is actually making the services visible. Again I added the number for when I am working with multiple pod’s.

$Services1= $hvServer1.ExtensionData

And a quick look at the available services which I will explain in a next blog post.

Disconnecting

If you are connected to a single Connection server this is easy, just a disconnect-hvserver is enough.

disconnect-hvserver

Or without confirmation, this is a standard powershell thing.

disconnect-hvserver -confirm:$false

This will not work when you are connected to multiple Pod’s so you’ll need to specify the server you are connected to.

disconnect-hvserver -server pod2cbr1 -confirm:$false

The End

Next time I will go into some of the things you can do with the services I quickly showed you.

New View API query services in PowerCLI 10.1.1: pulling event information without the sql password.

A while back I already posted about new services that where available for the View API’s in PowerCLI 10.1.1. Recently the api explorer for this version was published and can be found here. Two things that I didn’t find back then was the addition of two services for the query service. The first is GlobalApplicationEntitlementInfo this one can be compared to the previously already available GlobalEntitlementSummaryView and will return information about global entitlements.

The second added services is extremely useful: you can now query the event database. This means you don’t need the actual sql password anymore to query the events. According to the api explorer at least Horizon 7.3 is required and only events from the Event and Event_Data database tables. A simple query will show all events.

$queryservice=new-object VMware.Hv.QueryServiceservice
$defn=new-object VMware.Hv.QueryDefinition
$defn.queryEntityType = 'EventSummaryView'
$results=($queryservice.QueryService_Query($services1,$defn)).results
$results

As you can see the data is divided in data and namesdata properties, these contain the same data as what is returned with get-hvevent. I added some selections to show only one event.

$results | where {$_.data.eventtype -like "*BROKER_USERLOGGEDIN*"}  | select -last 1 | select -expandproperty data

and

$results | where {$_.data.eventtype -like "*BROKER_USERLOGGEDIN*"}  | select -last 1 | select -expandproperty namesdata

Offcourse it;s better to use filtering from the query directly. The full lust for that is available from the api explorer but I will give a couple of examples. (be aware that membername and the value are case sensitive)

$queryservice=new-object VMware.Hv.QueryServiceservice
$defn=new-object VMware.Hv.QueryDefinition
$defn.queryEntityType = 'EventSummaryView'
$equalsFilter = New-Object VMware.Hv.QueryFilterEquals
$equalsFilter.membername='data.eventType'
$equalsFilter.value="BROKER_USERLOGGEDIN"
$defn.filter=$equalsFilter
($queryservice.QueryService_Query($services1,$defn)).results.data | select -last 1

Or by severity

$queryservice=new-object VMware.Hv.QueryServiceservice
$defn=new-object VMware.Hv.QueryDefinition
$defn.queryEntityType = 'EventSummaryView'
$equalsFilter = New-Object VMware.Hv.QueryFilterEquals
$equalsFilter.membername='data.severity'
$equalsFilter.value="WARNING"
$defn.filter=$equalsFilter
($queryservice.QueryService_Query($services1,$defn)).results.data | select -last 1

As said it can be filtered on other properties as well but that might require some more logic to get the userid or desktopid for example. This is a very useful addition in my opinion to the Horizon View api’s.

Registering an Instantclone administrator using PowerCLI

Another question Sean Massey asked me if it is possible to register an instant clone domain administrator. This is possible using the instantcloneenginedomainadministrator service with the InstantCloneEngineDomainAdministrator_create method. This needs a spec with the following content:

  • spec (vmware.hv.InstantCloneEngineDomainAdministratorSpec)
    • base (vmware.hv.InstantCloneEngineDomainAdministratorBase)
      • username (string)
      • domain (domainid)
      • password(vmware.hv.securestring)

The password can be created using the same scriptlet I used to register a new vCenter server. The domain ID can actually be gotten by listing all domains using

$services1.ADDomain.addomain_list()

For now I have created a scripts that requires you to give some details so it can register the instant clone domain administrator. It can also be found on Github but I will also definitively add it to the vmware.hv.helper module.

$icausername=read-host "What username to use for instantclone administrator?"
$icadomain=read-host "please give the dns name for the domain to user (i.e. domain.com)"
$icapassword=read-host "vCenter User password?" -assecurestring
$temppw = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($icaPassword)
$PlainicaPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($temppw)
$icadminPassword = New-Object VMware.Hv.SecureString
$enc = [system.Text.Encoding]::UTF8
$icadminPassword.Utf8String = $enc.GetBytes($PlainicaPassword)
$spec=new-object vmware.hv.InstantCloneEngineDomainAdministratorSpec
$spec.base=new-object vmware.hv.InstantCloneEngineDomainAdministratorBase
$spec.base.domain=(($services1.ADDomain.addomain_list() | where {$_.DnsName -eq $icadomain} | select-object -first 1).id)
$spec.base.username=$icausername
$spec.base.password=$icadminpassword
$services1.InstantCloneEngineDomainAdministrator.InstantCloneEngineDomainAdministrator_Create($spec)

Multi vlan Network for Horizon View using PowerCLI & API’s

One of the things I wanted to do for a while is to write an API version on how to use multiple dvSwitch portgroups with Horizon View linked clones. With instant clones there’s a gui way to select multiple portgroups but for instant clones the only was to do this was to use the View PowerCLI. This gets installed with the connection server and can only be used from there. What you do is create a file, edit and apply it. Johan has described this process very well on his blog. I decided there had to be a way to do this as well with ‘regular’ PowerCLI & the api’s.

The api explorer shows a property named networklabel for both desktop pools and rds farms. This entry showed me what data I needed to configure. I spent most of my time in gathering all the data for this. As you can see in the script I had to dig rather deep to get all information like hostorclusterid and snapshotid. This information then needs to be put into an object called nics.

The script I made is a working prove of concept and doesn’t contain logic about what portgroups to apply. It just grabs all portgroups that comply with a simple filter. It then grabs the id’s for those and configures them to use for the pool. The script grabs information using the snapshotid but in my testing it’s 100% safe to change snapshots or golden images after that, is just uses that information to know where to configure things.

Something I found during testing is that the maximum amount of labels is respected and spread over all port groups as long as there are labels available. If the system runs out of labels it will continue using only the last configured label! I have tested this on View 6.2 and 7.3.2 with vSphere 6.5 on both methods of configuring the portgroups.

This is the script, it asks for some required information at first. This way you don’t have to put a password in plain text in the script. You can see I have the maxlabeltype and enabled properties pre-configured as LIMITED and $true. If the maxlabeltype is UNLIMITED the composer would stop using any other labels configured after that one and if enabled would be $false that label wouldn’t be used at all..

#-------------------------------------------------
# Linked Clone Configure multiple vlan's
# This script is created to allow a Linked Clone
# Desktop pool to use multiple vlan's
#
# In the past only the 'old' View PowerCLI on the Connection
# broker could be used to accomplish this. Now it's possible 
# from any system running PowerCLI 6.5 or above.
#
# This version replaces all current settings!
# 
# Requires PowerCLI 6.5 or higher
#
# Feel free to use or alter in anyway but please remember the original creator :)
#
# Version 1.0
# 16-01-2018
# Created by: Wouter Kursten
# https://retouw.eu
# Twitter @Magneet_NL
#-------------------------------------------------

$hvservername=Read-host "Which Connection broker do you want to connect to?"
$domain=read-host "Please enter your active directory domain?"
$username=Read-host "Please enter your useraccount"
$password=Read-host -assecurestring "Please enter your password"
$poolname=read-host "What pool to configure?"
$labelfilter=Read-host "What portgroups do you wnat to configure (use * as wildcard i.e. DVVDI*)"
$maxlabels=read-host "How many labels to configure per portgroup?"

#Connect to View Connection broker
Import-module vmware.hv.helper
write-host "Connecting to the connection broker" -ForegroundColor Green
try {
	$hvserver1=connect-hvserver $hvservername -domain $domain -username $username -password $password -WarningAction silentlyContinue -erroraction stop
	$Services1= $hvServer1.ExtensionData
}
catch {
	Write-host "Can't connect to the Connection server please check the credentials." -ForegroundColor Red
	exit
}
$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.name'; 'value' = $poolname}
try     {
        $poolid=($queryService.queryservice_create($Services1, $defn)).results
        }
catch   { 
        throw "Can't find $poolname, exiting" 
        }

$pool=$Services1.Desktop.desktop_get($poolid.id)
$networklabelsall=$services1.networklabel.NetworkLabel_ListByHostOrCluster($pool.AutomatedDesktopData.VirtualCenterProvisioningSettings.VirtualCenterProvisioningData.hostorcluster)
$networklabels=$networklabelsall | where-object {$_.data.name -like $labelfilter}
$NetworkInterfaceCard=$services1.NetworkInterfaceCard.NetworkInterfaceCard_ListBySnapshot($pool.AutomatedDesktopData.VirtualCenterProvisioningSettings.VirtualCenterProvisioningData.snapshot)
$NetworkInterfaceCardSettings=new-object vmware.hv.desktopNetworkInterfaceCardSettings
$NetworkInterfaceCardSettings.nic=$NetworkInterfaceCard.id
$networkLabelAssignmentSpecs=@()

foreach ($networklabel in $networklabels){
    $NetworkLabelAssignmentSpec=new-object VMware.Hv.desktopNetworkLabelAssignmentSpec
    $NetworkLabelAssignmentSpec.enabled=$True
    $NetworkLabelAssignmentSpec.networklabel=$networklabel.id
    $NetworkLabelAssignmentSpec.maxlabeltype="LIMITED"
    $NetworkLabelAssignmentSpec.MaxLabel=$maxlabels
    $networkLabelAssignmentSpecs+=$networkLabelAssignmentSpec
    }
$NetworkInterfaceCardSettings.networkLabelAssignmentSpecs=$networkLabelAssignmentSpecs

$VirtualCenterNetworkingSettings=@()
$VirtualCenterNetworkingSettings=new-object vmware.hv.DesktopVirtualCenterNetworkingSettings
$VirtualCenterNetworkingSettings.nics+=$NetworkInterfaceCardSettings

$desktopService = New-Object VMware.Hv.DesktopService
$desktopInfoHelper = $desktopService.read($services1, $Pool.Id)
$desktopinfohelper.getAutomatedDesktopDataHelper().getVirtualCenterProvisioningSettingsHelper().setVirtualCenterNetworkingSettingsHelper($VirtualCenterNetworkingSettings)
$desktopservice.update($services1, $desktopInfoHelper)

I used a lot of variables and arrays with the names as they are pulled from the data, that explains their long names. Afterwards it doesn’t give any feedback. For this I created a separate script so you can separately check what is configured before or after you change the configuration:

#-------------------------------------------------
# Linked Clone get vlan configuration
# This script is created to check if a linked clone pool 
# has any configured vlan/portgroup configuration
#
# Requires PowerCLI 6.5 or higher 
#
# Feel free to use or alter in anyway but please remember the original creator :)
#
# Version 1.0
# 16-01-2018
# Created by: Wouter Kursten
# https://retouw.eu
# Twitter @Magneet_NL
#-------------------------------------------------

#region variables
$hvservername=Read-host "Which Connection broker do you want to connect to?"
$domain=read-host "Please enter your active directory domain?"
$username=Read-host "Please enter your useraccount"
$password=Read-host -assecurestring "Please enter your password"
$poolname=read-host "What pool to check?"

#endregion

#region Connect to View Connection broker
Import-module vmware.hv.helper
write-host "Connecting to the connection broker" -ForegroundColor Green
try{
    $hvserver1=connect-hvserver $hvservername -domain $domain -username $username -password $password -WarningAction silentlyContinue -erroraction stop
    $Services1= $hvServer1.ExtensionData
}
catch{
    Write-host "Can't connect to the Connection server please check the credentials." -ForegroundColor Red
    exit
}
    
#endregion

#regio gather and display data
$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.name'; 'value' = $poolname}
try     {
        $poolid=($queryService.queryservice_create($Services1, $defn)).results
        }
catch   { 
        throw "Can't find $poolname, exiting" 
        }

$pool=$Services1.Desktop.desktop_get($poolid.id)
$labels=($pool.automateddesktopdata.virtualcenterprovisioningsettings.VirtualCenterNetworkingSettings.nics).NetworkLabelAssignmentSpecs
if (!$labels){
    write-output "No configured portgroup(s) or $poolname not found."
}
else{
    $output=@()
    foreach ($label in $labels){
        $output+= New-Object PSObject -Property @{
            "Labelname" = get-hvinternalname $label.networklabel;
            "Enabled" = $label.Enabled;
            "Labeltype" = $label.maxlabeltype;
            "Max_labelcount" = $label.maxlabel;
        }
    }
$output | select-object Labelname,Labeltype,Max_labelcount,enabled
}

And the result:

In the end the script looks and is way more complex than the ‘old’ way to assign multiple vlans. On the other hand it is way more flexible to use in any scripting you are already using for the automation of your Horizon environment.

As always both scripts can be found on Github here and here.

New and updated VMware flings for August 2017

Intro

(For those of you who ever watch or used to watch WWE think: New Age Outlaws. For those who never did watch this from about 1:40.

Ladies and gentlemen, boys and girls, nerds of all ages. Retouw.nl proudly brings to you, the monthly  VMware Labs updated Fliiiiings. The new, the updated change logs and all.

“And if you ain’t down with that I got two words for ya: read it!”

This month we had two new flings and six updated including a dinosaur that I even forgot it existed!

New Flings

vRealize Operations Export tool

Ever felt the need to export all of that vRops data because you don’t trust the recommendations it makes for you? This is your chance to do just that. The vRealize Operations Export Tool actually is an Open Source Fling and can be found on Github. If you want to know more about the VMware Open Source initiative visiting this site might be usefull.

Changelog

No changelog yet.

DRS Dump Insight

While DRS Lens already gives you some insight in why DRS actions might be happening the DRS Dump Insight actually uses drmdump files created on vCenter and analyses why a DRS action really happened or not and you can also run what-if scenarios to see what would happen if a threshold had been breached.

Changelog

Again no changelog yet.

Updated flings

Like I said 6 updated flings and let’s start with the Dinosaur you (like me) might have forgotten.

Visual Esxtop

WHAT? Yes Visual Esxtop has been updated! Duncan wrote about this over four years ago and I believe it might actually be older then that. The name says enough, this shows you the output from ESXtop in a graphical way and since I can never ever describe it better then Duncan head over there to read about it!

Changelog

I could copy the only changelog item but since that mentions vSphere 5.5 I think this might be an old one 🙂

ESXi Embedded Host Client

The ESXi Embedded Host client is in the GA product since 6.x but there’s still lab updates being released. Some very nice fixes have been implemented.

Changelog

Version 1.23.0 build 6360286 (Fling 18) – August 16, 2017

Minor features and bugfixes

  • General
    • Display the VM List in the Host autostart settings
    • Fix role selection in IE 11
    • Correct partition info portlet
    • Better handling of unknown partition types
    • Fix issue with fractional cores per socket in VM settings
    • Several wizard fixes
    • Remove persistent warning when importing VMs that include a floppy drive
    • Fix hidden selection when using the ‘select all’ checkbox in a filtered VM list
    • Handle OVAs with a missing description field
    • Available NICs display correctly
    • Default VMFS to the most recent version when formatting
    • Security fixes

VMware OS Optimization Tool

This is THE go to application if it comes to building golden images for VDI or SBC environments. If it is Horizon or Citrix if you don’t optimize you will fail!

Changelog

August 2, 2017

  • New Template: App Volumes Packaging Machine – This template is intended to be used by Application Packagers who are responsible for creating AppStacks and should only be used on the ‘Packaging machine’.

vSphere HTML5 Web Client

The HTML5 client  got a couple of updates with heaps of new features and bugfixes.

Changelog

Fling 3.20 – Build 6433743

New Features

  • Installed I/O Filters for Cluster and Host
  • Create and configure network resource pools in Network I/O Control v3

Bug Fixes

  • Fixed exception when navigating to VM summary page and configuring VM overrides: “Could not fetch query binding: com.vmware.vsphere.client.clusterui.model.services.VmFailureResponsesData”

Known Issues

  • If you see error in the vSphere Client (HTML5) similar to this – ‘getHostIsAssignLicenseActionAvailable’, then you can resolve this error by following below steps:
    • If vSphere Client (HTML5) Fling appliance is pointed to a vCenter Server Appliance (VCSA), then you should reregister the fling appliance by logging in to FAMI UI (or by running the config-ui CLI). Refer the instructions document to follow the steps for configuring Fling appliance for VCSA.
    • If vSphere Client (HTML5) Fling appliance is pointed to a Windows vCenter Server, then reregister by downloading latest server-configure.bat from the Download section of this website. Refer the instructions document to follow the steps for configuring Fling appliance for Windows vCenter Server.

Fling 3.19 – Build 6365405

New Features

  • Add host and client USB device to a VM
  • Add USB controller
  • Assign License action on VC/Cluster/Host
  • Edit/Clone VM Storage Policy
  • Edit Storage Policies of a VM (Actions > VM Policies > Edit VM Storage Policies…)
  • Storage Policy components view
  • Create/Delete Storage Policy components
  • Related VM Templates view for a Storage Policy
  • Mount VVOL datastore action
  • VVOL Capability Profiles Capacity portlet
  • Create and edit VM customization specifications (without custom network configurations)
  • Configure per disk option on Select storage page when cloning VM/template
  • Host lists can be sorted by consumed CPU and memory
  • Monitoring DRS memory utilization for clusters allows switching between active and consumed memory for the charts
  • Updated UI of the compatibility issues dialog in the migrate wizard – ability to sort the compatibility by VM, host or compatibility issue

Bug Fixes

  • The list of physical network adapters didn’t render correctly for some ESX hosts and an error message was appearing on the top of the page
  • Setting the DRS advanced option “PercentIdleMBInMemDemand” through the advanced settings now works for any value

Known Issues

  • If you see error in the vSphere Client (HTML5) similar to this – ‘getHostIsAssignLicenseActionAvailable’, then you can resolve this error by following below steps:
    • If vSphere Client (HTML5) Fling appliance is pointed to a vCenter Server Appliance (VCSA), then you should reregister the fling appliance by logging in to FAMI UI (or by running the config-ui CLI). Refer the instructions document to follow the steps for configuring Fling appliance for VCSA.
    • If vSphere Client (HTML5) Fling appliance is pointed to a Windows vCenter Server, then reregister by downloading latest server-configure.bat from the Download section of this website. Refer the instructions document to follow the steps for configuring Fling appliance for Windows vCenter Server.
  • If you see this error when you click on the VM – “Could not fetch query binding: com.vmware.vsphere.client.clusterui.model.services.VmFailureResponsesData cause: java.lang.RuntimeException: Could not fetch query binding: com.vmware.vsphere.client.clusterui.model.services.VmVmcpSupportData”, collaps the HA portlet in the VM summary. We are working on fixing this.

HCIBench

HCIBench is a tool to test your hyperconverged infrastructure. No vSan required, any HCI is good as long as it runs vSphere.

Changelog

Version Version 1.6.3

  • Enhanced vSANPerformanceDiagnose function call
  • Enhanced port 443 validation
  • Enhanced results calculation
  • Added host maintenance mode validation
  • Added deployment validation

Horizon Toolbox

This one came out at the very last moment of August. Some bugs have been fixed and a couple of old features that had been removed have been re-added but have been marked deprecated.

Changelog

2017-Aug-31 Horizon Toolbox 7.2.1

Bugs fixed

  • Auditing – Export CSV failed
  • Console Access – Some vCenter versions were not supported. Now, almost all vCenter versions after 5.5 are supported.
  • Console Access – “Parent VMs” show all VMs. Now only the VMs which are (or ready to be) parent VMs are shown.
  • Installation sometimes failed due to Tomcat error. Now, the installation should be successful every time if the Connection Server is good.

New Features

  • Console Access – “Problem VMs” show the VMs with View Agent, but in abnormal status like “error”, “unavailable” or others.

The following features are added back since some customers strongly require these features, but they are marked as “deprecated”, since we suggest using the production features in Horizon or VIDM.

  • Management- Remote Assistance
  • Management- Device Access Filter

New and updated VMware flings for july 2017

Intro

I decided to make this almost monthly post a bit wider and just post updates and new releases of all flings in that month. There are four flings that have been updated at least once this month.

New Flings

There has been one new release this month:

DRS Lens

During the development fase at some point DRS Lens was named DRS Goggle so if you talk to me irl it might be possible that I call it that way. What this Flings does is give you insight in DRS activity. In several dashboards it will help the user visualize why DRS did or maybe didn’t move those vm’s you are so attached to.

As VMware vSphere DRS has become more widely adopted now, more and more users are interested in knowing how it works. They need more insights into DRS activity and actions. They want to know the value that DRS provides to their clusters. DRS Lens is an attempt to provide a UI-based solution to help understand DRS better.

DRS Lens provides a simple, yet powerful interface to highlight the value proposition of vSphere DRS. Providing answers to simple questions about DRS will help quell many of the common concerns that users may have. DRS Lens provides different dashboards in the form of tabs for each cluster being monitored.

Changelog

Version 1.1

  • Added login compatibility to 5.5 vCenter
  • Fixed VC certificate parsing bug found with some 5.5 vCenters

Updated flings

These Flings have received one or more updates during this month.

Horizon Toolbox 2

The Horizon toolbox 2 has been updated to version 7.2 and since Horizon 7.2 itself now contains a Remote Assistance feature in the helpdesk part this has been removed from the fling. This is stil one of my favorite flings that has functionality that should be in Horizon itself!

Changelog

2017 Jul 17

New Features

  • Support Horizon 7.2. Horizon Toolbox uses the same version as the latest supported Horizon.
  • Support end users’ actions auditing (agent side), including USB storage, Client Drive Redirection and Clipboard.
  • Support vSphere Console Access to all Parent Images.

Bug Fixes

  • Fix one bug which caused the number of concurrent sessions not accurate.
  • Fix one bug which caused missed domains in login page.

Removed Features

  • Remote Assistance is part of Horizon 7.2 production (in Help Desk). So we have removed this feature from Horizon Toolbox.

vSphere html5 web client

The updates for this really great fling don’t get a date but a build number. I could find that 3.16 was released early July so I decided to take that one as the oldest for the changelog of the vSphere html5 web client.

Changelog

Fling 3.18 – Build 6163115

Improvements

  • Upgrade distributed switch wizard now supports the upgrade of LACP to Enhanced mode and the upgrade of Network I/O Control to version 3.
  • View settings of link aggregation groups on a distributed switch

Fling 3.17 – Build 6088028

New Features

  • Create VM Storage Policy (limited)
    • Migrate Host Networking to a Distributed Switch
    • Configure default gateway address on VMkernel adapters (ESX 6.5 only)
    • Network I/O Control v3 – configure shares, reservation and limit for the different types of system traffic
    • Customize hardware options when cloning VM or deploying VM from template
    • Create VVol Storage Policies

Improvements

  • Warn when about to edit the settings or perform snapshot operations on VM managed by a solution
  • Warning message when uploading files bigger than the datastore free space

Known Issues

  • Import Item into Content Library is not working.

Bug Fixes

  • Fixed the bug on import workflow in content library

Fling 3.16 – Build 5956761

New Features

  • Create VM Storage Policy (limited)
    • Create vSAN Policy (without Tags)
    • Create Policy with Tags and Common rules
  • Distributed Switch
    • Manage physical network adapters at the host level
    • LACP support – view the link aggregation groups created on a distributed switch
    • Upgrade distributed switch wizard
  • SR-IOV support – enable/disable SR-IOV on physical network adapters that support it
  • Content Library
    • Tags, notes, subscription/Publication portlet
    • Edit settings on the content library
    • Delete Content Library
    • Synchronize Library

Improvements

  • Select TCP/IP stack while creating new VMkernel network adapter

Known Issues

  • Import Item into Content Library is not working.

HCIBench

HCIBench is a tool developed for benchmarking the hyper-converged infrastructure. It not only works for VSAN but for all kinds of hyper-converged solutions. Again this tool has no build date but version but the Internet Waybackmachine found for me that 1.6.1 was released back in february.

Changelog

Version 1.6.2

  • Integrated with vSAN Performance Diagnostic of vSphere_6.5U1/vSAN_6.6.1.
  • Added DHCP Service validation.
  • Added Vdbench workload profile validation.
  • Removed the root password expiration policy.
  • Changed results display to show full file names.
  • Changed easy-run calculation from host basis to disk-group basis.

Updated flings for Horizon View in May

Yes I am a bit late but there are only two Horizon View related flings that received an update last month. First is the OS Optimization tool and second is the Ubuntu OVA for Horizon. The OSOT even already received an update in June but that’s for next month.

Ubuntu OVA for Horizon

Changelog:

v1.1.0

  • MATE Only Release
  • Increased vRAM to 128 MB instead of Automatic
  • Removed Audio Device
  • Updated default network device to VMXNET3
  • Updated repository for open-vm-tools to Ubuntu repo
  • Added Horizon 7.1 Agent Dependencies
  • Updated Dependency packages for Ubuntu 16.04 on Horizon 7.1
  • Agent installer script updated with Horizon 7.1 links
  • Updated Media Codec packages for Ubuntu 16.04
  • Updated MATE packages to Xenial
  • More reliable domain join
  • Password update optional
  • Timezone update optional
  • Option to change hostname
  • Desktop addons optional
  • Added retry attempts for failed wgets of smb and krb5 configuration files
  • Renamed ‘horizon-linux-installer.sh’ to ‘linux-agent-installer.sh

VMware OS Optimization Tool

Changelog

May 16, 2017

  • OSOT binary is now digital-signed, to make sure the integrity of distribution
  • Template update: Windows 10 – Item “Use small icons on taskbar” is unselected by default.

Building a Horizon View vCheck (part 3)

So it’s time for part 3 already of building checks for Horizon View. I got some remarks after last post and thus I need to say that the checks have been created for View 7 because some commands might not work against a 6.* installation. three new plugins this time or actually two since one was already in the original uploads on github but I didn’t mention it on here yet.

11 Linked Clone Desktop Pool Information.ps166

Just like the full clone pool information but tailored for linked pools.

# Start of Settings
# End of Settings

$automatedpoolstatus=@()
foreach ($pool in $pools){
$poolname=$pool.base.name
if ($pool.type -like "*automated*" -AND $pool.source -like "*VIEW_COMPOSER*"){
$desktops=get-hvmachinesummary -pool $poolname
$automatedpoolstatus+=New-Object PSObject -Property @{"Name" = $Poolname;
								"Pool_Image" = $pool.automateddesktopdata.VirtualCenternamesdata.parentvmpath;
								"Pool_Snapshot" = $pool.automateddesktopdata.VirtualCenternamesdata.snapshotpath;
								"Desktop_Count" = ($desktops).count;
								"Available" = ($desktops | where {$_.base.basicstate -eq "AVAILABLE"}).count;
								"Connected" = ($desktops | where {$_.base.basicstate -eq "CONNECTED"}).count;
								"Disconnected" = ($desktops | where {$_.base.basicstate -eq "DISCONNECTED"}).count;
								"Maintenance" = ($desktops | where {$_.base.basicstate -eq "MAINTENANCE"}).count;
								"Provisioning" = ($desktops | where {$_.base.basicstate -eq "PROVISIONING"}).count;
								"Customizing" = ($desktops | where {$_.base.basicstate -eq "CUSTOMIZING"}).count;
								"Already_Used" = ($desktops | where {$_.base.basicstate -eq "ALREADY_USED"}).count;
								"Agent_Unreachable" = ($desktops | where {$_.base.basicstate -eq "AGENT_UNREACHABLE"}).count;
								"Error" = ($desktops | where {$_.base.basicstate -eq "ERROR"}).count;
								"Deleting" = ($desktops | where {$_.base.basicstate -eq "DELETING"}).count;
								"Provisioning_Error" = ($desktops | where {$_.base.basicstate -eq "PROVISIONING_ERROR"}).count;
}
}
}
$automatedpoolstatus | select Name,Pool_Image,Pool_Snapshot,Desktop_Count,Available,Connected,Disconnected,Maintenance,Provisioning,Customizing,Already_Used,Agent_Unreachable,Error,Deleting,Provisioning_Error
$Title = "Linked Clone Desktop Pool Status"
$Header = "Linked Clone Desktop Pool Status"
$Comments = "These are the pools that have floating linked clones. Not all but the most common status's are counted."
$Display = "Table"
$Author = "Wouter Kursten"
$PluginVersion = 0.1
$PluginCategory = "View"

13 Dedicated Full Clones Assignment.ps1

This plugin is targeted at the dedicated full clones (and I just realize that one can also have dedicated linked clones so will need to build one for that as well). It gives information about which desktop is assigned to which account but also with information about the host it is running on if this information is available (not in my case).

# Start of Settings
# End of Settings

$fulldesktopassignment=@()
foreach ($pool in $pools){
$poolname=$pool.base.name
if ($pool.type -like "*automated*" -AND $pool.source -like "*VIRTUAL_CENTER*"){
	$desktops=get-hvmachinesummary -pool $poolname
	foreach ($desktop in $desktops){
	if ($desktop.namesdata.username){
		$username=$desktop.namesdata.username
		}
	else{
		$username="Unassigned"
		}
$fulldesktopassignment+=New-Object PSObject -Property @{"Pool_Name" = $Poolname;
								"Desktop_Name" = $desktop.base.name;
								"Desktop_State" = $desktop.base.basicstate;
								"Desktop_Assigned_to" = $username;
								"Desktop_OperatingSystem" = $desktop.base.Operatingsystem;
								"Agent_version" = $desktop.base.agentversion;
								"Host" = $desktop.managedmachinesdata.hostname;
								"Datastore" = $desktop.ManagedMachineNamesData.datastorepaths | out-string;
}
}
}
}
$fulldesktopassignment | select Pool_Name,Desktop_Name,Desktop_State,Desktop_Assigned_to,Desktop_OperatingSystem,Agent_version,Host,Datastore
$Title = "Dedicated Desktop Pool Assignment"
$Header = "Dedicated Desktop Pool Assignment"
$Comments = "These are the dedicated desktops with their current user assignment"
$Display = "Table"
$Author = "Wouter Kursten"
$PluginVersion = 0.1
$PluginCategory = "View"

04 License Status.ps1

This plugin gives licensing information including expiration date and what techniques are allowed under this license.

# Start of Settings
# End of Settings

$licensestatus=@()

$license=($services1).license.license_get()
$licensestatus+=New-Object PSObject -Property @{"Licensed" = $license.Licensed;
								"LicenseKey" = $license.LicenseKey;
								"ExpirationTime" = $license.ExpirationTime;
								"ViewComposerEnabled" = $license.ViewComposerEnabled;
								"DesktopLaunchingEnabled" = $license.DesktopLaunchingEnabled;
								"ApplicationLaunchingEnabled" = $license.ApplicationLaunchingEnabled;
								"InstantCloneEnabled" = $license.InstantCloneEnabled;
								"UsageModel" = $license.UsageModel;
}								

$licensestatus | select Licensed,LicenseKey,ExpirationTime,ViewComposerEnabled,DesktopLaunchingEnabled,ApplicationLaunchingEnabled,InstantCloneEnabled,UsageModel

$Title = "License Status"
$Header = "License Status"
$Comments = "This is the license status information"
$Display = "Table"
$Author = "Wouter Kursten"
$PluginVersion = 0.1
$PluginCategory = "View"

Building a Horizon View vCheck (part 2)

So last time I created some simple scripts for the Horizon View vCheck. This time I wanted to add some information about the Composer, Connection, security servers and the event database. So all in all I added four scripts that might seem to do the same but since the api’s treat the types of servers differently I decided to make separate scripts as well.

Please pull the scripts from Github since by the time you read this post things might have changed.

05 Connection Servers Status.ps1

This plugin pulls some information about the connection servers, if the status is ok and gives a warning if the Certificate will expire within 30 days. This period is something I need to change in the future to a setting so it will be customizable.

# Start of Settings
# End of Settings

$date=get-date
$datemaxexp=(get-date).adddays(30)
$conserverstatus=@()
$conservers=$services1.connectionserverhealth.connectionserverhealth_list()
foreach ($conserver in $conservers) {
if ($conserver.CertificateHealth.ExpirationTime -lt $date){
$expiring="Already Expired"
}
elseif ($conserver.CertificateHealth.ExpirationTime -lt $datemaxexp){
$expiring="Expiring in 30 days"
}
else {
$expiring="False"
}

$conserverstatus+=New-Object PSObject -Property @{"Name" = $conserver.name;
								"Status" = $conserver.Status;
								"Version" = $conserver.Version;
								"Build" = $conserver.Build
								"Certificate_Status" = $conserver.CertificateHealth.Valid;
								"Certificate_Expiration_Time" = $conserver.CertificateHealth.ExpirationTime;
								"Certificate_Expiring" = $expiring;
								"Certificate_Invalidation_Reason" = $conserver.CertificateHealth.InValidReason;
								
}
}
$conserverstatus | select name,Status,Version,Build,Certificate_Status,Certificate_Expiring,Certificate_Expiration_Time,Certificate_Invalidation_Reason 

$Title = "Connection Servers Status"
$Header = "Connection Servers Status"
$Comments = "These are the used Connection Servers"
$Display = "Table"
$Author = "Wouter Kursten"
$PluginVersion = 0.1
$PluginCategory = "View"

06 Security Servers Status.ps1

Almost the same as the connection servers but this time it checks for the security servers. I don’t run the appliance yet so will need to check on those somewhere as well.

# Start of Settings
# End of Settings

$date=get-date
$datemaxexp=(get-date).adddays(30)
$secserverstatus=@()
$secservers=$services1.securityserverhealth.securityserverhealth_list()
foreach ($secserver in $secservers) {
if ($secserver.CertificateHealth.ExpirationTime -lt $date){
$expiring="Already Expired"
}
elseif ($secserver.CertificateHealth.ExpirationTime -lt $datemaxexp){
$expiring="Expiring in 30 days"
}
else {
$expiring="False"
}

$secserverstatus+=New-Object PSObject -Property @{"Name" = $secserver.name;
								"Status" = $secserver.Status;
								"Version" = $secserver.Version;
								"Build" = $secserver.Build
								"Certificate_Status" = $secserver.CertificateHealth.Valid;
								"Certificate_Expiration_Time" = $secserver.CertificateHealth.ExpirationTime;
								"Certificate_Expiring" = $expiring;
								"Certificate_Invalidation_Reason" = $secserver.CertificateHealth.InValidReason;
								
}
}
$secserverstatus | select name,Status,Version,Build,Certificate_Status,Certificate_Expiring,Certificate_Expiration_Time,Certificate_Invalidation_Reason 

$Title = "Security Servers Status"
$Header = "Security Servers Status"
$Comments = "These are the used Security Servers"
$Display = "Table"
$Author = "Wouter Kursten"
$PluginVersion = 0.1
$PluginCategory = "View"

07 Composer Servers Status.ps1

Strangely enough the composer server doesn’t have a status in the api’s. I would have expected at least something for it being available or not. Because of this I only added information and the vCenter server it is connecting to. Another weird thing (might be me offcourse) is that the vcentername actually gives a plural output even though composer and vCenter have a 1on1 relation,

# Start of Settings
# End of Settings

$comserverstatus=@()
$comservers=$services1.viewcomposerhealth.viewcomposerhealth_list()
foreach ($comserver in $comservers) {
$vcenters=$comserver.data.virtualcenters

foreach ($vcenter in $vcenters){
if ($vcenternames){
$vcenternames+=","
$vcenternames+=($services1.virtualcenterhealth.virtualcenterhealth_get($vcenter)).data.name
}
else{
$vcenternames+=($services1.virtualcenterhealth.virtualcenterhealth_get($vcenter)).data.name
}
}
$comserverstatus+=New-Object PSObject -Property @{"Name" = $comserver.ServerName;
								"Version" = $comserver.Data.Version;
								"Build" = $comserver.Data.Build;
								"vCenter_Server"= $vcenternames
								
}
}
$comserverstatus | select name,Version,Build,vcenter_server

$Title = "Composer Servers Status"
$Header = "Composer Servers Status"
$Comments = "These are the used Composer Servers"
$Display = "Table"
$Author = "Wouter Kursten"
$PluginVersion = 0.1
$PluginCategory = "View"

08 Event Database Status.ps1

For the event database I decided to give as much information as possible from the api’s. Maybe in the future it could pull some information from the sql server itself but I think that should be covered by a sql check.

# Start of Settings
# End of Settings


$eventdbstatus=@()
$eventdb=$services1.EventDatabaseHealth.EventDatabaseHealth_get()
if ($eventdb.configured -eq $True){
$eventdbstatus+=New-Object PSObject -Property @{"Servername" = $eventdb.data.Servername;
								"Port" = $eventdb.data.Port;
								"Status" = $eventdb.data.State;
								"Username" = $eventdb.data.Username;
								"DatabaseName" = $eventdb.data.DatabaseName
								"TablePrefix" = $eventdb.data.TablePrefix;
								"State" = $eventdb.data.State;
								"Error" = $eventdb.data.Error;
}
}
$eventdbstatus | select Servername,Port,Status,Username,DatabaseName,TablePrefix,State,Error 

$Title = "Event Database Status"
$Header = "Event Database Status"
$Comments = "These are the settings for the Event Database"
$Display = "Table"
$Author = "Wouter Kursten"
$PluginVersion = 0.1
$PluginCategory = "View"

The result

Building a Horizon View vCheck with those nice api’s (part 1 of ??)

Intro

Ever since I saw Alan Renouf’s vCheck script first in action years ago it has been one of the tools I have been promoting to use for daily checks. The fact that you can disable and enable plugins makes it a flexible adjustable solution that helped me preventing companies having big problems or proving that I have been warning them about things for weeks or months. Also I have whipped many colleague or customer around the ears with questions why they didn’t remove those snapshot they created 3 days before

Getting started

Fast forward until a couple of months ago when I saw those release note’s for PowerCli 6.5 with more options to talk to the Horizon View api’s. This immediately gave me the idea to build a set of vCheck scripts for Horizon View. One of the first things to do was finding out how the vCheck framework actually works. This turned out to be a matter of outputting the info you would like in the output as if it is on the command line. Also adding a section that contains a description helps in building the output:

$Title = "Composer Servers Status"
$Header = "Composer Servers Status"
$Comments = "These are the used Composer Servers"
$Display = "Table"
$Author = "Wouter Kursten"
$PluginVersion = 0.1
$PluginCategory = "View"

The 2nd thing to do is deciding on what checks needed to be build. After checking on the vExpert slack and with some co-workers and friends I came up with a shortlist:

  • Dashboard error status (Sean Massey)
  • Desktops with error (non-standard) status (Myself,Sean Massey)
  • Compare the Snapshots that have been set to the ones actually used on desktops to see if recompose might not have run (Brian Suhr, myself)
  • relation between Composer and vCenter (Kevin Leclaire)
  • last use time for dedicated desktops (Kees Baggeman)
  • Event Database status
  • Connection,composer,security server status
  • Information and status about the various desktop pool types
  • RDS farm status

Getting things done

Before actually building any checks a connecton has to be made this is done in the Connection plugin:

$Title = "Connection settings for View"
$Author = "Wouter Kursten"
$PluginVersion = 0.1
$Header = "Connection Settings"
$Comments = "Connection Plugin for connecting to View"
$Display = "None"
$PluginCategory = "View"

# Start of Settings
# Please Specify the address of one of the connection servers or the address for the general View environment
$Server = "Servername"
# Maximum number of samples to gather for events
$MaxSampleVIEvent = 100000
# Please give the user account to connect to Connection Server
$hvcsUser= "username"															
# Please give the domain for the user to connect to Connection Server
$hvcsDomain = "domain"														

# End of Settings



# Credential file for the user to connect to the Connection Server
$hvcsPassword = get-content .\hvcs_Credentials.txt | convertto-securestring		
# Credential file for the User configured n View to connect to the Database
$hvedbpassword=get-content .\hvedb_Credentials.txt | convertto-securestring   	

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

# --- Connect to Horizon Connection Server API Service ---
$hvServer1 = Connect-HVServer -Server $server -User $hvcsUser -Password $hvcsPassword -Domain $hvcsDomain

# --- Get Services for interacting with the View API Service ---
$Services1= $hvServer1.ExtensionData

# --- Connect to the view events database ---
#$eventdb=connect-hvevent -dbpassword $hvedbpassword

# --- Get Desktop pools
$pools=(get-hvpool)

As you might notice the vmware.hv.helper plugin is required to do this.

The first real check I decided to build was to see if the desktops are actually build on the same snapshot as configured on pool level. With this you are able to see if a recompose ran into trouble. Let me highlight some of the code:

if ($pool.type -like "*automated*" -AND $pool.source -like "*VIEW_COMPOSER*"){

There are a couple of pooltypes and one of them is automated, since we’re looking for linked clones we also need to make sure the pool source is VIEW_COMPOSER if this says VIRTUAL_CENTER you’re looking at full clones.

$wrongsnaps=$poolmachines | where {$_.managedmachinedata.viewcomposerdata.baseimagesnapshotpath -notlike  $pool.automateddesktopdata.VirtualCenternamesdata.snapshotpath -OR $_.managedmachinedata.viewcomposerdata.baseimagesnapshotpath -notlike $pool.automateddesktopdata.VirtualCenternamesdata.snapshotpath}

I could have shortened this one by defining a couple of variables but this gives an impression of how deep you might have to go to get the required data. WHat I do is check if the snapshot has the same name AND if the selected source VM has the same name if either of the two is different the vm wil be entered on the output.

$wrongsnapdesktops+= New-Object PSObject -Property @{"VM Name" = $wrongsnap.base.name;
								"VM Snapshot" = $wrongsnap.managedmachinedata.viewcomposerdata.baseimagesnapshotpath;
								"VM GI" = $wrongsnap.managedmachinedata.viewcomposerdata.baseimagepath;
								"Pool Snapshot" = $pool.automateddesktopdata.VirtualCenternamesdata.snapshotpath;
								"Pool GI" = $pool.automateddesktopdata.VirtualCenternamesdata.parentvmpath;

Last of the real code is about displaying the actual info for the desktop.

This all results in the following plugin, be aware that this might be a bit slow to run since it needs go go trough all desktops. For my customer it takes about 3 minutes on 1350 desktops.

# Start of Settings
# End of Settings


$wrongsnapdesktops=@()
foreach ($pool in $pools){
$poolname=$pool.base.name
if ($pool.type -like "*automated*" -AND $pool.source -like "*VIEW_COMPOSER*"){

$poolmachines=get-hvmachine ($pool.base.name)
$wrongsnaps=$poolmachines | where {$_.managedmachinedata.viewcomposerdata.baseimagesnapshotpath -notlike  $pool.automateddesktopdata.VirtualCenternamesdata.snapshotpath -OR $_.managedmachinedata.viewcomposerdata.baseimagesnapshotpath -notlike $pool.automateddesktopdata.VirtualCenternamesdata.snapshotpath}
foreach ($wrongsnap in $wrongsnaps){
$wrongsnapdesktops+= New-Object PSObject -Property @{"VM Name" = $wrongsnap.base.name;
								"VM Snapshot" = $wrongsnap.managedmachinedata.viewcomposerdata.baseimagesnapshotpath;
								"VM GI" = $wrongsnap.managedmachinedata.viewcomposerdata.baseimagepath;
								"Pool Snapshot" = $pool.automateddesktopdata.VirtualCenternamesdata.snapshotpath;
								"Pool GI" = $pool.automateddesktopdata.VirtualCenternamesdata.parentvmpath;
}
}
}
}
$wrongsnapdesktops

$Title = "VDI Desktops based on wrong snapshot"
$Header = "VDI Desktops based on wrong snapshot"
$Comments = "These desktops have not been recomposed with the correct Golden Image Snapshot"
$Display = "Table"
$Author = "Wouter Kursten"
$PluginVersion = 0.1
$PluginCategory = "View"

And this is how it looks:

Another script I already made is a simple one to get the status of all full clone pools. Not really fancy but it gets information about what template is used as the base and several counts for the various status of desktops:

# Start of Settings
# End of Settings

$fullpoolstatus=@()
foreach ($pool in $pools){
$poolname=$pool.base.name
if ($pool.type -like "*automated*" -AND $pool.source -like "*VIRTUAL_CENTER*"){
$desktops=get-hvmachinesummary -pool $poolname
$fullpoolstatus+=New-Object PSObject -Property @{"Name" = $Poolname;
								"Template" = $pool.AutomatedDesktopData.VirtualCenterNamesData.TemplatePath;
								"Desktop_Count" = ($desktops).count;
								"Desktops_Unassigned" = ($desktops | where {$_.base.User -eq $null}).count;
								"Available" = ($desktops | where {$_.base.basicstate -eq "AVAILABLE"}).count;
								"Connected" = ($desktops | where {$_.base.basicstate -eq "CONNECTED"}).count;
								"Disconnected" = ($desktops | where {$_.base.basicstate -eq "DISCONNECTED"}).count;
								"Maintenance" = ($desktops | where {$_.base.basicstate -eq "MAINTENANCE"}).count;
								"Provisioning" = ($desktops | where {$_.base.basicstate -eq "PROVISIONING"}).count;
								"Customizing" = ($desktops | where {$_.base.basicstate -eq "CUSTOMIZING"}).count;
								"Already_Used" = ($desktops | where {$_.base.basicstate -eq "ALREADY_USED"}).count;
								"Agent_Unreachable" = ($desktops | where {$_.base.basicstate -eq "AGENT_UNREACHABLE"}).count;
								"Error" = ($desktops | where {$_.base.basicstate -eq "ERROR"}).count;
								"Deleting" = ($desktops | where {$_.base.basicstate -eq "DELETING"}).count;
								"Provisioning_Error" = ($desktops | where {$_.base.basicstate -eq "PROVISIONING_ERROR"}).count;
}
}
}
$fullpoolstatus | select Name,Template,Desktop_Count,Desktops_Unassigned,Available,Connected,Disconnected,Maintenance,Provisioning,Customizing,Already_Used,Agent_Unreachable,Error,Deleting,Provisioning_Error
$Title = "Full Clone Desktop Pool Status"
$Header = "Full Clone Desktop Pool Status"
$Comments = "These are all pools with full clones and their most common counters"
$Display = "Table"
$Author = "Wouter Kursten"
$PluginVersion = 0.1
$PluginCategory = "View"

and again this is how it can look:

Github

After Alan Renouf saw me posting screenshots on Twitter he offered to setup a github project for this. Last week this was done and I have already done my first few commits. Hopefully more people will jump on the bandwagon so we can make this check as awesome as the original is.