Delega la gestione delle sessioni RDP

Delega la gestione delle sessioni RDP
Nell'organizzazione in cui lavoro, lo smart working era in principio vietato. Fino alla scorsa settimana. Ora abbiamo dovuto implementare urgentemente una soluzione. Da parte del business — adattare i processi al nuovo formato di lavoro, da parte nostra — PKI con codici PIN e token, VPN, registrazioni dettagliate e molto altro.
Oltre a tutto ciò, mi sono occupato della configurazione dell'infrastruttura dei desktop remoti, nota come servizio terminal. Abbiamo diverse distribuzioni RDS in diversi data center. Uno degli obiettivi era permettere ai colleghi di reparti adiacenti all'IT di collegarsi alle sessioni utente in modalità interattiva. Come noto, esiste un meccanismo nativo RDS Shadow e il modo più semplice per delegarlo è fornire diritti di amministratore locale sui server RDS.
Rispetto e apprezzo i miei colleghi, ma sono molto avaro nella distribuzione dei diritti di amministrazione. 🙂 Chi è d'accordo con me, venga a leggere di più.

Bene, il compito è chiaro, ora — al lavoro.

Passo 1

Creiamo un gruppo di sicurezza in Active Directory RDP_Operators e includiamo 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 hai più siti AD, prima di passare al passaggio successivo, devi attendere che venga replicato su tutti i controller di dominio. Di solito ciò richiede non più di 15 minuti.

Passo 2

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

Set-RDSPermissions.ps1

$Group = "RDP_Operators"
$Servers = @(
    "RDSHost01",
    "RDSHost02",
    "RDSHost03"
)
ForEach ($Server in $Servers) {
    #Delegiamo il diritto sulle sessioni shadow
    $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 = "riuscito"
        If ($retVal.ReturnValue -ne 0) {
            $opstatus = "errore"
        }
        Write-Host ("Delegazione dei diritti per la connessione shadow al gruppo " +
            $Group + " sul server " + $Server + ": " + $opstatus + "`r`n")
        }
    }
}

Passo 3

Aggiungiamo il gruppo al gruppo locale Utenti del desktop remoto su ciascun server RDSH. Se i server sono uniti in collezioni di sessioni, lo facciamo a livello di collezione:

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

Per i server singoli utilizziamo la policy di gruppo, aspettando che venga applicata sui server. Coloro che non vogliono aspettare possono forzare il processo utilizzando il buon vecchio gpupdate, preferibilmente in modo centralizzato.

Passo 4

Prepariamo per i "gestori" questo script PS:

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 "Inserisci il nome utente"
Write-Host "Ricerca delle sessioni RDP dell'utente sui server..."
$SessionList = @()
ForEach ($Server in $Servers) {
    $TargetSession = $null
    Write-Host "  Interrogazione del server $Server"
    Try {
        $TargetSession = Get-LoggedOnUser -ComputerName $Server | Where-Object {$_.UserName -eq $UserLogin}
    }
    Catch {
        Write-Host "Errore: " $Error[0].Exception.Message -ForegroundColor Red
        Continue
    }
    If ($TargetSession) {
        Write-Host "    Sessione trovata con ID $($TargetSession.ID) sul server $Server" -ForegroundColor Yellow
        Write-Host "    Cosa vuoi fare?"
        Write-Host "      1 - connettersi alla sessione"
        Write-Host "      2 - terminare la sessione"
        Write-Host "      0 - niente"
        $Action = Read-Host -Prompt "Inserisci l'azione"
        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 "    nessuna sessione trovata"
    }
}

Per facilitare l'esecuzione dello script PS, creeremo un wrapper 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" %*

Mettiamo entrambi i file in una cartella accessibile ai "gestori" e chiediamo loro di effettuare nuovamente il login. Ora, avviando il file cmd, potranno connettersi alle sessioni di altri utenti in modalità RDS Shadow e disconnetterli forzatamente (utile quando un utente non riesce a chiudere autonomamente una sessione "bloccata").

Ecco come appare:

Per il "gestore"Delega la gestione delle sessioni RDP

Per l'utenteDelega la gestione delle sessioni RDP

Alcune osservazioni finali

Nota 1. Se la sessione dell'utente a cui si cerca di accedere è stata avviata prima che lo script Set-RDSPermissions.ps1 fosse eseguito sul server, il "gestore" riceverà un errore di accesso. La soluzione qui è ovvia: attendere che l'utente controllato effettui di nuovo il login.

Nota 2. Dopo alcuni giorni di lavoro con RDP Shadow, abbiamo notato un comportamento interessante, che potrebbe essere un bug o una funzionalità: dopo la conclusione della sessione shadow dell'utente a cui ci siamo collegati, la barra della lingua nella tray scompare, e per ripristinarla, l'utente deve eseguire il logout. A quanto pare, non siamo soli. una volta, due volte, tre volte.

Questo è tutto. Vi auguro buona salute a voi e ai vostri server. Come sempre, aspetto il vostro feedback nei commenti e vi chiedo di completare un breve sondaggio qui sotto.

Fonti

Solo gli utenti registrati possono partecipare al sondaggio. Accedi, per favore.

Quale strumento usate?

  • 8,1%AMMYY Admin5

  • 17,7%AnyDesk11

  • 9,7%DameWare6

  • 24,2%Radmin15

  • 14,5%RDS Shadow9

  • 1,6%Assistenza Rapida / Assistenza Remota di Windows1

  • 38,7%TeamViewer24

  • 32,3%VNC20

  • 32,3%altro20

  • 3,2%LiteManager2

Hanno votato 62 utenti. 22 utenti si sono astenuti.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster