Delegiranje upravljanja RDP sesijama

Delegiranje upravljanja RDP sesijama
U organizaciji u kojoj radim, rad od kuće je u osnovi bio zabranjen. Bio je. Do prošlog tjedna. Sada je bilo potrebno hitno implementirati rješenje. Od posla — prilagodba procesa novom radnom formatu, od nas — PKI s PIN kodovima i tokenima, VPN, detaljno logiranje i mnogo toga još.
Osim svega, bavio sam se konfiguracijom infrastrukture daljinskih radnih površina, aka terminalske usluge. Imamo nekoliko RDS implementacija u različitim podatkovnim centrima. Jedan od zadataka bio je omogućiti kolegama iz susjednih IT odjela da se povežu na korisničke sesije u interaktivnom modu. Kao što je poznato, za ovo postoji ugrađeni mehanizam RDS Shadow, a najjednostavniji način za delegiranje prava je dati ovlasti lokalnog administratora na RDS poslužiteljima.
Cijenim svoje kolege, ali vrlo sam škrt na dodjeli administratorskih prava. 🙂 One koji se slažu sa mnom, pozivam pod kat.

Pa, zadatak je jasan, sada — na posao.

Korak 1

Stvorimo sigurnosnu grupu u Active Directory-ju RDP_Operators i uključimo 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, prije nego što pređete na sljedeći korak, trebate pričekati da se replicira na sve kontrolere domene. Obično to traje ne više od 15 minuta.

Korak 2

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

Set-RDSPermissions.ps1

$Group = "RDP_Operators"
$Servers = @(
    "RDSHost01",
    "RDSHost02",
    "RDSHost03"
)
ForEach ($Server in $Servers) {
    # Delegiramo pravo na sjenovite sesije
    $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 = "uspješno"
        If ($retVal.ReturnValue -ne 0) {
            $opstatus = "greška"
        }
        Write-Host ("Delegiranje prava na sjenovito povezivanje grupi " +
            $Group + " na poslužitelju " + $Server + ": " + $opstatus + "`r`n")
        }
    }
}

Korak 3

Dodajmo grupu u lokalnu grupu Korisnici daljinskih radnih površina na svakom od RDSH poslužitelja. Ako su vaši poslužitelji povezani u kolekcijama sesija, to činimo na razini kolekcije:

$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 grupnu politiku, čekajući da se primijeni na serverima. Oni koji se ne žele čekati, mogu forsirati proces pomoću starog dobrog gpupdate, po mogućstvu centralizirano.

Korak 4

Pripremit ćemo za 'menadžere' takav PS skript:

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 "Unesite korisničko ime"
Write-Host "Traženje RDP sesija korisnika na serverima..."
$SessionList = @()
ForEach ($Server in $Servers) {
    $TargetSession = $null
    Write-Host "  Upit servera $Server"
    Try {
        $TargetSession = Get-LoggedOnUser -ComputerName $Server | Where-Object {$_.UserName -eq $UserLogin}
    }
    Catch {
        Write-Host "Greška: " $Error[0].Exception.Message -ForegroundColor Red
        Continue
    }
    If ($TargetSession) {
        Write-Host "    Pronađena sesija s ID $($TargetSession.ID) na serveru $Server" -ForegroundColor Yellow
        Write-Host "    Što ćemo napraviti?"
        Write-Host "      1 - povezati se na sesiju"
        Write-Host "      2 - završiti sesiju"
        Write-Host "      0 - ništa"
        $Action = Read-Host -Prompt "Unesite akciju"
        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 "    Sesije nisu pronađene"
    }
}

Kako bi PS skripta bila lakša za pokretanje, napravit ćemo za nju okvir u obliku cmd datoteke s istim imenom kao PS skripta:

RDSManagement.cmd

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

Stavljamo oba datoteke u mapu koja će biti dostupna «menadžerima» i tražimo od njih da se ponovo prijave. Sada, pokretanjem cmd-datoteke, oni će moći pristupiti sesijama drugih korisnika u režimu RDS Shadow i prisilno ih odjaviti (korisno kada korisnik ne može samostalno završiti «zamrznutu» sesiju).

Izgleda to otprilike ovako:

Za «menadžera»Delegiranje upravljanja RDP sesijama

Za korisnikaDelegiranje upravljanja RDP sesijama

Nekoliko zapažanja na kraju

Nijansa 1. Ako je sesija korisnika, kojoj pokušavamo pristupiti, pokrenuta pre nego što je na serveru izvršen skript Set-RDSPermissions.ps1, onda će «menadžer» dobiti grešku pristupa. Rešenje je očigledno: sačekati da se upravljani korisnik ponovo prijavi.

Nijansa 2. Nakon nekoliko dana rada sa RDP Shadow primetili smo zanimljivu ili grešku ili mogućnost: nakon završetka senke sesije kod korisnika, kojem smo se povezivali, nestaje jezička traka u sistemskoj traci i da bi se vratila, korisnik treba da se ponovo prijavi. Kako se ispostavilo, nismo jedini: jednom, dvaput, tri.

To je sve. Želim vam zdravlje i vašim serverima. Kao i uvek, očekujem povratne informacije u komentarima i molim vas da se obavezno prijavite na kratku anketu ispod.

Izvori

Samo registrirani korisnici mogu sudjelovati u anketi. Prijavite se, molimo.

Čime se koristite?

  • 8,1%AMMYY Admin5

  • 17,7%AnyDesk11

  • 9,7%DameWare6

  • 24,2%Radmin15

  • 14,5%RDS Shadow9

  • 1,6%Quick Assist / Windows Remote Assistance1

  • 38,7%TeamViewer24

  • 32,3%VNC20

  • 32,3%drugo20

  • 3,2%LiteManager2

Glasalo je 62 korisnika. Uzdržalo se 22 korisnika.

Izvor: habr.com

Kupite pouzdan hosting za web stranice s DDoS zaštitom, VPS VDS servere 🔥 Kupite pouzdan hosting za web stranice s DDoS zaštitom, VPS VDS servere | ProHoster