Delegiranje upravljanja RDP sesijama

Delegiranje upravljanja RDP sesijama
U organizaciji u kojoj radim rad na daljinu je načelno zabranjen. bio. Sve do prošlog tjedna. Sada smo morali hitno implementirati rješenje. Od poslovanja - prilagođavanje procesa novom formatu rada, od nas - PKI s PIN kodovima i tokenima, VPN, detaljno logovanje i još mnogo toga.
Između ostalog, postavljao sam Remote Desktop Infrastructure aka Terminal Services. Imamo nekoliko implementacija RDS-a u različitim podatkovnim centrima. Jedan od ciljeva bio je omogućiti kolegama iz srodnih IT odjela interaktivno povezivanje na korisničke sesije. Kao što znate, za to postoji standardni RDS Shadow mehanizam, a najlakši način da ga delegirate je davanje lokalnih administratorskih prava na RDS poslužiteljima.
Poštujem i cijenim svoje kolege, ali sam vrlo pohlepan kada je u pitanju dijeljenje administratorskih prava. 🙂 Za one koji se slažu sa mnom, molim vas da pratite rez.

Pa, zadatak je jasan, a sada idemo na posao.

Korak 1

Kreirajmo sigurnosnu grupu u Active Directory RDP_Operatori i u njega uključiti račune onih korisnika kojima želimo prenijeti prava:

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

Ako imate više AD stranica, morat ćete pričekati dok se ne replicira na sve kontrolere domene prije nego što prijeđete na sljedeći korak. To obično ne traje više od 15 minuta.

Korak 2

Dajmo grupi prava za upravljanje terminalskim sesijama na svakom od RDSH poslužitelja:

Postavi-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")
        }
    }
}

Korak 3

Dodajte grupu u lokalnu grupu Korisnici udaljene radne površine na svakom od RDSH poslužitelja. Ako su vaši poslužitelji kombinirani u zbirke sesija, tada to radimo na razini zbirke:

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

Za pojedinačne poslužitelje koje koristimo pravila grupe, čekajući da se primijeni na poslužiteljima. Oni koji su previše lijeni za čekanje mogu ubrzati proces korištenjem dobrog starog gpupdatea, po mogućnosti centralno.

Korak 4

Pripremimo sljedeću PS skriptu za "menadžere":

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 "    сессий не найдено"
    }
}

Kako bismo PS skriptu učinili zgodnom za pokretanje, stvorit ćemo ljusku za nju u obliku cmd datoteke s istim nazivom kao i PS skripta:

RDSManagement.cmd

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

Obje datoteke stavljamo u mapu koja će biti dostupna “menadžerima” i tražimo od njih da se ponovno prijave. Sada, pokretanjem cmd datoteke, oni će se moći povezati sa sesijama drugih korisnika u RDS Shadow modu i prisiliti ih da se odjave (ovo može biti korisno kada korisnik ne može samostalno prekinuti "viseću" sesiju).

Izgleda ovako:

Za "menadžera"Delegiranje upravljanja RDP sesijama

Za korisnikaDelegiranje upravljanja RDP sesijama

Nekoliko završnih komentara

Nijansa 1. Ako je korisnička sesija nad kojom pokušavamo preuzeti kontrolu pokrenuta prije nego što je skripta Set-RDSPermissions.ps1 izvršena na poslužitelju, tada će "upravitelj" dobiti grešku pristupa. Rješenje je očito: pričekajte dok se upravljani korisnik ne prijavi.

Nijansa 2. Nakon nekoliko dana rada s RDP Shadowom, primijetili smo zanimljivu pogrešku ili značajku: nakon završetka shadow sesije, jezična traka u traci nestaje za korisnika s kojim se povezuje, a da bi je vratio, korisnik treba ponovno -prijaviti se. Kako se pokazalo, nismo sami: vrijeme, два, tri.

To je sve. Vama i vašim poslužiteljima želim dobro zdravlje. Kao i uvijek, veselim se vašim povratnim informacijama u komentarima i molim vas da ispunite kratku anketu u nastavku.

izvori

U anketi mogu sudjelovati samo registrirani korisnici. Prijaviti se, molim.

Što koristite?

  • 8,1%AMMYY Administrator5

  • 17,7%Bilo koji radni stol11

  • 9,7%DameWare6

  • 24,2%Radmin15

  • 14,5%RDS sjena9

  • 1,6%Brza pomoć / Windows daljinska pomoć1

  • 38,7%TeamViewer24

  • 32,3%VNC20

  • 32,3%ostalo20

  • 3,2%LiteManager2

Glasovalo je 62 korisnika. Suzdržana su bila 22 korisnika.

Izvor: www.habr.com

Dodajte komentar