Delegieren Sie die Verwaltung von RDP-Sitzungen

Delegieren Sie die Verwaltung von RDP-Sitzungen
In der Organisation, in der ich arbeite, ist Remote-Arbeit grundsätzlich verboten. War. Bis letzte Woche. Jetzt musste ich dringend eine Lösung umsetzen. Von Business – Anpassung von Prozessen an ein neues Arbeitsformat, von uns – PKI mit PIN-Codes und Tokens, VPN, detaillierte Protokollierung und vieles mehr.
Unter anderem war ich an der Einrichtung der Remote Desktop Infrastructure bzw. Terminal Services beteiligt. Wir haben mehrere RDS-Bereitstellungen in verschiedenen Rechenzentren. Eines der Ziele bestand darin, Kollegen aus verwandten IT-Abteilungen die interaktive Verbindung zu Benutzersitzungen zu ermöglichen. Wie Sie wissen, gibt es hierfür einen regulären RDS-Shadow-Mechanismus und der einfachste Weg, ihn zu delegieren, besteht darin, lokalen Administratorrechten auf RDS-Servern zu erteilen.
Ich respektiere und schätze meine Kollegen, bin aber sehr gierig, wenn es darum geht, Admin-Rechte zu verteilen. 🙂 Wer mir zustimmt, bitte unter Kat.

Nun, die Aufgabe ist jetzt klar – zur Sache.

Schritt 1

Erstellen Sie eine Sicherheitsgruppe in Active Directory RDP_Operators und fügen Sie darin die Konten der Benutzer hinzu, an die wir Rechte delegieren möchten:

$Users = @(
    "UserLogin1",
    "UserLogin2",
    "UserLogin3"
)
$Group = "RDP_Operators"
New-ADGroup -Name $Group -GroupCategory Security -GroupScope DomainLocal
Add-ADGroupMember -Identity $Group -Members $Users

Wenn Sie über mehrere AD-Standorte verfügen, müssen Sie warten, bis die Replikation auf allen Domänencontrollern erfolgt, bevor Sie mit dem nächsten Schritt fortfahren. Dies dauert in der Regel nicht länger als 15 Minuten.

Schritt 2

Geben wir der Gruppe die Rechte, Terminalsitzungen auf jedem der RDSH-Server zu verwalten:

Set-RDSPermissions.ps1

$Group = "RDP_Operators"
$Servers = @(
    "RDSHost01",
    "RDSHost02",
    "RDSHost03"
)
ForEach ($Server in $Servers) {
    #Делегируем право на теневые сессии
    $WMIHandles = Get-WmiObject `
        -Class "Win32_TSPermissionsSetting" `
        -Namespace "rootCIMV2terminalservices" `
        -ComputerName $Server `
        -Authentication PacketPrivacy `
        -Impersonation Impersonate
    ForEach($WMIHandle in $WMIHandles)
    {
        If ($WMIHandle.TerminalName -eq "RDP-Tcp")
        {
        $retVal = $WMIHandle.AddAccount($Group, 2)
        $opstatus = "успешно"
        If ($retVal.ReturnValue -ne 0) {
            $opstatus = "ошибка"
        }
        Write-Host ("Делегирование прав на теневое подключение группе " +
            $Group + " на сервере " + $Server + ": " + $opstatus + "`r`n")
        }
    }
}

Schritt 3

Fügen Sie eine Gruppe zu einer lokalen Gruppe hinzu Remotedesktopbenutzer auf jedem der RDSH-Server. Wenn Ihre Server zu Sitzungssammlungen zusammengefasst sind, tun wir dies auf Sammlungsebene:

$Group = "RDP_Operators"
$CollectionName = "MyRDSCollection"
[String[]]$CurrentCollectionGroups = @(Get-RDSessionCollectionConfiguration -CollectionName $CollectionName -UserGroup).UserGroup
Set-RDSessionCollectionConfiguration -CollectionName $CollectionName -UserGroup ($CurrentCollectionGroups + $Group)

Für einzelne Server verwenden Sie Gruppenrichtlinie, und wartet darauf, dass es auf den Servern angewendet wird. Für diejenigen, die zu faul zum Warten sind, können Sie den Vorgang vorzugsweise mit dem guten alten gpupdate erzwingen zentral.

Schritt 4

Bereiten wir das folgende PS-Skript für „Manager“ vor:

RDSManagement.ps1

$Servers = @(
    "RDSHost01",
    "RDSHost02",
    "RDSHost03"
)

function Invoke-RDPSessionLogoff {
    Param(
        [parameter(Mandatory=$True, Position=0)][String]$ComputerName,
        [parameter(Mandatory=$true, Position=1)][String]$SessionID
    )
    $ErrorActionPreference = "Stop"
    logoff $SessionID /server:$ComputerName /v 2>&1
}

function Invoke-RDPShadowSession {
    Param(
        [parameter(Mandatory=$True, Position=0)][String]$ComputerName,
        [parameter(Mandatory=$true, Position=1)][String]$SessionID
    )
    $ErrorActionPreference = "Stop"
    mstsc /shadow:$SessionID /v:$ComputerName /control 2>&1
}

Function Get-LoggedOnUser {
    Param(
        [parameter(Mandatory=$True, Position=0)][String]$ComputerName="localhost"
    )
    $ErrorActionPreference = "Stop"
    Test-Connection $ComputerName -Count 1 | Out-Null
    quser /server:$ComputerName 2>&1 | Select-Object -Skip 1 | ForEach-Object {
        $CurrentLine = $_.Trim() -Replace "s+"," " -Split "s"
        $HashProps = @{
            UserName = $CurrentLine[0]
            ComputerName = $ComputerName
        }
        If ($CurrentLine[2] -eq "Disc") {
            $HashProps.SessionName = $null
            $HashProps.Id = $CurrentLine[1]
            $HashProps.State = $CurrentLine[2]
            $HashProps.IdleTime = $CurrentLine[3]
            $HashProps.LogonTime = $CurrentLine[4..6] -join " "
            $HashProps.LogonTime = $CurrentLine[4..($CurrentLine.GetUpperBound(0))] -join " "
        }
        else {
            $HashProps.SessionName = $CurrentLine[1]
            $HashProps.Id = $CurrentLine[2]
            $HashProps.State = $CurrentLine[3]
            $HashProps.IdleTime = $CurrentLine[4]
            $HashProps.LogonTime = $CurrentLine[5..($CurrentLine.GetUpperBound(0))] -join " "
        }
        New-Object -TypeName PSCustomObject -Property $HashProps |
        Select-Object -Property UserName, ComputerName, SessionName, Id, State, IdleTime, LogonTime
    }
}

$UserLogin = Read-Host -Prompt "Введите логин пользователя"
Write-Host "Поиск RDP-сессий пользователя на серверах..."
$SessionList = @()
ForEach ($Server in $Servers) {
    $TargetSession = $null
    Write-Host "  Опрос сервера $Server"
    Try {
        $TargetSession = Get-LoggedOnUser -ComputerName $Server | Where-Object {$_.UserName -eq $UserLogin}
    }
    Catch {
        Write-Host "Ошибка: " $Error[0].Exception.Message -ForegroundColor Red
        Continue
    }
    If ($TargetSession) {
        Write-Host "    Найдена сессия с ID $($TargetSession.ID) на сервере $Server" -ForegroundColor Yellow
        Write-Host "    Что будем делать?"
        Write-Host "      1 - подключиться к сессии"
        Write-Host "      2 - завершить сессию"
        Write-Host "      0 - ничего"
        $Action = Read-Host -Prompt "Введите действие"
        If ($Action -eq "1") {
            Invoke-RDPShadowSession -ComputerName $Server -SessionID $TargetSession.ID
        }
        ElseIf ($Action -eq "2") {
            Invoke-RDPSessionLogoff -ComputerName $Server -SessionID $TargetSession.ID
        }
        Break
    }
    Else {
        Write-Host "    сессий не найдено"
    }
}

Um die Ausführung des PS-Skripts zu vereinfachen, erstellen wir eine Shell dafür in Form einer cmd-Datei mit demselben Namen wie das PS-Skript:

RDSManagement.cmd

@ECHO OFF
powershell -NoLogo -ExecutionPolicy Bypass -File "%~d0%~p0%~n0.ps1" %*

Wir legen beide Dateien in einem Ordner ab, der den „Managern“ zur Verfügung steht, und bitten sie, sich erneut anzumelden. Durch Ausführen der cmd-Datei können sie nun eine Verbindung zu den Sitzungen anderer Benutzer im RDS-Schattenmodus herstellen und diese zum Abmelden zwingen (dies ist nützlich, wenn der Benutzer die „hängen gebliebene“ Sitzung nicht selbst beenden kann).

Es sieht ungefähr so ​​aus:

Für „Manager“Delegieren Sie die Verwaltung von RDP-Sitzungen

Für den BenutzerDelegieren Sie die Verwaltung von RDP-Sitzungen

Ein paar letzte Bemerkungen

Nuance 1. Wenn die Sitzung des Benutzers, über den wir die Kontrolle erlangen wollen, gestartet wurde, bevor das Skript Set-RDSPermissions.ps1 auf dem Server ausgeführt wurde, erhält der „Manager“ einen Zugriffsfehler. Die Lösung liegt hier auf der Hand: Warten Sie, bis sich der verwaltete Benutzer erneut anmeldet.

Nuance 2. Nach mehreren Tagen der Arbeit mit RDP Shadow bemerkten sie einen interessanten Fehler oder eine interessante Funktion: Nach dem Ende der Shadow-Sitzung verschwindet die Sprachleiste des Benutzers, mit dem sie verbunden waren, in der Taskleiste, und um sie zurückzugeben, wird die Sprachleiste angezeigt Der Benutzer muss sich erneut anmelden. Wie sich herausstellt, sind wir nicht allein: Zeit, два, drei.

Das ist alles. Ich wünsche Ihnen und Ihren Servern Gesundheit. Ich freue mich wie immer über Ihr Feedback in den Kommentaren und bitte Sie, unten an einer kurzen Umfrage teilzunehmen.

Quellen

An der Umfrage können nur registrierte Benutzer teilnehmen. Einloggenbitte.

Was benutzt du?

  • 8,1%AMMYY Admin5

  • 17,7%AnyDesk11

  • 9,7%DameWare6

  • 24,2%Radmin15

  • 14,5%RDS Shadow9

  • 1,6%Quick Assist / Windows-Remoteunterstützung1

  • 38,7%TeamViewer24

  • 32,3%VNC20

  • 32,3%andere20

  • 3,2%LiteManager2

62 Benutzer haben abgestimmt. 22 Benutzer enthielten sich der Stimme.

Source: habr.com

Kommentar hinzufügen