Delegiranje upravljanja sesijama RDP-a

Delegiranje upravljanja sesijama RDP-a
U organizaciji u kojoj radim rad na daljinu je u principu zabranjen. Bio. Do prošle sedmice. Sada smo morali hitno implementirati rješenje. Od poslovanja - prilagođavanje procesa novom formatu rada, od nas - PKI sa PIN kodovima i tokenima, VPN, detaljna evidencija i još mnogo toga.
Između ostalog, postavljao sam Remote Desktop Infrastructure aka Terminal Services. Imamo nekoliko RDS implementacija u različitim data centrima. Jedan od ciljeva je bio omogućiti kolegama iz srodnih IT odjela da se interaktivno povežu na korisničke sesije. Kao što znate, postoji standardni RDS Shadow mehanizam za ovo, a najlakši način da se delegira je da se daju prava lokalnog administratora na RDS serverima.
Poštujem i cijenim svoje kolege, ali sam jako pohlepan kada je riječ o dodjeli administratorskih prava. 🙂 Za one koji se slažu sa mnom, molim vas da pratite rez.

Pa, zadatak je jasan, a sad pređimo na posao.

korak 1

Kreirajmo sigurnosnu grupu u Active Directory RDP_Operatori i uključiti u njega račune onih korisnika kojima želimo delegirati 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 lokacija, morat ćete pričekati dok se ne replicira na sve kontrolere domene prije nego što pređete na sljedeći korak. Ovo obično ne traje više od 15 minuta.

korak 2

Dajmo grupi prava da upravlja terminalskim sesijama na svakom od RDSH servera:

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

korak 3

Dodajte grupu lokalnoj grupi Korisnici udaljene radne površine na svakom od RDSH servera. Ako su vaši serveri kombinovani u kolekcije sesija, onda to radimo na nivou prikupljanja:

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

Za pojedinačne servere koristimo grupna politika, čekajući da se primijeni na serverima. Oni koji su previše lijeni da čekaju mogu ubrzati proces koristeći stari stari gpupdate, po mogućnosti centralno.

korak 4

Hajde da pripremimo sledeć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 "    сессий не найдено"
    }
}

Da bismo PS skriptu učinili zgodnom za pokretanje, kreirat ćemo ljusku za nju u obliku cmd datoteke s istim imenom kao i PS skripta:

RDSManagement.cmd

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

Stavljamo obje datoteke u mapu koja će biti dostupna "menadžerima" i tražimo od njih da se ponovo prijave. Sada, pokretanjem cmd datoteke, moći će se 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 sesijama RDP-a

Za korisnikaDelegiranje upravljanja sesijama RDP-a

Nekoliko završnih komentara

Nijansa 1. Ako je korisnička sesija nad kojom pokušavamo da dobijemo kontrolu pokrenuta prije nego što je skripta Set-RDSPermissions.ps1 izvršena na serveru, tada će “menadžer” dobiti grešku pristupa. Rješenje je ovdje očigledno: pričekajte dok se upravljani korisnik ne prijavi.

Nijansa 2. Nakon nekoliko dana rada sa RDP Shadow, primijetili smo zanimljivu grešku ili značajku: nakon završetka shadow sesije, jezička traka u traci nestaje za korisnika na kojeg se povezuje, a da bi je vratio, korisnik mora ponovo -Ulogovati se. Kako se ispostavilo, nismo sami: puta, два, tri.

To je sve. Želim Vama i Vašim serverima dobro zdravlje. Kao i uvijek, radujem se vašim povratnim informacijama u komentarima i molim vas da popunite kratku anketu u nastavku.

Izvori

Samo registrovani korisnici mogu učestvovati u anketi. Prijavite semolim.

šta koristiš?

  • 8,1%AMMYY Admin5

  • 17,7%AnyDesk11

  • 9,7%DameWare6

  • 24,2%Radmin15

  • 14,5%RDS Shadow9

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

  • 38,7%TeamViewer24

  • 32,3%VNC20

  • 32,3%ostalo20

  • 3,2%LiteManager2

62 korisnika je glasalo. 22 korisnika su bila uzdržana.

izvor: www.habr.com

Dodajte komentar