Gestión delegada de sesiones RDP

Gestión delegada de sesiones RDP
En la organización donde trabajo, el trabajo remoto está prohibido en principio. Era. Hasta la semana pasada. Ahora tenía que implementar urgentemente una solución. De empresa - adaptación de procesos a un nuevo formato de trabajo, de nosotros - PKI con códigos pin y tokens, VPN, registro detallado y mucho más.
Entre otras cosas, participé en la configuración de la infraestructura de escritorio remoto, también conocida como servicios de terminal. Tenemos varias implementaciones de RDS en diferentes centros de datos. Uno de los objetivos era permitir que los colegas de los departamentos de TI relacionados se conectaran a las sesiones de los usuarios de forma interactiva. Como sabe, existe un mecanismo RDS Shadow regular para esto y la forma más fácil de delegar es otorgar derechos de administrador local en los servidores RDS.
Respeto y aprecio a mis colegas, pero soy muy codicioso por distribuir derechos de administrador. 🙂 Quienes estén de acuerdo conmigo, por favor bajo cat.

Bueno, la tarea está clara, ahora: para hacer negocios.

Paso 1

Crear un grupo de seguridad en Active Directory RDP_Operadores e incluir en ella las cuentas de aquellos usuarios a los que queremos delegar derechos:

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

Si tiene varios sitios de AD, antes de pasar al siguiente paso, debe esperar hasta que se replique en todos los controladores de dominio. Esto por lo general no toma más de 15 minutos.

Paso 2

Démosle al grupo los derechos para administrar sesiones de terminal en cada uno de los servidores RDSH:

Establecer-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

Agregar un grupo a un grupo local Usuarios de escritorio remoto en cada uno de los servidores RDSH. Si sus servidores se combinan en colecciones de sesiones, lo hacemos 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 individuales, use política de grupo, esperando a que se aplique en los servidores. Para aquellos demasiado perezosos para esperar, puede forzar el proceso con gpupdate, preferiblemente centralmente.

Paso 4

Preparemos el siguiente script PS para "gerentes":

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 sea conveniente ejecutar el script de PS, crearemos un shell para él en forma de archivo cmd con el mismo nombre que el script de PS:

RDSManagement.cmd

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

Ponemos ambos archivos en una carpeta que estará disponible para los "gestores" y les pedimos que vuelvan a iniciar sesión. Ahora, al ejecutar el archivo cmd, podrán conectarse a las sesiones de otros usuarios en modo RDS Shadow y forzarlos a cerrar sesión (es útil cuando el usuario no puede finalizar la sesión "colgada" por sí mismo).

Se parece a esto:

Por "gerente"Gestión delegada de sesiones RDP

para el usuarioGestión delegada de sesiones RDP

Unas últimas observaciones

matiz 1. Si la sesión del usuario sobre el que intentamos obtener el control se inició antes de que se ejecutara el script Set-RDSPermissions.ps1 en el servidor, el "administrador" recibirá un error de acceso. La solución aquí es obvia: espere a que el usuario administrado vuelva a iniciar sesión.

matiz 2. Después de varios días de trabajar con RDP Shadow, notaron un error o característica interesante: después de que finaliza la sesión de sombra, el usuario al que se conectaron desaparece la barra de idioma en la bandeja y para devolverla, el usuario debe volver a acceso. Resulta que no estamos solos: tiempo, два, tres.

Eso es todo. Deseo salud para usted y sus servidores. Como siempre, espero sus comentarios en los comentarios y le pido que responda una breve encuesta a continuación.

fuentes

Solo los usuarios registrados pueden participar en la encuesta. Registrarsepor favor

¿Que usas?

  • 8,1%Administrador de AMMYY5

  • 17,7%cualquier escritorio11

  • 9,7%dameware6

  • 24,2%radmin15

  • 14,5%RDS Shadow9

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

  • 38,7%TeamViewer24

  • 32,3%VNC20

  • 32,3%otros20

  • 3,2%LiteManager2

62 usuarios votaron. 22 usuarios se abstuvieron.

Fuente: habr.com

Añadir un comentario