Déléguer la gestion des sessions RDP

Déléguer la gestion des sessions RDP
Dans l'organisation où je travaille, le travail à distance est en principe interdit. Était. Jusqu'à la semaine dernière. Maintenant, je devais mettre en œuvre de toute urgence une solution. De l'entreprise - adaptation des processus à un nouveau format de travail, de nous - PKI avec codes PIN et jetons, VPN, journalisation détaillée et bien plus encore.
Entre autres choses, j'ai été impliqué dans la mise en place de l'infrastructure de bureau à distance alias Terminal Services. Nous avons plusieurs déploiements RDS dans différents centres de données. L'un des objectifs était de permettre aux collègues des services informatiques concernés de se connecter de manière interactive aux sessions utilisateur. Comme vous le savez, il existe un mécanisme RDS Shadow régulier pour cela et le moyen le plus simple de le déléguer est de donner des droits d'administrateur local sur les serveurs RDS.
Je respecte et apprécie mes collègues, mais je suis très gourmand pour la distribution des droits d'administration. 🙂 Ceux qui sont d'accord avec moi, merci sous chat.

Eh bien, la tâche est claire, maintenant - pour les entreprises.

Étape 1

Créer un groupe de sécurité dans Active Directory RDP_Opérateurs et y inclure les comptes des utilisateurs auxquels nous voulons déléguer des droits :

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

Si vous avez plusieurs sites AD, avant de passer à l'étape suivante, vous devez attendre qu'il soit répliqué sur tous les contrôleurs de domaine. Cela ne prend généralement pas plus de 15 minutes.

Étape 2

Donnons au groupe le droit de gérer les sessions terminal sur chacun des serveurs 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")
        }
    }
}

Étape 3

Ajouter un groupe à un groupe local Utilisateurs de bureau à distance sur chacun des serveurs RDSH. Si vos serveurs sont combinés en collections de sessions, nous le faisons au niveau de la collection :

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

Pour les serveurs uniques, utilisez stratégie de groupe, en attendant qu'il soit appliqué sur les serveurs. Pour ceux qui ont la flemme d'attendre, vous pouvez forcer le processus avec le bon vieux gpupdate, de préférence au centre.

Étape 4

Préparons le script PS suivant pour les "managers":

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

Pour faciliter l'exécution du script PS, nous allons lui créer un shell sous la forme d'un fichier cmd portant le même nom que le script PS :

RDSManagement.cmd

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

Nous mettons les deux fichiers dans un dossier qui sera disponible pour les "gestionnaires" et leur demandons de se reconnecter. Désormais, en exécutant le fichier cmd, ils pourront se connecter aux sessions des autres utilisateurs en mode RDS Shadow et les forcer à se déconnecter (c'est utile lorsque l'utilisateur ne peut pas mettre fin à la session "accrochée" par lui-même).

Cela ressemble à ceci:

Pour "gestionnaire"Déléguer la gestion des sessions RDP

Pour l'utilisateurDéléguer la gestion des sessions RDP

Quelques dernières remarques

Nuance 1. Si la session de l'utilisateur à laquelle nous essayons de prendre le contrôle a été démarrée avant l'exécution du script Set-RDSPermissions.ps1 sur le serveur, alors le "gestionnaire" recevra une erreur d'accès. La solution ici est évidente : attendez que l'utilisateur géré se reconnecte.

Nuance 2. Après plusieurs jours de travail avec RDP Shadow, ils ont remarqué un bogue ou une fonctionnalité intéressante : après la fin de la session shadow, l'utilisateur auquel ils se sont connectés fait disparaître la barre de langue dans la barre d'état système, et pour la retourner, le l'utilisateur doit se reconnecter. Il s'avère que nous ne sommes pas seuls : temps, два, trois.

C'est tout. Je vous souhaite la santé ainsi qu'à vos serveurs. Comme toujours, j'attends avec impatience vos commentaires dans les commentaires et vous demande de répondre à un court sondage ci-dessous.

sources

Seuls les utilisateurs enregistrés peuvent participer à l'enquête. se connecters'il te plait.

Qu'est ce que tu utilises?

  • 8,1%Administrateur AMMYY5

  • 17,7%N'importe quel bureau11

  • 9,7%DameWare6

  • 24,2%Radmin15

  • 14,5%RDS Shadow9

  • 1,6%Assistance rapide / Assistance à distance Windows1

  • 38,7%TeamViewer24

  • 32,3%VNC20

  • 32,3%autre20

  • 3,2%LiteManager2

62 utilisateurs ont voté. 22 utilisateurs se sont abstenus.

Source: habr.com

Ajouter un commentaire