U organizaciji u kojoj radim, rad od kuće je u osnovi bio zabranjen. Bio je. Do prošlog tjedna. Sada je bilo potrebno hitno implementirati rješenje. Od posla — prilagodba procesa novom radnom formatu, od nas — PKI s PIN kodovima i tokenima, VPN, detaljno logiranje i mnogo toga još.
Osim svega, bavio sam se konfiguracijom infrastrukture daljinskih radnih površina, aka terminalske usluge. Imamo nekoliko RDS implementacija u različitim podatkovnim centrima. Jedan od zadataka bio je omogućiti kolegama iz susjednih IT odjela da se povežu na korisničke sesije u interaktivnom modu. Kao što je poznato, za ovo postoji ugrađeni mehanizam RDS Shadow, a najjednostavniji način za delegiranje prava je dati ovlasti lokalnog administratora na RDS poslužiteljima.
Cijenim svoje kolege, ali vrlo sam škrt na dodjeli administratorskih prava. 🙂 One koji se slažu sa mnom, pozivam pod kat.
Pa, zadatak je jasan, sada — na posao.
Korak 1
Stvorimo sigurnosnu grupu u Active Directory-ju RDP_Operators i uključimo račune onih korisnika kojima želimo delegirati prava:
$Users = @(
"UserLogin1",
"UserLogin2",
"UserLogin3"
)
$Group = "RDP_Operators"
New-ADGroup -Name $Group -GroupCategory Security -GroupScope DomainLocal
Add-ADGroupMember -Identity $Group -Members $Users
Ako imate više AD lokacija, prije nego što pređete na sljedeći korak, trebate pričekati da se replicira na sve kontrolere domene. Obično to traje ne više od 15 minuta.
Korak 2
Dajmo grupi prava za upravljanje terminalskim sesijama na svakom od RDSH poslužitelja:
Set-RDSPermissions.ps1
$Group = "RDP_Operators"
$Servers = @(
"RDSHost01",
"RDSHost02",
"RDSHost03"
)
ForEach ($Server in $Servers) {
# Delegiramo pravo na sjenovite sesije
$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 = "uspješno"
If ($retVal.ReturnValue -ne 0) {
$opstatus = "greška"
}
Write-Host ("Delegiranje prava na sjenovito povezivanje grupi " +
$Group + " na poslužitelju " + $Server + ": " + $opstatus + "`r`n")
}
}
}
Korak 3
Dodajmo grupu u lokalnu grupu Korisnici daljinskih radnih površina na svakom od RDSH poslužitelja. Ako su vaši poslužitelji povezani u kolekcijama sesija, to činimo na razini kolekcije:
$Group = "RDP_Operators"
$CollectionName = "MyRDSCollection"
[String[]]$CurrentCollectionGroups = @(Get-RDSessionCollectionConfiguration -CollectionName $CollectionName -UserGroup).UserGroup
Set-RDSessionCollectionConfiguration -CollectionName $CollectionName -UserGroup ($CurrentCollectionGroups + $Group)
Za pojedinačne servere koristimo , čekajući da se primijeni na serverima. Oni koji se ne žele čekati, mogu forsirati proces pomoću starog dobrog gpupdate, po mogućstvu .
Korak 4
Pripremit ćemo za 'menadžere' takav PS skript:
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 "Unesite korisničko ime"
Write-Host "Traženje RDP sesija korisnika na serverima..."
$SessionList = @()
ForEach ($Server in $Servers) {
$TargetSession = $null
Write-Host " Upit servera $Server"
Try {
$TargetSession = Get-LoggedOnUser -ComputerName $Server | Where-Object {$_.UserName -eq $UserLogin}
}
Catch {
Write-Host "Greška: " $Error[0].Exception.Message -ForegroundColor Red
Continue
}
If ($TargetSession) {
Write-Host " Pronađena sesija s ID $($TargetSession.ID) na serveru $Server" -ForegroundColor Yellow
Write-Host " Što ćemo napraviti?"
Write-Host " 1 - povezati se na sesiju"
Write-Host " 2 - završiti sesiju"
Write-Host " 0 - ništa"
$Action = Read-Host -Prompt "Unesite akciju"
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 " Sesije nisu pronađene"
}
}
Kako bi PS skripta bila lakša za pokretanje, napravit ćemo za nju okvir u obliku cmd datoteke s istim imenom kao PS skripta:
RDSManagement.cmd
@ECHO OFF
powershell -NoLogo -ExecutionPolicy Bypass -File "%~d0%~p0%~n0.ps1" %*
Stavljamo oba datoteke u mapu koja će biti dostupna «menadžerima» i tražimo od njih da se ponovo prijave. Sada, pokretanjem cmd-datoteke, oni će moći pristupiti sesijama drugih korisnika u režimu RDS Shadow i prisilno ih odjaviti (korisno kada korisnik ne može samostalno završiti «zamrznutu» sesiju).
Izgleda to otprilike ovako:
Za «menadžera»
Za korisnika
Nekoliko zapažanja na kraju
Nijansa 1. Ako je sesija korisnika, kojoj pokušavamo pristupiti, pokrenuta pre nego što je na serveru izvršen skript Set-RDSPermissions.ps1, onda će «menadžer» dobiti grešku pristupa. Rešenje je očigledno: sačekati da se upravljani korisnik ponovo prijavi.
Nijansa 2. Nakon nekoliko dana rada sa RDP Shadow primetili smo zanimljivu ili grešku ili mogućnost: nakon završetka senke sesije kod korisnika, kojem smo se povezivali, nestaje jezička traka u sistemskoj traci i da bi se vratila, korisnik treba da se ponovo prijavi. Kako se ispostavilo, nismo jedini: , , .
To je sve. Želim vam zdravlje i vašim serverima. Kao i uvek, očekujem povratne informacije u komentarima i molim vas da se obavezno prijavite na kratku anketu ispod.
Izvori
Samo registrirani korisnici mogu sudjelovati u anketi. , molimo.
Čime se koristite?
8,1%AMMYY Admin5
17,7%AnyDesk11
9,7%DameWare6
24,2%Radmin15
14,5%RDS Shadow9
1,6%Quick Assist / Windows Remote Assistance1
38,7%TeamViewer24
32,3%VNC20
32,3%drugo20
3,2%LiteManager2
Glasalo je 62 korisnika. Uzdržalo se 22 korisnika.
Izvor: habr.com
