5

Horizon View Log Collector

 3 years ago
source link: https://myvirtualcloud.net/horizon-view-log-collector/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Horizon View Log Collector

Whenever administrators need to do troubleshooting in a Horizon View environment it’s always a daunting task to cycle throughout all component logs. In special, it’s always difficult to remember the location of every log file is across the different components. Not anymore!

My rockstar colleague and VMware Architect Markt Ewert created a PowerShell script that automates the collection of log files from Horizon View components when you need, including Connection Servers, Security Gateways, Desktops, View Composer and Transfer Servers. With his permission I am sharing this script here with the broader community since it’s a very useful tool.

View_Log_Collector_v1.0.ps1

[css lang=”plain” autolinks=”false” classname=”myclass” collapse=”false” firstline=”1″ padlinenumbers=”false” gutter=”true” smarttabs=”true” toolbar=”true” language=”true”]
#
# VMware View Log Collector v1.0
# Copyright 2013 VMware. All Rights Reserved.
#
# Collects VMware View 4.x/5.x log files from View servers and virtual desktops.
#
# Developed 2012-2013 by Mark F. Ewert, Architect – Technical Enablement
#

#
# This script has been well tested but is not supported.
# Run the script without any parameters for detailed help
#

# Get parameters passed on the command line
Param(
[string]$Mode = "",
[string]$LogType = "",
[string]$Desktop = "",
[string]$LogRepository = "",
[string]$TargetShare = ""
)

# Set Main variables
$ServerLogTypes = @("debug","log","securitygateway")
$DesktopLogTypes = @("debug","log","pcoip_agent","pcoip_server","persona")
$ComposerLogTypes = @("vmware-viewcomposer.","vmware-viewcomposer-audit")
$TransferServerLogTypes = @("debug","log")
$Modes = @("server","desktop","composer","transferserver")
If ($Modes -notcontains $Mode) {$Mode = "help"} # default to display help
If (($Mode -eq "server") -and ($ServerLogTypes -notcontains $LogType)) {$LogType = "all"} # default to all server log types
If (($Mode -eq "desktop") -and ($DesktopLogTypes -notcontains $LogType)) {$LogType = "all"} # default to all desktop log types
If ($Mode -eq "composer") {$LogType = "all"} # collect all Composer logs by default
If (($Mode -eq "transferserver") -and ($TransferServerLogTypes -notcontains $LogType)) {$LogType = "all"} # default to all transfer server log types
$CollectedCount = 0
$ConnectionServers = @()
$vCenterServers = @()
$TransferServers = @()
$SystemsWithLogs = @()
$LogTypes = @()

# USER CONFIGURABLE VARIABLES
If (!$targetshare) {$TargetShare = "C$"} # default to C$ share
If (!$LogRepository) {$LogRepository = ""} # SET DEFAULT LOG REPOSITORY HERE
#
$2008_Win7_LogLocation = "ProgramData\VMWare\VDM\logs" # 2008\Windows 7 log location
$2003_WinXP_LogLocation = "\Documents and Settings\All Users\Application Data\VMware\VDM\logs" # 2003\Windows XP log location
$2008_Composer_LogLocation = "\Documents and Settings\All Users\Application Data\VMware\View Composer\Logs" # 2008 Composer log location
$2003_Composer_LogLocation = "\ProgramData\VMware\View Composer\Logs" # 2003 Composer log location
#
$TitleColor = "green"
$WarningColor = "yellow"
$AlertColor = "red"

#
# Load VMware View PowerCLI Snapin if not already loaded
#
if (!(get-pssnapin -name VMware.View.Broker -erroraction silentlycontinue)) {
add-pssnapin VMware.View.Broker
}

#
# FUNCTIONS
#

Function TitleScreen () {
# Display Title
Clear-Host
Write-Host
Write-Host "VMware View Log Collector" -foregroundcolor $TitleColor
Write-Host
write-host "Mode: " -nonewline; write-host ""$Mode -nonewline -foregroundcolor $WarningColor; write-host " Log type to collect:" -nonewline; write-host ""$LogType -foregroundcolor $WarningColor
write-host
}

Function Wait4KeyPress () {
# Pause for key press
Write-Host
Write-Host "Press any key to continue …" -nonewline -foregroundcolor $WarningColor
$KeyPress = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
Clear-Host
write-host
}

Function ShowHelp () {
Clear-Host
Write-Host
Write-Host "VMware View Server Log Collector Help" -foregroundcolor $TitleColor
Write-Host "————————————-" -foregroundcolor $TitleColor
Write-Host "This script collects VMware View virtual desktop infrastructure log files,"
Write-Host "centralizing them on a CIFS file share. To simplify log analysis, the name"
Write-Host "of the system the logs were copied from is appended to the filename."
Write-Host
Write-Host "The collector copies the latest, non-zero length log file. If the most recent"
Write-Host "two log files of a specific type are both zero length, none are copied."
Write-Host
Write-Host
Write-Host "Program Modes" -foregroundcolor $TitleColor
Write-Host "————-" -foregroundcolor $TitleColor
Write-Host "Logs can be collected from View Connection\Security Servers, Virtual Desktops,"
Write-Host "Composer Servers and Transfer Servers. The type of system to collect logs from"
Write-Host "is specified using the " -nonewline; write-host "-mode" -nonewline -foregroundcolor $WarningColor; write-host " parameter. The following modes are supported:"
Write-Host
Write-host "server" -foregroundcolor $WarningColor
Write-host "desktop" -foregroundcolor $WarningColor
Write-host "composer" -foregroundcolor $WarningColor
Write-host "transferserver" -foregroundcolor $WarningColor
Write-Host
Write-Host "If no mode is selected, this help information is dislayed."
Wait4KeyPress
Write-Host "Server, composer and transferserver modes automatically identify the servers to"
Write-Host "collect logs from by querying View (server,composer) or vSphere (transferserver)"
Write-Host "Desktop mode requires specification of a desktop. This can be done on the"
Write-Host "command line using the " -nonewline; Write-Host "-desktop" -nonewline -foregroundcolor $WarningColor; Write-Host " parameter. If none is specified the"
Write-Host "script will prompt for it."
Write-Host
Write-Host
Write-Host "Log Types" -foregroundcolor $TitleColor
Write-Host "———" -foregroundcolor $TitleColor
Write-Host "Each mode supports different log types that can be collected as detailed below."
Write-Host
Write-Host "Server" -nonewline -foregroundcolor $WarningColor; Write-Host " log types: debug, log, securitygateway"
Write-Host "Desktop" -nonewline -foregroundcolor $WarningColor; Write-Host " log types: debug, log, pcoip_agent, pcoip_server"
Write-Host "Composer" -nonewline -foregroundcolor $WarningColor; Write-Host " log types: all (collects the two Composer logs)"
Write-Host "TransferServer" -nonewline -foregroundcolor $WarningColor; Write-Host " log types: debug, log"
Write-Host
Write-Host "Log type: "-nonewline; Write-Host "all" -nonewline -foregroundcolor $WarningColor; Write-Host " can also be specified to collect all types of logs from the"
Write-Host "target system(s). If no log type is specified or is specified incorrectly,"
Write-Host "the script defaults to: " -nonewline; Write-Host "all" -foregroundcolor $WarningColor
Write-Host
Wait4KeyPress
Write-Host "Log Repository" -foregroundcolor $TitleColor
Write-Host "————–" -foregroundcolor $TitleColor
Write-Host "The script needs to be configured with a Log Repository to store the collected"
Write-Host "logs. Any CIFS-based file share is supported. The user account running the "
Write-Host "script must have the Windows NTFS equivalent of " -nonewline; Write-Host "Modify" -nonewline -foregroundcolor $WarningColor; Write-Host " rights."
Write-Host
Write-Host "The log repository can be specified on the command line using the"
Write-Host "parameter: " -nonewline; Write-Host "-LogRepository" -nonewline -foregroundcolor $WarningColor; Write-Host ". The repository can also be set"
Write-Host "within the USER CONFIGURABLE VARIABLES section near the top of the script to"
Write-Host "prevent having to specify one each time the script is run. Be sure to enclose"
Write-Host "the repository in quotations if there are any spaces in the path."
Write-Host
Write-Host
Write-Host "Target Share and Security" -foregroundcolor $TitleColor
Write-Host "————————-" -foregroundcolor $TitleColor
Write-Host "By default the script connects to each target system using the " -nonewline; Write-Host "C$" -nonewline -foregroundcolor $WarningColor; Write-Host " share and"
Write-Host "requires the user account running the script to be able to connect to this path."
Write-Host "A different share can be specified using the " -nonewline; Write-Host "-targetshare" -nonewline -foregroundcolor $WarningColor; Write-Host " parameter."
Write-Host
Wait4KeyPress
Write-Host "Log Locations" -foregroundcolor $TitleColor
Write-Host "————-" -foregroundcolor $TitleColor
Write-Host "The script collects logs from the standard VMware View log locations as"
Write-Host "detailed in: " -nonewline; Write-Host "KB 1027744" -nonewline -foregroundcolor $WarningColor; Write-Host " by default. These locations can be changed using"
Write-Host "the respective variables also located within the USER CONFIGURABLE VARIABLES"
Write-Host "section near the top of the script."
Write-Host
Write-Host
Write-Host "Examples" -foregroundcolor $WarningColor
Write-Host "——–" -foregroundcolor $WarningColor
Write-Host "logcollector.ps1 -mode desktop -desktop HRDSKTOP112 -logtype pcoip_server"
Write-Host "-logrepository \\nashost.domain.local\viewlogs"
Write-Host
Write-Host "logcollector.ps1 -mode server -logtype debug -logrepository"
Write-Host "\\fileserver.domain.local\log_repository"
Write-Host
Write-Host "logcollector.ps1 -mode server -logtype all -targetshare log_share"
Write-Host "-logrepository \\fileserver.domain.local\logs"
Write-Host
Write-Host "logcollector.ps1 -mode composer"
Write-Host
Wait4KeyPress
Write-Host "Powershell Requirements" -foregroundcolor $TitleColor
Write-Host "———————–" -foregroundcolor $TitleColor
Write-Host "All collection modes require the VMware View PowerCLI which is"
Write-Host "installed on each Connection Server by default. This script must"
Write-Host "be run on a Connection Server using an account that has Administrative"
Write-Host "rights to both the Connection Server and the View Infrastructure. When"
Write-Host "launching the script or opening a Powershell session to run the script"
Write-Host "be sure to launch it as an Administrator " -nonewline; write-host "(Run as Administrator)" -foregroundcolor $WarningColor
Write-Host
Write-Host "Transferserver mode also requires the account running the script to"
Write-Host "have rights to connect to the vSphere vCenter Servers supporting the"
Write-Host "View Infrastructure and read the Notes associated with each Virtual Machine."
Write-Host "This is required in order to identify the deployed Transfer Servers."
Write-Host "Make sure the vSphere PowerCLI supporting the version of vSphere deployed"
Write-Host "has been installed on the Connection Server where this script will"
Write-Host "be executed."
Write-Host
Write-Host
Write-Host
Write-Host "Script developed by: Mark F. Ewert, Architect – Technical Enablement, VMware" -foregroundcolor $WarningColor
Write-Host "Script copyright VMware 2013 – All Rights Reserved" -foregroundcolor $WarningColor
Write-Host
exit
}

Function LogCollector ($SystemsWithLogs,$Mode,$LogType) {
ForEach ($System in $SystemsWithLogs) {
# First check if system is running Windows 2003 or 2008
If ($Mode -ne "composer") {
$LogLocation = $2008_Win7_LogLocation
$FullLogPath = "\\"+$System+"\"+$TargetShare+"\"+$LogLocation+"\"
# Assume 2008 but check to see if it’s actually 2003
If (!(Test-Path -path $FullLogPath)) { # if 2008 log directory doesn’t exist, it’s 2003
$LogLocation = $2003_WinXP_LogLocation
$FullLogPath = "\\"+$System+"\"+$TargetShare+"\"+$LogLocation+"\"
}
}
Else { # must be composer mode
$LogLocation = $2008_Composer_LogLocation
$FullLogPath = "\\"+$System+"\"+$TargetShare+"\"+$LogLocation+"\"
# Assume 2008 but check to see if it’s actually 2003
If (!(Test-Path -path $FullLogPath)) { # if 2008 log directory doesn’t exist, it’s 2003
$LogLocation = $2003_Composer_LogLocation
$FullLogPath = "\\"+$System+"\"+$TargetShare+"\"+$LogLocation+"\"
}
}
# finish creating path and filename for log to collect
If ($LogType -ne "securitygateway") {
$Log2Fetch = $FullLogPath+""+$LogType+"*"
}
Else {
$Log2Fetch = $FullLogPath+"PCoIP Secure Gateway\"+$LogType+"*"
}
# Fetch details for last two logs
$LogFiles = @()
$LogFiles = @(gci $Log2Fetch -ea SilentlyContinue | sort LastWriteTime | select -last 2)
If ($LogFiles) {
# Check for zero size logs handling situation where only one file was returned
If (!$LogFiles[1]) {
$LogFiles += $LogFiles[0]
}
$Size = Get-Item $LogFiles[1]
If ($Size.length -ne 0) {
[string]$LogFileAndPath = $LogFiles[1]
}
Else {
$Size = Get-Item $LogFiles[0]
If ($Size.length -ne 0) {
[string]$LogFileAndPath = $LogFiles[0]
}
Else {
Write-Host
# turn persona log type back into human understandable
If ($LogType -eq "vmvvp") {$LogType = "persona"}
Write-Host "Warning: " -nonewline -foregroundcolor $WarningColor; Write-Host "The two latest $LogType logs for $System are 0 bytes and will not be collected"
$LogFileAndPath = $null
}
}
}
Else {
Write-Host
# turn persona log type back into human understandable
If ($LogType -eq "vmvvp") {$LogType = "persona"}
Write-Host "Warning: " -nonewline -foregroundcolor $WarningColor; Write-host "No $LogType log was found on"$System
$LogFileAndPath = $null
}

# If there’s a recent non zero sized log file, collect it
If ($LogFileAndPath) {
[string]$LogFileName = $LogFileAndPath.SubString($FullLogPath.length)
$LogFileExtension = [System.IO.Path]::GetExtension($LogFileName)
$NewLogFileName = ""+$LogRepository+"\"+$LogFileName.TrimEnd($LogFileExtension)+"_-_"+$System+$LogFileExtension
Copy-Item -Path $LogFileAndPath -Destination $NewLogFileName
write-host
write-host "Success: " -nonewline -foregroundcolor $TitleColor; write-host "$LogType log collected from"$System
# Increase count of collected logs
$CollectedCount++
}
}
Return $CollectedCount
}

#
# Main Program
#

# Check to see if HELP was requested
If ($Mode -eq "help") {
ShowHelp
}

# Verify a Log Repository was specified

If (!$LogRepository) {
Clear-Host
Write-Host "A LOG RESPOSITORY WAS NOT SPECIFIED ON THE COMMAND LINE" -foregroundcolor $AlertColor
Write-Host "OR WITHIN THE USER CONFIGURBLE VARIABLES SECTION" -foregroundcolor $AlertColor
Write-Host
Write-Host "Please specify a repository the next time the script is"
Write-Host "executed or configure a default respository using the"
Write-Host "LogRepository variable in the USER CONFIGURABLE VARIABLES"
Write-Host "section near the top of the script."
Write-Host
exit
}

# Verify the Log Repository exists
If (!(Test-Path -path $LogRepository)) {
Clear-Host
Write-Host "LOG REPOSITORY DOES NOT EXIST OR CANNOT BE CONTACTED" -foregroundcolor $AlertColor
Write-Host
Write-Host "Please verify log repository settings before re-running the script."
Write-Host
exit
}

# Display Title Screen
TitleScreen

# Server Mode
If ($Mode -eq "server") {
# create PCoIP log repository sub-directory if it doesn’t already exist.
$SecureGatewayLogPath = $LogRepository + "\PCoIP Secure Gateway\"
If (!(Test-Path -path $SecureGatewayLogPath)) {New-Item $SecureGatewayLogPath -Type Directory}
# Get Connection Servers from View
$ConnectionServers = Get-ConnectionBroker
ForEach ($ConnectionServer in $ConnectionServers) {
$SystemsWithLogs += $ConnectionServer.broker_id
}
# set LogTypes to server log types
$LogTypes = $ServerLogTypes
Write-Host "View Servers: " -nonewline; write-host ""$SystemsWithLogs -foregroundcolor $WarningColor
}

# Desktop Mode
If ($Mode -eq "desktop") {
# Prompt for name of desktop if one was not entered on the command line
If ($Desktop) {
Write-Host "Desktop: " -nonewline; write-host ""$Desktop -nonewline -foregroundcolor $WarningColor
Write-Host
}
While (!$Desktop) {
Write-Host "Enter Name of Desktop containing logs: " -nonewline -foregroundcolor $WarningColor; $Desktop = Read-Host
}
$SystemsWithLogs = $Desktop
# set LogTypes to desktop log types
$LogTypes = $DesktopLogTypes
}

# Composer Mode
If ($Mode -eq "composer") {
# Get the name of the View Composer server from View
$VC = Get-ViewVC
$ComposerURL = $VC.composerUrl
$Composer = $ComposerURL.TrimStart("https://")
$Composer = $Composer.SubString(0,($Composer.LastIndexOf(‘:’)+1))
$Composer = $Composer.Trim(":")
$SystemsWithLogs = $Composer
# set LogTypes to composer log types
$LogTypes = $ComposerLogTypes
Write-Host "View Composer IP Address: " -nonewline; write-host ""$SystemsWithLogs -foregroundcolor $WarningColor
}

# Transfer Server Mode
If ($Mode -eq "transferserver") {
# Load VMware vSphere PowerCLI Snapin if not already loaded
If (!(get-pssnapin -name VMware.VimAutomation.Core -erroraction silentlycontinue)) {
add-pssnapin VMware.VimAutomation.Core
}
Write-Host "Scanning vCenter(s) for Transfer Servers… Please Wait…" -foregroundcolor $WarningColor
# Get vCenter Server(s) from View
@($ViewVCs = Get-ViewVC)
ForEach ($ViewVC in $ViewVCs) {
$vCenterServers += $ViewVC.serverName
}
# Now get Transfer Servers from vCenter
ForEach ($vCenterServer in $vCenterServers) {
connect-viserver $vCenterServer -ea SilentlyContinue | Out-Null
@($VMs = Get-VM)
ForEach ($VM in $VMs) {
$Annotations = Get-Annotation -CustomAttribute "Transfer Server Status" $VM
If ($Annotations.Value) {
$SystemsWithLogs += $VM
}
}
}
# set LogTypes to transfer server log types
$LogTypes = $TransferServerLogTypes
# Display Title Screen
TitleScreen
Write-Host "Transfer Servers: " -nonewline; write-host ""$SystemsWithLogs -foregroundcolor $WarningColor
}

# Collect Logs
write-host
write-host "—————————————————-" -foregroundcolor $WarningColor
$LogCollectionAttempts = 0
If ($LogType -eq "all") {
ForEach ($Log in $LogTypes) {
$LogType = $Log
# check for persona logtype and replace human understandable with actual
If ($LogType -eq "persona") {$LogType = "vmvvp"}
If (!$SystemsWithLogs.count) {$LogCollectionAttempts++}
Else {$LogCollectionAttempts += $SystemsWithLogs.count}
$Count += LogCollector $SystemsWithLogs $Mode $LogType
}
$CollectedCount += $Count
}
Else {
# check for persona logtype and replace human understandable with actual
If ($LogType -eq "persona") {$LogType = "vmvvp"}
$LogCollectionAttempts = $SystemsWithLogs.count
$CollectedCount = LogCollector $SystemsWithLogs $Mode $LogType
}
write-host
write-host "—————————————————-" -foregroundcolor $WarningColor
write-host
write-host

If ($CollectedCount) {
write-host "Total number of logs collected:" -nonewline; write-host ""$CollectedCount -foregroundcolor $WarningColor
write-host "Total number of log collection attempts:" -nonewline; write-host ""$LogCollectionAttempts -foregroundcolor $WarningColor
If ($LogCollectionAttempts -ne $CollectedCount) {
If (($LogCollectionAttempts – $CollectedCount) -eq 1) {
write-host
write-host "1" -nonewline -foregroundcolor $WarningColor; write-host " log was not collected"
}
Else {
write-host
write-host ($LogCollectionAttempts – $CollectedCount)"" -nonewline -foregroundcolor $WarningColor; write-host "logs were not collected"
}
}
write-host
}
Else {
write-host "ALERT:" -nonewline -foregroundcolor $AlertColor; write-host " NO LOGS WERE COLLECTED."
write-host "Total number of log collection attempts:" -nonewline; write-host ""$LogCollectionAttempts -foregroundcolor $WarningColor
write-host
}
write-host
write-host
[/css]

This article was first published by Andre Leibovici (@andreleibovici) at myvirtualcloud.net.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK