Утилита за нормално shadow свързване на неадмин до RDP сесии на потребители в WinServer 2012R2

Проблемата по време на карантинната работа на предприятието стана следната: наистина е нужно да се минимизира броят на посещенията в кабинетите на специалистите, които обслужват и консултират по приложен софтуер, и да го кажем откровено, потребителите често злоупотребяват с помощта на специалисти, без да искат да се запознаят с въпроса, тъй като "ще дойдат — ще помогнат — ще направят, а аз докато пуша/пия кафе и т.н.". Консултацията по телефона при съвместен достъп до сървъра е по-ефективна, ако се преглежда отдалеченият екран.

Утилита за нормално shadow свързване на неадмин до RDP сесии на потребители в WinServer 2012R2

Вече след "изобретяването" на нашия велосипед се появи разумна информация по темата на статията: RDS Shadow – тенева свързаност към RDP сесиите на потребителите в Windows Server 2012 R2 или Режимът на shadow за неправа потребител в Windows Server или Делегираме управлението на RDP сесии. Всички те предвиждат използване на конзолата, дори с елементи на прост диалог.

Всичката изложена по-долу информация е предназначена за онези, които нормално понасят ненормалните извращения за постигане на желания резултат, изобретявайки ненужни начини.
За да "не дърпам котката за опашката", ще започна с последното: велосипедът работи при обикновения потребител чрез утилитата AdmiLink, за което на автора й благодаря.

I. Конзола и shadow RDP.

Тъй като използването с административни права на конзолата Server Manager -> QuickSessionCollection -> щраквайки върху сесията на интересуващия потребител, избирайки в контекстното меню Shadow (Тенева копие) за персонала, който инструктира по работа с ПО, — не е вариант, беше разгледан друг "дървен" начин, а именно:

1. Научаваме RDP id на сесията:

query user | findstr Administrator

или:

qwinsta | findstr Administrator 

При това "| findstr Administrator" беше удобно само когато знаеш, какво точно Administrator търсиш, или да използваш само първата част, за да видиш всички, които са влезли на сървера.

Утилита за нормално shadow свързване на неадмин до RDP сесии на потребители в WinServer 2012R2

2. Свързваме се с тази сесия, при условие че в доменните групови политики параметърът "Установява правила за отдалечено управление на потребителските сесии на услуги за отдалечен работен плот" е избран най-малко като "Наблюдение на сесия с разрешение от потребителя" (по-подробно):

mstsc /shadow:127

Моля, обърнете внимание, че в списъка ще бъдат само логините на потребителите.

Повтарям, че без административни права ще получите следното:

Утилита за нормално shadow свързване на неадмин до RDP сесии на потребители в WinServer 2012R2

Но за предварителното отстраняване на грешки в програмата, за която ще става дума, използвах акаунт с права на администратор.

II. Програма

И така, задачата е: създаване на прост графичен интерфейс за свързване с обект на потребителя с негово съгласие, изпращане на съобщение на потребителя. Средата за програмиране е избрана Lazarus.

1. Получаваме пълен списък с домейни на потребители "логин" — "пълно име" от администратора, или чрез конзолата:

wmic useraccount get Name,FullName 

никой не забранява дори така:

wmic useraccount get Name,FullName > c:testusername.txt

Искам да кажа, че именно в Lazarus имаше проблем с обработката на този файл, тъй като по подразбиране неговото кодиране е UCS-2, затова се наложи да го преобразувам ръчно в обикновен UTF-8. В структурата на файла има много табулации, по-скоро множество интервали, които решихме да обработим програмно; рано или късно задачата с кодировката ще бъде решена и файлът ще се обновява програмно.

И така, в замисъла папката, достъпна за потребителите на програмата, например c:test, в която ще има 2 файла: първият с login и fullname, вторият с id_rdp и login на потребителите. След това тези данни обработваме, каквото можем:).

А за момента, за асоцииране със списъка със сесии, прехвърляме това (login и fullname) съдържание в масив:

procedure Tf_rdp.UserF2Array;
var 
  F:TextFile;   i:integer;   f1, line1:String;   fL: TStringList;
begin  
f1:=f_d+'user_name.txt';     
 fL := TStringList.Create; 
 fL.Delimiter := '|'; fL.StrictDelimiter := True;
AssignFile(F,f1); 
try 
  reset(F); ReadLn(F,line1);
  i:=0;
while not eof(F) do 
begin
ReadLn(F,line1);
line1:= StringReplace(line1, '  ', '|',[]);
while pos('  ',line1)>0 do line1:= StringReplace(line1, '  ', ' ', [rfReplaceAll]);
begin
if (pos('|',line1)>0) then
begin 
fL.DelimitedText :=line1; 
if (fL[0]'' ) then 
begin 
 inc(i); 
fam[0,i]:=StringReplace(fL[1],' ','',[rfReplaceall, rfIgnoreCase]);
 fam[1,i]:=fL[0];
 end;end;end;end; 
 CloseFile(F);
 Fl.Free;
 except
 on E: EInOutError do  ShowMessage('Грешка при обработката на файла. Подробности: '+E.Message);
 end;end;

Искрено се извинявам за "много код", следващите точки ще бъдат по-лаконични.

2. По аналогичен метод от предишната точка се считывает резултата от обработката на списъка в елемента StringGrid, при това давам „значим“ фрагмент от кода:

2.1 Получаваме актуален списък с RDP сесии в файл:

f1:=f_d+'user.txt';
cmdline:='\/c query user >'+ f1;
if ShellExecute(0,nil, PChar('cmd'),PChar(cmdline),nil,1)=0 then;
Sleep(500); \/\/ може и по-дълго, за да изчакате създаването на файла за четене

2.2 Обработваме файла (указани са само значимите редове от кода):

StringGrid1.Cells[0,i]:=fL[1]; StringGrid1.Cells[2,i]:=fL[3]; \/\/ добавяме в цикъл в StringGrid1
login1:=StringReplace(fL[1],' ','',[rfReplaceall, rfIgnoreCase]); \/\/ премахваме интервалите от логина
if (SearchArr(login1)>=0) then \/\/ търсим в масива от п1. логина и записваме в таблицата ФИО
StringGrid1.Cells[1,i]:=fam[1,SearchArr(login1)]
else StringGrid1.Cells[1,i]:='+'; \/\/ или записваме плюсче:)
.... \/\/ в зависимост от избора на потребителя сортираме и форматираме по данни
if (b_id.Checked=true) then SortGrid(0) else SortGrid(1);
StringGrid1.AutoSizeColumn(0);StringGrid1.AutoSizeColumn(1); StringGrid1.AutoSizeColumn(2);  

3. Непосредствено самото свързване при клик върху реда с потребителя и номера на неговата сесия:

  id:=(StringGrid1.Row);\/\/ разбираме номера на реда IntToStr(StringGrid1.Row)
  ids:=StringGrid1.Cells[2,id]; \/\/ получаваме идентификатора на rdp
  cmdline:='\/c mstsc \/shadow:'+ ids; \/\/ и се свързваме....
 if (b_rdp.Checked=True) then  if ShellExecute(0,nil, PChar('cmd'),PChar(cmdline),nil,1) =0 then;       

4. Направени са още няколко украшения като сортиране при клик върху radiobutton, и съобщения на потребителя, или на всички потребители.

Утилита за нормално shadow свързване на неадмин до RDP сесии на потребители в WinServer 2012R2

→ Пълният изходен код може да се види тук.

III. Приложение на AdminLink — какво видях:

AdminLink наистина генерира пряк път, в който сочи към местоположението на инструмента admilaunch.exe, и лична копия на инструмента за стартиране AdmiRun.Exe която се намира в папката на потребителя, например vasya, по подобие на C:UsersvasyaWINDOWS. Общо взето, не всичко е толкова лошо: с правата за достъп до файла на пряк път и други, за да се освободи собствената административна съвест, може да се поиграе.

Източник: habr.com

Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри 🔥 Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри | ProHoster