MAK seansside haldamise delegeerimine

MAK seansside haldamise delegeerimine
Organisatsioonis, kus ma töötan, on kaugtöö põhimõtteliselt keelatud. Oli. Kuni eelmise nädalani. Nüüd tuli kiiremas korras lahendus ellu viia. Ärist – protsesside kohandamine uuele töövormingule, meilt – PIN-koodide ja žetoonidega PKI, VPN, detailne logimine ja palju muud.
Muuhulgas seadistasin kaugtöölaua infrastruktuuri ehk terminaliteenuseid. Meil on erinevates andmekeskustes mitu RDS-i juurutamist. Üks eesmärke oli võimaldada seotud IT-osakondade kolleegidel interaktiivselt kasutajaseanssidega ühenduda. Teatavasti on selleks standardne RDS Shadow mehhanism ja lihtsaim viis selle delegeerimiseks on anda RDS-serverites kohaliku administraatori õigused.
Ma austan ja hindan oma kolleege, kuid olen väga ahne, kui asi puudutab administraatoriõiguste jagamist. 🙂 Kes on minuga nõus, jälgige lõiget.

Noh, ülesanne on selge, asume nüüd asja juurde.

Samm 1

Loome Active Directorysse turvarühma RDP_Operaatorid ja lisage sellesse nende kasutajate kontod, kellele tahame õigusi delegeerida:

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

Kui teil on mitu AD-saiti, peate enne järgmise sammu juurde liikumist ootama, kuni see kopeeritakse kõigile domeenikontrolleritele. See ei kesta tavaliselt rohkem kui 15 minutit.

Samm 2

Anname rühmale õigused terminaliseansside haldamiseks igas RDSH-serveris:

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

Samm 3

Lisage rühm kohalikku gruppi Kaugtöölaua kasutajad igas RDSH-serveris. Kui teie serverid on ühendatud seansikogudeks, teeme seda kogude tasemel:

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

Kasutame üksikute serverite jaoks rühmapoliitika, oodates selle rakendamist serverites. Need, kes on ootama liiga laisad, saavad protsessi kiirendada, kasutades eelistatavalt vana head gpupdate'i tsentraalselt.

Samm 4

Valmistame ette järgmise PS-skripti "halduritele":

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

PS-skripti käitamise mugavamaks muutmiseks loome selle jaoks kesta cmd-failina, millel on sama nimi kui PS-skriptil:

RDSManagement.cmd

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

Panime mõlemad failid kausta, mis on "halduritele" juurdepääsetav, ja palume neil uuesti sisse logida. Nüüd saavad nad cmd-faili käivitades luua ühenduse teiste kasutajate seanssidega RDS Shadow režiimis ja sundida neid välja logima (see võib olla kasulik, kui kasutaja ei saa iseseisvalt rippuvat seanssi lõpetada).

See näeb välja umbes selline:

"Juhataja" jaoksMAK seansside haldamise delegeerimine

Kasutaja jaoksMAK seansside haldamise delegeerimine

Mõned viimased kommentaarid

Nüanss 1. Kui kasutajaseanss, mille üle me kontrolli püüame saada, käivitati enne, kui serveris käivitati skript Set-RDSPermissions.ps1, siis saab "haldur" juurdepääsutõrketeate. Lahendus on siin ilmne: oodake, kuni hallatav kasutaja sisse logib.

Nüanss 2. Pärast mitut päeva RDP Shadowiga töötamist märkasime huvitavat viga või funktsiooni: pärast variseansi lõppu kaob salves olev keeleriba kasutaja jaoks, kellega ühenduses on, ja selle tagasi saamiseks peab kasutaja uuesti -Logi sisse. Nagu selgub, pole me üksi: aeg, два, kolm.

See on kõik. Soovin teile ja teie teenindajatele head tervist. Nagu alati, ootan teie tagasisidet kommentaarides ja palun teil täita alljärgnev lühike küsitlus.

allikatest

Küsitluses saavad osaleda ainult registreerunud kasutajad. Logi sissepalun.

Mida sa kasutad?

  • 8,1%AMMYY Admin5

  • 17,7%AnyDesk11

  • 9,7%DameWare6

  • 24,2%Radmin15

  • 14,5%RDS-vari9

  • 1,6%Kiirabi / Windowsi kaugabi1

  • 38,7%TeamViewer24

  • 32,3%VNC20

  • 32,3%muu20

  • 3,2%LiteManager2

62 kasutajat hääletas. 22 kasutajat jäi erapooletuks.

Allikas: www.habr.com

Lisa kommentaar