Gestione delegata delle sessioni RDP

Gestione delegata delle sessioni RDP
Nell’organizzazione in cui lavoro, il lavoro a distanza è in linea di principio vietato. Era. Fino alla settimana scorsa. Ora dovevo implementare urgentemente una soluzione. Dal business - adattamento dei processi a un nuovo formato di lavoro, da noi - PKI con codici PIN e token, VPN, registrazione dettagliata e molto altro.
Tra le altre cose, sono stato coinvolto nella creazione dell'infrastruttura desktop remoto, ovvero Servizi terminal. Abbiamo diverse implementazioni RDS in diversi data center. Uno degli obiettivi era consentire ai colleghi dei reparti IT correlati di connettersi alle sessioni utente in modo interattivo. Come sai, esiste un normale meccanismo RDS Shadow per questo e il modo più semplice per delegarlo è concedere i diritti di amministratore locale sui server RDS.
Rispetto e apprezzo i miei colleghi, ma sono molto avido nella distribuzione dei diritti di amministratore. 🙂 Chi è d'accordo con me, per favore sotto cat.

Bene, ora il compito è chiaro: gli affari.

Passo 1

Crea un gruppo di sicurezza in Active Directory RDP_Operatori e includere in esso gli account degli utenti a cui vogliamo delegare i diritti:

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

Se disponi di più siti AD, prima di passare al passaggio successivo è necessario attendere la replica su tutti i controller di dominio. Di solito non ci vogliono più di 15 minuti.

Passo 2

Diamo al gruppo i diritti per gestire le sessioni terminale su ciascuno dei server RDSH:

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

Passo 3

Aggiungi un gruppo a un gruppo locale Utenti desktop remoti su ciascuno dei server RDSH. Se i tuoi server sono combinati in raccolte di sessioni, lo facciamo a livello di raccolta:

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

Per server singoli, utilizzare politica di gruppo, in attesa che venga applicato sui server. Per quelli troppo pigri per aspettare, è possibile forzare il processo con il buon vecchio gpupdate, preferibilmente centralmente.

Passo 4

Prepariamo il seguente script PS per "manager":

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

Per rendere conveniente l'esecuzione dello script PS, creeremo una shell sotto forma di file cmd con lo stesso nome dello script PS:

RDSManagement.cmd

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

Inseriamo entrambi i file in una cartella che sarà disponibile ai "gestori" e chiediamo loro di effettuare nuovamente l'accesso. Ora, eseguendo il file cmd, potranno connettersi alle sessioni di altri utenti in modalità RDS Shadow e forzarli al logout (è utile quando l'utente non riesce a terminare da solo la sessione “bloccata”).

Sembra qualcosa del genere:

Per "direttore"Gestione delegata delle sessioni RDP

Per l'utenteGestione delegata delle sessioni RDP

Alcune ultime osservazioni

Sfumatura 1. Se la sessione dell'utente di cui stiamo cercando di ottenere il controllo è stata avviata prima che lo script Set-RDSPermissions.ps1 fosse eseguito sul server, il "manager" riceverà un errore di accesso. La soluzione qui è ovvia: attendere che l'utente gestito esegua nuovamente l'accesso.

Sfumatura 2. Dopo diversi giorni di lavoro con RDP Shadow, hanno notato un bug o una funzionalità interessante: dopo la fine della sessione shadow, l'utente a cui si sono connessi scompare dalla barra della lingua nella barra delle applicazioni e, per ripristinarla, l'utente deve effettuare nuovamente l'accesso. A quanto pare, non siamo soli: tempo, два, tre.

È tutto. Auguro salute a te e ai tuoi servitori. Come sempre, attendo con ansia il tuo feedback nei commenti e ti chiedo di partecipare a un breve sondaggio qui sotto.

fonti

Solo gli utenti registrati possono partecipare al sondaggio. AccediPer favore.

Cosa usi?

  • 8,1%AMMYY Amministratore5

  • 17,7%AnyDesk11

  • 9,7%DameWare6

  • 24,2%Radmin15

  • 14,5%RDS Shadow9

  • 1,6%Assistenza rapida/Assistenza remota Windows1

  • 38,7%TeamViewer24

  • 32,3%VNC20

  • 32,3%altro20

  • 3,2%LiteManager2

62 utenti hanno votato. 22 utenti si sono astenuti.

Fonte: habr.com

Aggiungi un commento