Horizon View – letztes Verbindungsdatum ermitteln
Horizon View bietet keine eingebaute Möglichkeit das letzte Datum einer Verbindung auf eine bestimmte Maschine zu ermitteln. Das ist aber in einigen Fällen notwendig, zum Beispiel wenn man dedizierte Desktops betreibt und die Kosten möglichst effizient halten möchte. Die Kosten kann man senken indem man inaktive Desktops findet. Orientiert sich die Anzahl der provisionierten Desktops an der Anzahl der tatsächlichen Nutzer, spart man sich unnötige Hardwareeinkäufe.
Zwar bietet VMware mit dem Produkt vRealize Operations Manager (vROPs) eine Möglichkeit solche inaktiven Desktops aufzuspüren, Kunden ohne die passende Lizenz. Sollen die Daten aber automatisiert weiter verarbeitet werden, eignet sich auch vROPs nicht unbedingt dafür.
Vor einiger Zeit schrieb ich ein Powershell-Script welches sich auf die Eventdatenbank von Horizon View stützt und dort die Daten ausliest. Die Daten werden dann in einem maschinenlesbaren Format gespeichert oder können auch an ein Fremdsystem weitergeleitet werden.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
#Name of the DSN for the database connection to the event database $dsn = "HorizonViewEvents" #username for the specified DSN $dbUser = "EventUser" #password for the specified user $dbPassword = "secret" #timeout of sql Connection, adjust if neccessary $ConnectionTimeout = 30 #timeout of SQLQuery, adjust if neccessary $QueryTimeout = 120 <# DO NOT EDIT BELOW THIS LINE #> #Define read query $Query = "SELECT a.ModuleAndEventText,a.Time,EventType FROM event_historical a INNER JOIN (SELECT ModuleAndEventText, MAX(Time) as Time FROM event_historical GROUP BY ModuleAndEventText ) AS b ON a.ModuleAndEventText = b.ModuleAndEventText AND a.Time = b.Time WHERE EventType = 'Agent_CONNECTED' OR EventType = 'AGENT_RECONNECTED'" #cache desktops for future use $assignedDesktops = @{} Get-DesktopVM | Where { $_.isInPool -eq $true -and $_.user_sid -like "S*" } | ForEach { $assignedDesktops.add($_.Name, $_) } $conn = new-object System.Data.Odbc.OdbcConnectio $conn.connectionstring = "DSN=$dsn;Uid=$dbUser;Pwd=$dbPassword" $conn.Open() $cmd = New-object System.Data.Odbc.OdbcCommand($Query,$conn) $cmd.CommandTimeout=$QueryTimeout $ds=New-Object system.Data.DataSet $da=New-Object System.Data.Odbc.OdbcDataAdapter($cmd) [void]$da.fill($ds) $conn.Close() $rawData = New-Object System.Collections.ArrayList $ds.Tables.Rows | ForEach { $time1 = $_.Time $obj = New-Object System.Object $string = $_.ModuleAndEventText $eventType = $_.EventType $time=[datetime]::ParseExact($time1, "MM/dd/yyyy HH:mm:ss", $null) if($eventType -eq "Agent_CONNECTED") { $split = $string -split " has logged in to a new session on machine " } else { $split = $string -split " has reconnected to machine " } $machine = $split[1] $obj | Add-Member -type NoteProperty -name Machine -value $machine $obj | Add-Member -type NoteProperty -name Time -value (Get-Date -Date $time -Format "dd.MM.yyyy HH:mm:ss") $rawData.add($obj) } $parsedData = @{} #determine last available connection date $rawData | ForEach { $machineName = $_.machine $date = [datetime]::ParseExact($_.Time, "dd.MM.yyyy HH:mm:ss", $null) if($parsedData.containsKey($machineName)) { $date2 = [datetime]::ParseExact($parsedData.get_Item($machineName), "dd.MM.yyyy HH:mm:ss", $null) if($date2 -gt $date) { $date = $date2 } $parsedData.set_Item($machineName, (Get-Date -Date $date -Format "dd.MM.yyy HH:mm:ss")) } else { $parsedData.add($machineName, (Get-Date -Date $date -Format "dd.MM.yyy HH:mm:ss")) } } $temp = @("machine;date") $parsedData.keys |%{ $temp += (@($_) + $parsedData.$_) -join ";" } $objectArray = ConvertFrom-CSV -Delimiter ";" $temp $objs = @(); $objectArray | ForEach { $machine = $_.machine $date = [datetime]::ParseExact($_.date, "dd.MM.yyyy HH:mm:ss", $null) #Get desktop from previous cache if($assignedDesktops.ContainsKey($machine)) { $desktop = $assignedDesktops.Get_Item($machine) $obj = New-Object System.Object $tempUserName = $desktop.user_displayname $tempUserNameSplit = $tempUserName.Split("\") $userName = $tempUserNameSplit[1] $obj | Add-Member -type NoteProperty -name "hostedmachinename" -value $machine $obj | Add-Member -type NoteProperty -name "associatedusernames" -value $userName $obj | Add-Member -type NoteProperty -name "lastconnectionday" -value $date $objs += $obj } } $objs | Export-Csv "$PSScriptRoot\lastConnectionDate.csv" -Encoding utf8 -noTypeInformation -Delimiter ";" |
Das Script erstellt eine CSV-Datei im Scriptroot. In dieser steht der Maschinenname, der zugeordnete Benutzername und das letzte Datum einer Verbindung. Die CSV-Datei lässt sich beliebig weiterverwenden. Alternativ kann die Variable $objs
an ein anderes Script übergeben werden. Gerne kann auch das Script nach Belieben erweitert werden.