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.

Pulling Horizon View events with PowerCLI in a nicer way

Update: There is a new way to pull the event information without having to enter the sql password please see this post about it.

 

So in one of the first posts I did about Powercli 6.5 was a bit about pulling events from the Horizon View events database. This off course was not the crude way to pull the events. Another was was using the event dumper fling but that one is a bit to slow for my taste. I decided to create a script that leveraged and had the speed of PowerCli but actually gave some options and that dumped the results in a .csv file since reading them from the command line will be too much at some point.

What I ended up with is a 71 line script where 18 are informational, 8 blanks, 1 that pulls the information and the rest for the menus and error handling. I decided on not giving any real errors when things don’t work but just red text. A lot is done with try <> catch and a if elseif else.

There is no need to load any modules but the scripts assumes at least PowerCLI 6.5 with the vmware.hv.helper module loaded.

I have created a github repo for these smaller scripts over here.

#-------------------------------------------------
# Get the Horizon view event for the last x time and export to a csv
#
# Requires PowerCLI 6.5 or higher
# Requires vmware.hv.helper module
# Module can be found at https://github.com/vmware/PowerCLI-Example-Scripts
#
# Version 1.0
# 16-06-2017
# Created by: Wouter Kursten
#
#-------------------------------------------------

# Load the required VMware modules (for PowerShell only)

Write-Host "Loading VMware PowerCLI Modules" -ForegroundColor Green
try	{
	get-module -listavailable vm* | import-module -erroraction stop
	}
catch	{
	write-host "No Powercli 6.5 or higher found" -ForegroundColor Red
		}
$version=get-powercliversion -WarningAction silentlyContinue
if ($version.build -lt 4624819)	{
	write-host "Horizon View api's require Powercli 6.5 or higher to function, please upgrade PowerCLI" -ForegroundColor Red
	exit
	}
elseif (get-module vmware.hv.helper  ) {
	write-host "VMware.hv.helper found"
	}
else {
	write-host "Please download and install the VMware.hv.helper module from https://github.com/vmware/PowerCLI-Example-Scripts" -ForegroundColor Red
	exit
	}

#Ask for connection information

$hvservername=Read-host "Welke Connection broker?"
$domain=read-host "Please enter your active directory domain?"
$username=Read-host "Please enter your useraccount"
$password=Read-host -assecurestring "Please enter your password"

#Connect to View Connection broker
write-host "Connecting to the connection broker" -ForegroundColor Green
try {
$hvserver=connect-hvserver $hvservername -domain $domain -username $username -password $password -WarningAction silentlyContinue -erroraction stop
}
catch {
	Write-host "Can't connect to the Connection server please check the credentials." -ForegroundColor Red
	exit
	}

#connect to the Event Database

$dbpassword=Read-host -assecurestring "Please enter the password of the account configured in Horizon View to access the event database."
write-host "Connecting to the database" -ForegroundColor Green
try {
	$eventdb=connect-hvevent -dbpassword $dbpassword -erroraction stop
	}
catch {
	Write-host "Can't connect to the Database server please check the password." -ForegroundColor Red
	exit
	}

#Retreive information

write-host "Please provide the following information use % as wildcard." -ForegroundColor Green
$searchuser=Read-Host "Please enter the accountname you need information on?"
$module=Read-Host "What module do you want the logs for? (Agent,Broker,Client,Tunnel,Framework,Client)"
$sevfilter=Read-Host "What is the severity level you need information on?(Audit_fail, Audit_Success,Info,Warning,Error)"
$message=Read-host "Looking for any specific text in the message?"
$maxage=Read-Host "How far do you want to look back in event history? (Day,week,month,all)"
$filelocation=Read-host "Please provide filename and location for the exported csv file"

#Export to file

$lastevent=get-hvevent -hvdbserver $eventdb -timeperiod $maxage -SeverityFilter $sevfilter -userfilter $searchuser -modulefilter $module -messagefilter $message

try {
	$lastevent.events  | export-csv $filelocation -erroraction stop
	}
catch{
	write-host "Unable to create the file, please check name and location" -ForegroundColor Red
	exit
	}
Write-host "Events have been successfully exported." -ForegroundColor Green

And how does this look in the end??

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.

Updated flings for Horizon View

The last couple of weeks some of the flings applicable for Horizon View and that I had in my VMUG presentation have been updated. The Horizon Toolbox 2 has been updated so it now supports console access for vCenter 6.0u2 and 6.5 + it now supports horizon 7.1. The Horizon OS Optimization Tool got several bugfixes.

Recent change for the Horizon Toolbox 2:

2017-Mar-17 Horizon Toolbox 2.1.3

New Features

  • Support new Horizon version(7.1)
  • Support new VCenter version(VC6.5 and 6.0u2a) in Console Access feature

 

Recent changelog for the OSOT:

April 27, 2017 b1090b

  • Issue Fix: “the node to be removed is not a child of this node” when opitimize windows 10 template
  • Issue Fix: System.NullReferenceException occurs if the network can’t reach any of the public template repository.
  • Template Update (Windows 7/8/8.1): Correct the Menu Show Delay type to REG_SZ in item “Reduce Menu Show Delay”

April 18, 2017

Issue fixed

    • Some optimization items are skipped mistakenly. For example, Remote Apps in Windows 10 template. This is caused by a recent change in Conditional Check feature.

April 17, 2017 b1088

Feature

      • Conditional Check: you can specify on what condition an optimization should be run. For example, when a specific registry key match certain value.

Template

      • “Change Explorer Default View” has been changed to unselected by default, because of conflict to UEM. Details: it causes the locations in “user files” (desktop, downloads, favorites, music, videos , Documents, Pictures) folder is to the local drive c:\Users\Username, its Should be \\server\folder_redirection\%username% when use UEM folder redirection.

Enhancements

      • Public Templates tab: click template on the list is very slow, which should not be
      • Default public template repository URL updated
      • Loading public template repository takes too long

Issue Fix

    • Field validation: prevent user from creating template with blank name

Using PowerCLI to get Horizon view status & events

Update: There is a new way to pull the event information without having to enter the sql password please see this post about it.

So two weeks ago I had a nice little post about talking to Horizon View using PowerCLI. I also promised to be digging a bit more into PowerCLI by grabbing the script posted on the VMware blog and editing it a little to my taste. It’s a very useful script they have on there but still I prefer to know what might have caused the issues. I decided I needed to know who the last user was that used the desktop and the last entry into the eventlog and the time of that log. So actually most code used talks to the eventlog database, something already available pre PowerCLI 6.5 but what I hardly ever used.

The basics for connecting I won’t post but we do need an extra connection and that is to the event database:

$eventdb=connect-hvevent -dbpassword $hvedbpassword

As with the Horizon View connection it’s best to put this into a variable so it can be used later on. The $hvedbpassword should be the password for the user that View uses to connect to the database server in plain text! Earlier in the script I read the password from hashed contents in a text file.The request has been dropped to be able to pass encrypted credentials and/or creta a credentialstore for this.

Next up is grabbing the events for a certain Desktop

$lastevent=get-hvevent -hvdbserver $eventdb -timeperiod 'day' -messagefilter $problemvm.base.name

This could use some rework since I would prefer the time period to be a variable based on the current date but if the event is older then a day it will be hard to find anything on it anyway.

if ($lastevent.events){
$lasteventtime=$lastevent.events | select -expandproperty eventtime -first 1
$lasteventmessage=$lastevent.events | select -expandproperty message -first 1 
$lasteventusername=$lastevent.events | select -expandproperty Username -first 1 
}

This grabs the latest event, the time it happened and the user it happened to. This can be anything including a logoff. It might be able to help you why a lot of desktops are ending up in a rotten state.

The rest of the script is basic building of arrays, filling them, mailing it etc etc. So still not a lot of complicated code that some people build but it’s a bit of the basics in talking to the View Api and the event database.

This is the output you will get (this is from an html file and heavily edited to anonimize it)

The complete script, please do use and abuse it to your own taste as I have done with the original:

#########################################################################################
#																						#
# Get List of Desktops that are not available or connected		 						#
# This is based on the script posted here:												#
# https://blogs.vmware.com/euc/2017/01/vmware-horizon-7-powercli-6-5.html				#
# Required:																				#
# Powercli 6.5 Release 1																#
# The VMware.Hv.Helper Module from https://github.com/vmware/PowerCLI-Example-Scripts	#
#																						#
#########################################################################################

#region variables
#########################################################################################
#								Variables												#
#	Password files need to be filled firs using:										#
#	Read-Host -AsSecureString | ConvertFrom-SecureString | Out-File 'filename.txt'		#
#	Enter password and press enter														#
#	vCenter things have been marked out but I left them in here 						#
#	because they might be usefull for when someone else uses this script				#
#########################################################################################
$cs = "connectionbroker"														# Horizon Connection Server
$hvcsUser= "Service_Account"													# User account to connect to Connection Server
$hvcsPassword = get-content .\hvcs_Credentials.txt | convertto-securestring		# Password for user to connect to Connection Server
$csDomain = "domain"															# Domain for user to connect to Connection Server
$hvedbpassword=get-content .\hvedb_Credentials.txt | convertto-securestring   	# password to access event database
$mailto="user@domain.com"														# Address to send the status mail to
$mailfrom="connectionbroker@domain.com"											# Address to send the mail from
$mailsubject="Overview bad VDI desktops"										# Mail subject
$smtpserver="mailserver.domain.com"												# Mail server			
#$vcuser="vcuser"																# User account to access the vCenter server
#$vcpassword=get-content .\vCenter_Credentials.txt | convertto-securestring		# password to access the vCenter server
#vc = "Enter vCenter name"														# vCenter Server



$baseStates = @('PROVISIONING_ERROR',
                'ERROR',
                'MAINTENANCE',
                'DISCONNECTED',
                'AGENT_UNREACHABLE',
                'AGENT_ERR_STARTUP_IN_PROGRESS',
                'AGENT_ERR_DISABLED',
                'AGENT_ERR_INVALID_IP',
                'AGENT_ERR_NEED_REBOOT',
                'AGENT_ERR_PROTOCOL_FAILURE',
                'AGENT_ERR_DOMAIN_FAILURE',
                'AGENT_CONFIG_ERROR',
                'UNKNOWN')
				

#endregion variables

#region initialize
###################################################################
#                    Initialize                                  #
###################################################################
# --- Import the PowerCLI Modules required ---
Import-Module VMware.VimAutomation.HorizonView
Import-Module VMware.VimAutomation.Core

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

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

# --- Connect to the vCenter Server ---
#Connect-VIServer -Server $vc -User $vcUser -Password $vcPassword

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

#endregion initialize

#region html
###################################################################
#                    HTML                                         #
###################################################################

$style = "<style>BODY{font-family: Arial; font-size: 10pt;}"
$style = $style + "TABLE{border: 1px solid black; border-collapse: collapse;}"
$style = $style + "TH{border: 1px solid black; background: #dddddd; padding: 5px; }"
$style = $style + "TD{border: 1px solid black; padding: 5px; }"
$style = $style + "</style>"

#endregion

#region main
###################################################################
#                    Main                                        #
###################################################################
$Problemarray=@()
#Write-Output ""
if ($Services1) 
	{
     foreach ($baseState in $baseStates) 
		{
           # --- Get a list of VMs in this state ---
           $ProblemVMs = Get-HVMachineSummary -State $baseState

           foreach ($ProblemVM in $ProblemVMs) 
		   {
		   			$lastevent=get-hvevent -hvdbserver $eventdb -timeperiod 'day' -messagefilter $problemvm.base.name
			
				if ($lastevent.events){
					$lasteventtime=$lastevent.events | select -expandproperty eventtime -first 1
					$lasteventmessage=$lastevent.events | select -expandproperty message -first 1 
					$lasteventusername=$lastevent.events | select -expandproperty Username -first 1 
					}
				else{
				$lasteventtime="Last event is longer then 1 day ago"
				$lasteventmessage="Not Available"
				}
			$lastmaintenancedate=(Get-HVMachine -machinename $problemvm.base.name)
		   	$item = New-Object PSObject
			$item | Add-Member -type NoteProperty -Name Name -Value $problemvm.base.name 
			$item | Add-Member -type NoteProperty -Name State -Value $problemvm.base.basicstate 
			$item | Add-Member -type NoteProperty -Name Pool -Value $problemvm.namesdata.desktopname
			$item | Add-Member -type NoteProperty -Name Last_event_time -Value $lasteventtime
			$item | Add-Member -type NoteProperty -Name Last_event_user -Value $lasteventusername
			$item | Add-Member -type NoteProperty -Name Last_event_message -Value $lasteventmessage
			$Problemarray+= $item
           }
		}
	
		if ($problemarray)	
			{
			$mailbody=$Problemarray | sort state,name | convertto-html -head $style -property  name,state,Pool,Last_event_time,Last_event_user,Last_event_message | out-string
			send-mailmessage -smtpserver $smtpserver -to $mailto -from $mailfrom -subject $mailsubject -body $mailbody -bodyashtml 
			}
		else
			{
			send-mailmessage -smtpserver $smtpserver -to $mailto -from $mailfrom -subject $mailsubject -body "No problems found in the Horizon View Environment" 
			}

     Write-Output "Disconnect from Connection Server."
     Disconnect-HVServer -Server $cs -confirm:$false
		} 

else 
	{
     Write-Output "Failed to login in to Connection Server."
     
     }
# --- Disconnect from the vCenter Server ---
#Write-Output "Disconnect from vCenter Server."
#Disconnect-VIServer -Server $vc
#endregion main

 

 

Talking PowerCLI against Horizon view (basics)

You know that VMware product that really lacked on the PowerCLI front called Horizon View? Well from PowerCLI 6.5 R1 it finally (try to imagine saying this like The Rock : Finally Powercli has come to Horizon View!) has its own module that you can use to talk to Horizon View and the View API’s.

Offcourse i am not the first to write about it and lots can already be found at the above link to the VMware blog by Graeme Gordon but I did want to share a couple of easy commands with you. I will not bore you with how to set it up because that’s already perfectly explained in Graeme’s post.

First we need to connect, looks like the connect-viserver right?:

connect-hvserver SERVERNAME

you will get a popup box for credentials, I haven’t found an option yet to do something like new-vicredentialstoreitem yet but you can use a hashed password in a text file.

Now for example to retrieve all disconnected desktops

Get-HVMachineSummary -State DISCONNECTED

This can be changed to whatever states are available for desktops.

One of the things Horizon View always lacked was proper reporting for desktop counts i.e. how many desktops are in what state. Lots of people had to use things like scripts that counted them from the adam database (sloooooow) or used tools like the VMware Horizon toolbox 2. To get a count is now really easy with powercli, just repeat the above command and do a count on it.

(Get-HVMachineSummary -State DISCONNECTED).count

For me this was a matter of a second with over 900 desktops available.

Want some information about a single desktop?

get-hvmachinesummary -machinename "machinename" | fl

In short you can find anything you want with the command or by using the View API’s. Since I am not an APi expert myself I would recommend heading over to the API browser and see what you want to use.  In my next post I will dig into the command a bit more by grabbing the script from the VMware blog post and editing it more to my taste.

Can you smellllllll what The Rock is cooking?

New VMware fling: View Client Resizer

I must have missed i during the holiday season but VMware has released a new fling: the View Client Resizer. It’s a simple fling that let’s you easily select any resolution you want to check your VMware Horizon View environment on to see how it behaves. The steps below I have done on a 2-screen setup.

  1. First you go to https://labs.vmware.com/flings/view-client-resizer and download the zip file
  2. Next unpack the zip file
  3. Start the executable
  4. Start the Horizon View client and open a VDI session
  5. Push refresh in the tool and it wil show the active sessions in the pulldown menu
  6.  
  7. Click resize and the session wil go to the top left corner of the Primary monitor in that resolution.

You can pick any of the default resolutions or make one up (smartphone resolutions for example ) as long as the x is between the digits with a minimum right now it seems of 800*600