Delegando o gerenciamento de sessões RDP

Delegando o gerenciamento de sessões RDP
Na organização onde trabalho, o trabalho remoto é, em princípio, proibido. Era. Até a semana passada. Agora tínhamos que implementar urgentemente uma solução. De negócios - adaptação de processos a um novo formato de trabalho, de nós - PKI com códigos PIN e tokens, VPN, registro detalhado e muito mais.
Entre outras coisas, eu estava configurando a Infraestrutura de Área de Trabalho Remota, também conhecida como Terminal Services. Temos diversas implantações de RDS em diferentes data centers. Um dos objetivos era permitir que colegas de departamentos de TI relacionados se conectassem interativamente às sessões dos usuários. Como você sabe, existe um mecanismo RDS Shadow padrão para isso, e a maneira mais fácil de delegá-lo é conceder direitos de administrador local nos servidores RDS.
Respeito e valorizo ​​meus colegas, mas sou muito ganancioso quando se trata de conceder direitos de administrador. 🙂 Para quem concorda comigo, siga o corte.

Bem, a tarefa está clara, agora vamos ao que interessa.

Passo 1

Vamos criar um grupo de segurança no Active Directory RDP_Operadores e incluir nele as contas dos usuários aos quais queremos delegar direitos:

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

Se você tiver vários sites do AD, precisará aguardar até que ele seja replicado para todos os controladores de domínio antes de passar para a próxima etapa. Isso geralmente não leva mais de 15 minutos.

Passo 2

Vamos dar ao grupo direitos para gerenciar sessões de terminal em cada um 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")
        }
    }
}

Passo 3

Adicione o grupo ao grupo local Usuários de área de trabalho remota em cada um dos servidores RDSH. Se seus servidores estiverem combinados em coleções de sessões, faremos isso no nível da coleção:

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

Para servidores únicos, usamos política de grupo, aguardando que seja aplicado nos servidores. Quem tem preguiça de esperar pode acelerar o processo usando o bom e velho gpupdate, de preferência centralmente.

Passo 4

Vamos preparar o seguinte script PS para “gestores”:

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 facilitar a execução do script PS, criaremos um shell para ele na forma de um arquivo cmd com o mesmo nome do script PS:

RDSManagement.cmd

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

Colocamos os dois arquivos em uma pasta que ficará acessível aos “gestores” e solicitamos que eles façam login novamente. Agora, ao executar o arquivo cmd, eles poderão se conectar às sessões de outros usuários no modo RDS Shadow e forçá-los a sair (isso pode ser útil quando o usuário não consegue encerrar independentemente uma sessão “travada”).

Parece algo como isto:

Para o "gerente"Delegando o gerenciamento de sessões RDP

Para o usuárioDelegando o gerenciamento de sessões RDP

Alguns comentários finais

Nuance 1. Se a sessão do usuário sobre a qual estamos tentando obter controle foi iniciada antes da execução do script Set-RDSPermissions.ps1 no servidor, o “gerente” receberá um erro de acesso. A solução aqui é óbvia: espere até que o usuário gerenciado faça login.

Nuance 2. Após vários dias trabalhando com RDP Shadow, notamos um bug ou recurso interessante: após o término da sessão shadow, a barra de idiomas na bandeja desaparece para o usuário que está conectado e, para recuperá-la, o usuário precisa voltar -Conecte-se. Acontece que não estamos sozinhos: tempo, два, três.

Isso é tudo. Desejo a você e aos seus servidores boa saúde. Como sempre, aguardo seus comentários nos comentários e peço que você responda à breve pesquisa abaixo.

fontes

Apenas usuários registrados podem participar da pesquisa. Entrarpor favor

O que você usa?

  • 8,1%Administrador AMMYY5

  • 17,7%AnyDesk11

  • 9,7%DameWare6

  • 24,2%Radmin15

  • 14,5%Sombra RDS9

  • 1,6%Assistência Rápida/Assistência Remota do Windows1

  • 38,7%TeamViewer24

  • 32,3%VNC20

  • 32,3%outros20

  • 3,2%LiteManager2

62 usuários votaram. 22 usuários se abstiveram.

Fonte: habr.com

Adicionar um comentário