Beheer van RDP-sessies delegeren

Beheer van RDP-sessies delegeren
In de organisatie waar ik werk is werken op afstand in principe verboden. Was. Tot vorige week. Nu moest ik dringend een oplossing implementeren. Van business - aanpassing van processen naar een nieuwe werkvorm, van ons - PKI met pincodes en tokens, VPN, gedetailleerde logging en nog veel meer.
Ik was onder andere betrokken bij het opzetten van Remote Desktop Infrastructure oftewel Terminal Services. We hebben verschillende RDS-implementaties in verschillende datacenters. Een van de doelen was om collega's van gerelateerde IT-afdelingen interactief te laten aansluiten op gebruikerssessies. Zoals u weet, is hiervoor een regulier RDS-schaduwmechanisme en de eenvoudigste manier om dit te delegeren, is door lokale beheerdersrechten op RDS-servers te geven.
Ik respecteer en waardeer mijn collega's, maar ik ben erg hebzuchtig voor het verdelen van admin-rechten. 🙂 Degenen die het met mij eens zijn, graag onder cat.

Welnu, de taak is nu duidelijk - voor zaken.

Stap 1

Maak een beveiligingsgroep aan in Active Directory RDP_Operators en neem daarin de accounts op van die gebruikers aan wie we rechten willen delegeren:

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

Als u meerdere AD-sites heeft, moet u, voordat u verder gaat met de volgende stap, wachten totdat deze is gerepliceerd naar alle domeincontrollers. Dit duurt meestal niet langer dan 15 minuten.

Stap 2

Laten we de groep de rechten geven om terminalsessies op elk van de RDSH-servers te beheren:

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")
        }
    }
}

Stap 3

Voeg een groep toe aan een lokale groep Remote Desktop-gebruikers op elk van de RDSH-servers. Als uw servers worden gecombineerd tot verzamelingen van sessies, dan doen we dit op verzamelingsniveau:

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

Gebruik voor enkele servers Groepsbeleid, wachtend tot het op de servers wordt toegepast. Voor degenen die te lui zijn om te wachten, kunt u het proces bij voorkeur forceren met de goede oude gpupdate centraal.

Stap 4

Laten we het volgende PS-script voorbereiden voor "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 "    сессий не найдено"
    }
}

Om het gemakkelijk te maken om het PS-script uit te voeren, maken we er een shell voor in de vorm van een cmd-bestand met dezelfde naam als het PS-script:

RDSManagement.cmd

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

We plaatsen beide bestanden in een map die beschikbaar is voor de "managers" en vragen hen om opnieuw in te loggen. Door nu het cmd-bestand uit te voeren, kunnen ze verbinding maken met de sessies van andere gebruikers in de RDS-schaduwmodus en hen dwingen uit te loggen (dit is handig wanneer de gebruiker de "vastgelopen" sessie niet zelf kan beëindigen).

Het ziet er ongeveer zo uit:

Voor "beheerder"Beheer van RDP-sessies delegeren

Voor de gebruikerBeheer van RDP-sessies delegeren

Een paar laatste opmerkingen

Nuance 1. Als de sessie van de gebruiker waarover we controle proberen te krijgen, is gestart voordat het script Set-RDSPermissions.ps1 op de server is uitgevoerd, krijgt de "manager" een toegangsfout. De oplossing hier ligt voor de hand: wacht tot de beheerde gebruiker opnieuw inlogt.

Nuance 2. Na een aantal dagen met RDP Shadow te hebben gewerkt, merkten ze een interessante bug of een functie op: na het einde van de schaduwsessie verdwijnt de gebruiker waarmee ze verbinding hebben gemaakt de taalbalk in de lade, en om terug te keren, de gebruiker moet opnieuw inloggen. Het blijkt dat we niet de enige zijn: tijd, два, drie.

Dat is alles. Ik wens gezondheid voor u en uw servers. Zoals altijd kijk ik uit naar je feedback in de reacties en vraag ik je om hieronder een korte enquête in te vullen.

bronnen

Alleen geregistreerde gebruikers kunnen deelnemen aan het onderzoek. Inloggen, Alsjeblieft.

Wat gebruik je?

  • 8,1%AMMYY-beheerder5

  • 17,7%AnyDesk11

  • 9,7%DameWare6

  • 24,2%Radmin15

  • 14,5%RDS-schaduw9

  • 1,6%Quick Assist / Windows Hulp op afstand1

  • 38,7%TeamViewer24

  • 32,3%VNC20

  • 32,3%andere20

  • 3,2%LiteManager2

62 gebruikers hebben gestemd. 22 gebruikers onthielden zich van stemming.

Bron: www.habr.com

Voeg een reactie