Delegar a xestión das sesións RDP

Delegar a xestión das sesións RDP
Na organización onde traballo, o traballo a distancia está prohibido en principio. Foi. Ata a semana pasada. Agora tiñamos que implementar urxentemente unha solución. Desde as empresas: adaptación de procesos a un novo formato de traballo, de nós: PKI con códigos PIN e tokens, VPN, rexistro detallado e moito máis.
Entre outras cousas, estaba configurando a Infraestrutura de Escritorio Remoto tamén coñecido como Servizos de Terminal. Temos varios despregamentos de RDS en diferentes centros de datos. Un dos obxectivos era permitir que os compañeiros dos departamentos de TI relacionados se conectaran ás sesións dos usuarios de forma interactiva. Como sabes, hai un mecanismo de sombra RDS estándar para iso, e a forma máis sinxela de delegalo é dar dereitos de administrador local nos servidores RDS.
Respecto e valoro aos meus compañeiros, pero son moi cobizoso á hora de repartir dereitos de administrador. 🙂 Para os que estean de acordo comigo, sigan o corte.

Ben, a tarefa está clara, agora imos mans á obra.

Paso 1

Imos crear un grupo de seguridade en Active Directory RDP_Operadores e incluír nela as contas daqueles usuarios nos que queremos delegar dereitos:

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

Se tes varios sitios de AD, terás que esperar ata que se replique en todos os controladores de dominio antes de pasar ao seguinte paso. Isto normalmente non leva máis de 15 minutos.

Paso 2

Dámoslle ao grupo dereitos para xestionar sesións de terminal en cada un dos servidores 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")
        }
    }
}

Paso 3

Engade o grupo ao grupo local Usuarios de escritorio remoto en cada un dos servidores RDSH. Se os teus servidores se combinan en coleccións de sesións, facemos isto a nivel de colección:

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

Para servidores únicos que usamos política de grupo, á espera de que se aplique nos servidores. Os que teñan preguiza para esperar poden acelerar o proceso usando o bo gpupdate antigo, preferiblemente centralmente.

Paso 4

Imos preparar o seguinte script de PS para "xestores":

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

Para que o script PS sexa cómodo de executar, crearemos un shell para el en forma de ficheiro cmd co mesmo nome que o script PS:

RDSManagement.cmd

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

Poñemos ambos ficheiros nun cartafol ao que poderán acceder os "xestores" e pedímoslles que volvan iniciar sesión. Agora, ao executar o ficheiro cmd, poderán conectarse ás sesións doutros usuarios no modo RDS Shadow e obrigalos a pechar sesión (isto pode ser útil cando o usuario non pode finalizar de forma independente unha sesión "colgada").

Parece algo así:

Para o "xerente"Delegar a xestión das sesións RDP

Para o usuarioDelegar a xestión das sesións RDP

Uns comentarios finais

Matiz 1. Se a sesión de usuario sobre a que estamos tentando controlar se lanzou antes de que o script Set-RDSPermissions.ps1 se executase no servidor, entón o "xestor" recibirá un erro de acceso. A solución aquí é obvia: agarde ata que o usuario xestionado inicie sesión.

Matiz 2. Despois de varios días de traballar con RDP Shadow, observamos un erro ou función interesante: despois do final da sesión de sombra, a barra de idioma da bandexa desaparece para o usuario ao que se está conectado e, para recuperalo, o usuario ten que volver -Iniciar sesión. Polo que se ve, non estamos sós: tempo, два, tres.

Iso é todo. Deséxoche boa saúde a ti e aos teus servidores. Coma sempre, espero os teus comentarios nos comentarios e pídoche que fagas a pequena enquisa a continuación.

Fontes

Só os usuarios rexistrados poden participar na enquisa. Rexístrate, por favor.

Que usas?

  • 8,1%Administrador AMMYY 5

  • 17,7%AnyDesk11

  • 9,7%DameWare6

  • 24,2%Radmin 15

  • 14,5%RDS Shadow 9

  • 1,6%Asistencia rápida/Asistencia remota de Windows1

  • 38,7%TeamViewer 24

  • 32,3%VNC20

  • 32,3%outros 20

  • 3,2%LiteManager 2

Votaron 62 usuarios. 22 usuarios abstivéronse.

Fonte: www.habr.com

Engadir un comentario