der-phil
Goto Top

Mehrere Windows 2012 R2 Terminalserver - gemeinsame Übersicht und Shadow der Sessions

Hallo!

Ich muss gerade eine neue Terminalserverfarm aufsetzen und von einer alten Windows 2003 Farm migrieren.
Es geht um anfangs zwei, dann drei Windows 2012 R2 Server.

Aufbau ist:
Loadbalancer -> TSE1
-> TSE2


Jetzt habe ich zwei Möglichkeiten probiert:

1. Remotedesktop-Connection-Broker als echte "Farm"
Hier sehe ich dann alle Sessions im Servermanager und kann sie beenden oder auch die Remoteüberwachung starten

Nachteile:
- Single-Point-Of-Failure ohne hochverfügbare SQL-Datenbank
- Keine Möglichkeit, dass ein User auf zwei Terminalservern angemeldet ist - sehr unangenehm zur Einrichtung
- Server-Manager zeigt nichts mehr, wenn einer der Server ausgefallen ist.

2. Einzelne, unabhängige Terminalserver nur über Loadbalancer nutzen
Da mein Loadbalancer auch ein Session-Verzeichnis bietet eigentlich eine prima Lösung, ABER:
Mir fehlt die alte Terminaldiensteverwaltung, in der ich mehrere Server sehe.


Die Hauptfrage ist also:
Gibt es irgendeine Lösung (gerne auch als Extrasoftware), in der ich die Sessions von mehreren Terminalservern, die keine gemeinsame Sammlung haben sehen, abmelden und shadowen kann?


Vielen Dank für eure Hilfe und eure Tipps

Gruß
Phil

Content-Key: 283765

Url: https://administrator.de/contentid/283765

Printed on: April 26, 2024 at 06:04 o'clock

Member: ukulele-7
ukulele-7 Sep 25, 2015 at 06:19:51 (UTC)
Goto Top
Also zunächst mal ist die Ausfallwarscheinlichkeit eines RD-CB vermutlich nicht besonders hoch wenn man ihn z.B. virtualisiert hat und mit anderen Mechanismen wie HA verfügbar hält. Ich würde jedenfalls keine dedizierte Hardware nur als RD-CB aufstellen, ist das bei dir der Fall?

Dann ist es meines Wissens nach auch möglich auf RD-SHs zu connecten wenn der RD-CB nicht verfügbar ist. Da bin ich mir aber nicht abschließend sicher, das habe ich noch nicht getestet.

Der "Trend", also die Entscheidung von Mircosoft die RDS Umgebungen von einem CB verwalten zu lassen, hat sicherlich Gründe. Möglicherweise kommen diesem in neueren Servergenerationen noch mehr Aufgaben zu und einige Vorteile bietet er ja schon. Ich würde hier also nicht die Brechstange auspacken um auf einen CB zugunsten einer "Bastellösung" verzichten. Vermutlich wird sich auch kein Anbieter von Extrasoftware auf diesem Gebiet betätigen, die würden eher versuchen den CB redudant zu halten und ihre Dienste darauf aufbauen, als den CB in seiner Funktion nachzubauen.

Versteh mich nicht falsch, der Gedanke eines Ausfalls ist mir auch gekommen und einige Dinge am CB nerven auch ein bischen. Ich habe dann aber das Risiko eines Ausfalls für mehr als 5 Minuten als zu gering angesehen. Wenn du dermaßen kritische Infrastruktur betreibst das auch dieses Restrisiko zählt solltest vermutlich erst recht von ungewöhnlichen Lösungen absehen, dadurch erhöhst du ja auch die Anfälligkeit und Komplexität deiner Systeme.
Member: Der-Phil
Der-Phil Sep 25, 2015 updated at 14:17:03 (UTC)
Goto Top
Hallo!

Wenn die Verbindung möglich wäre, wenn der Connection Broker ausgefallen ist, wäre ja alles prima. Kannst Du das bei Gelegenheit bei Dir mal testen?

Wäre prima!

Nachtrag: Ich habe das mal getestet: Wenn der Connection Broker weg ist, ist _KEINE_ Anmeldung mehr möglich.


Gruß
Phil
Member: ukulele-7
ukulele-7 Sep 25, 2015 at 14:24:33 (UTC)
Goto Top
Auch nicht unter angabe der Adresse eines RD-SH und ohne Sammlungsnamen in der .rdp? Eventuell kann man das irgendwie einstellen, ich meine es gelesen zu haben. Aber ich finde es auch nicht mehr, sry.
Member: Der-Phil
Der-Phil Oct 09, 2015 at 07:52:53 (UTC)
Goto Top
Hallo!

Falls noch jemand das Problem hat:
Ich habe es auf zwei Arten lösen können:

1. Über ein Powershell-Skript
Das Skript erstellt eine Liste der Sessions und daraus ein Menü im Batch-Stil. Dort kann man dann auf Shadow/Interact/Message/Logoff gehen. Nicht hübsch, aber o.k.

2. Terminal Services Manager von LizardSystems
Deutlich hübscher und fertig face-smile
Kostet 200$ pro System auf dem es installiert ist unabhängig von der Userzahl. Hätte ich das gleich gefunden, hätte ich mir das Coden gespart...

Phil
Member: ukulele-7
ukulele-7 Oct 09, 2015 at 14:01:42 (UTC)
Goto Top
Das Scirpt würde mich interessieren wenn du es eventuell teilst.

Ich habe mit dem RD-CB eigentlich kein Problem, mich stören nur drei Dinge:
- Ich muss manuell aktualisieren
- Meine VM hat einen kleinen Bildschirm, ich muss immer scrollen
- Ich sehe an keiner Stelle mehr von welchem Host aus die Verbindung aufgebaut wurde
Member: Der-Phil
Der-Phil Oct 27, 2015 at 15:00:10 (UTC)
Goto Top
Hallo!

Nicht schön, aber selten...
$Servers = "TSE1","TSE2"  



function DrawMenu {
    ## supportfunction to the Menu function below
    param ($menuItems, $menuPosition, $menuTitel)
    $fcolor = $host.UI.RawUI.ForegroundColor
    $bcolor = $host.UI.RawUI.BackgroundColor
    $l = $menuItems.length + 1
    cls
    $menuwidth = $menuTitel.length + 4
    Write-Host "`t" -NoNewLine  
    Write-Host ("*" * $menuwidth) -fore $fcolor -back $bcolor  
    Write-Host "`t" -NoNewLine  
    Write-Host "* $menuTitel *" -fore $fcolor -back $bcolor  
    Write-Host "`t" -NoNewLine  
    Write-Host ("*" * $menuwidth) -fore $fcolor -back $bcolor  
    Write-Host ""  
    Write-debug "L: $l MenuItems: $menuItems MenuPosition: $menuposition"  
    for ($i = 0; $i -le $l;$i++) {
  ##      Write-Host "`t" -NoNewLine 
        if ($i -eq $menuPosition) {
            Write-Host "$($menuItems[$i])" -fore $bcolor -back $fcolor  
        } else {
            Write-Host "$($menuItems[$i])" -fore $fcolor -back $bcolor  
        }
    }
}

function Menu {
    ## Generate a small "DOS-like" menu. 
    ## Choose a menuitem using up and down arrows, select by pressing ENTER
    param ([array]$menuItems, $menuTitel = "MENU")  
    $vkeycode = 0
    $pos = 0
    DrawMenu $menuItems $pos $menuTitel
    While ($vkeycode -ne 13) {
        $press = $host.ui.rawui.readkey("NoEcho,IncludeKeyDown")  
        $vkeycode = $press.virtualkeycode
        Write-host "$($press.character)" -NoNewLine  
        If ($vkeycode -eq 38) {$pos--}
        If ($vkeycode -eq 40) {$pos++}
        if ($pos -lt 0) {$pos = 0}
        if ($pos -ge $menuItems.length) {$pos = $menuItems.length -1}
        DrawMenu $menuItems $pos $menuTitel
    }
    Write-Output $($menuItems[$pos])
}



Function Get-ComputerSessions {
<#
.SYNOPSIS
    Retrieves tall user sessions from local or remote server/s
.DESCRIPTION
    Retrieves tall user sessions from local or remote server/s
.PARAMETER computer
    Name of computer/s to run session query against.
.NOTES
    Name: Get-ComputerSessions
    Author: Boe Prox
    DateCreated: 01Nov2010
 
.LINK
    https://boeprox.wordpress.org
.EXAMPLE
Get-ComputerSessions -computer "server1"  
 
Description
-----------
This command will query all current user sessions on 'server1'.  
 
#>
[cmdletbinding(
    DefaultParameterSetName = 'session',  
    ConfirmImpact = 'low'  
)]
    Param(
        [Parameter(
            Mandatory = $True,
            Position = 0,
            ValueFromPipeline = $True)]
            [string[]]$computer
            )
Begin {
    $report = @()
    }
Process {
    ForEach($c in $computer) {
        # Parse 'query session' and store in $sessions:  
        $sessions = query user /server:$c
            1..($sessions.count -1) | % {
                $temp = "" | Select Computer,User,Type,Id,Idle,Login  
                $temp.Computer = $c
                $temp.User = $sessions[$_].Substring(1,21).Trim()
                $temp.Type = $sessions[$_].Substring(22,19).Trim()
                $temp.Id = $sessions[$_].Substring(41,4).Trim()
		
		$tstring = $sessions[$_].Substring(54,10).Trim()
		$temp.Idle = $sessions[$_].Substring(54,10).Trim()
		if ($tstring.Length -eq 1) { $temp.Idle = '00:0' + $sessions[$_].Substring(54,10).Trim() }  
		if ($tstring.Length -eq 2) { $temp.Idle = '00:' + $sessions[$_].Substring(54,10).Trim() }  
		if ($tstring.Length -eq 4) { $temp.Idle = '0' + $sessions[$_].Substring(54,10).Trim() }  
             	if ($sessions[$_].Substring(54,10).Trim() -eq '.') { $temp.Idle = $sessions[$_].Substring(54,10).Trim() }  
           	if ($sessions[$_].Substring(54,10).Trim() -eq 'Kein') { $temp.Idle = $sessions[$_].Substring(54,10).Trim() }  

                $temp.Login = $sessions[$_].Substring(76).Trim()
#                $temp.Device = $sessions[$_].Substring(68).Trim()
                $report += $temp
            }
        }
    }
End {
    $report
    }
}



do {

$sortoptions = ("User","Computer","Idle","Login")  
$sortselection = Menu $sortoptions "Sorting:"  





(Get-ComputerSessions -computer @($Servers) | sort $sortselection | FT) > sessions.txt


$options = (Get-content sessions.txt | Foreach-Object {$_} )


#Write-Host $options


$selection = Menu $options "Sessions:"  

$selection1 = $selection

$choice2 = $selection
$options2 = ("...back","Interact","Shadow","Logoff","Message","Exit")  

$selection2 = Menu $options2 "Action"  


$TSE = $selection1.Substring(0,8).Trim()
$session = $selection1.Substring(60,4).Trim()



Switch ($selection2)
{
 "...back" { '' }  
 "Interact" {  
	Write-Host $selection1
	Write-Host $session
	Write-Host "/shadow:$session /v:$TSE /control /noConsentPrompt"  
	Pause
Start-Process mstsc.exe -ArgumentList "/shadow:$session /v:$TSE /control /noConsentPrompt" } ## -verb RunAs  
 "Shadow" { mstsc /shadow:$session /v:$TSE /noConsentPrompt }  
 "Logoff" { Logoff /server:$TSE $session $message}  
 "Message" {  
		$message = Read-Host 'Message-text:'  
		mstsc /shadow:$session /v:$TSE /noConsentPrompt $message }
 "Exit" {}   
}


} while ($selection2 -ne "Exit")  
Member: ukulele-7
ukulele-7 Oct 27, 2015 at 15:55:52 (UTC)
Goto Top
Alles klar, da steig ich nicht durch aber trotzdem Danke face-smile