Het probleem tijdens de quarantainetijden van bedrijven bleek het volgende: het is echt noodzakelijk om het aantal bezoeken aan specialistische ruimtes te minimaliseren, vooral omdat gebruikers vaak misbruik maken van de hulp van specialisten zonder zich echt in de kwestie te willen verdiepen, met de gedachte: 'ze komen wel ā helpen ā maken het in orde, en ik rook ondertussen/ drink koffie, etc.'. Telefonische consultatie met gezamenlijke toegang tot de server is effectiever als je het externe scherm bekijkt.

Kort na de 'uitvinding' van onze fiets kwam er zinvolle informatie over het onderwerp van het artikel: of of . Al deze oplossingen impliceren het gebruik van de console, zelfs met elementaire dialogen.
Alle onderstaande informatie is bedoeld voor degenen die normaal omgaan met ongewone afwijkingen om het gewenste resultaat te behalen door onnodige methoden uit te vinden.
Om 'de kat niet langer bij de staart te trekken', begin ik met het laatste: de fiets werkt voor de gewone gebruiker met behulp van het hulpprogramma , waarvoor de auteur mijn dank heeft.
I. Console en shadow RDP.
Aangezien het gebruik van de Server Manager-console met beheerdersrechten -> QuickSessionCollection -> door te klikken op de sessie van de betreffende gebruiker en in het contextmenu Shadow (Schaduwkopie) te selecteren voor personeel dat instructies geeft over het gebruik van de software, ā is geen optie, er werd een andere 'houten' methode overwogen, namelijk:
1. Bepaal het RDP ID van de sessie:
query user | findstr Administratorof:
qwinsta | findstr Administrator Het "| findstr Administrator" was handig wanneer je weet wat je precies nodig hebt, of gebruik alleen het eerste deel om alle ingelogde gebruikers op de server te bekijken. Administrator 2. Maak verbinding met deze sessie, op voorwaarde dat in de domein
![]()
groepsbeleid de parameter 'Stelt regels voor externe toegang voor gebruikerssessies van de Remote Desktop Services in' is ingesteld op ten minste 'Toezicht houden op de sessie met toestemming van de gebruiker' ( mstsc /shadow:127):
Let op dat in de lijst alleen de inloggegevens van de gebruikers zullen verschijnen.Let op dat er in de lijst alleen de gebruikersnamen zullen staan.
Ik herhaal dat je zonder beheerdersrechten het volgende zult krijgen:

Maar voor de voorlopige debug van het programma waar we het over gaan hebben, heb ik een account met beheerdersrechten gebruikt.
II. Programma
Dus de taakstelling: het creƫren van een eenvoudige grafische interface voor het verbinden met de schaduwzin van de gebruiker met zijn toestemming, het verzenden van een bericht naar de gebruiker. De programmeeromgeving is gekozen: Lazarus.
1. We krijgen een volledige domeinlijst van gebruikers "inlog" ā "volledige naam" van de admin, of opnieuw via de console:
wmic useraccount get Name,FullName niemand verhindert zelfs dit:
wmic useraccount get Name,FullName > c:testusername.txtIk moet onmiddellijk zeggen dat er juist bij Lazarus een probleem was met de verwerking van dit bestand, omdat zijn standaardcodering UCS-2 is, dus het moest handmatig worden omgezet naar gewone UTF-8. In de structuur van het bestand zijn er veel tabulaties, of beter gezegd, veel spaties die we toch programmatisch hebben besloten te verwerken, vroeg of laat zal de encodingprobleem worden opgelost en het bestand zal programmatisch worden bijgewerkt.
Dus, in de opzet is er een map, toegankelijk voor gebruikers van het programma, bijvoorbeeld c:test, waarin 2 bestanden zullen zijn: de eerste met login en volledige naam, de tweede met id_rdp en login van de gebruikers. Vervolgens verwerken we deze gegevens zoals we kunnen:).
En tot die tijd, om te associƫren met de sessielijst, voegen we deze (login en volledige naam) inhoud toe aan een array:
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('Fout bij de verwerking van het bestand. Details: '+E.Message);
end;
end;Mijn excuses voor de "veel code"; de volgende punten zullen bondiger zijn.
2. Op dezelfde manier lezen we de verwerkingsresultaten van de lijst in het StringGrid- element, en hierbij geef ik een "significant" stuk code:
2.1 We krijgen de actuele lijst van RDP-sessies in een bestand:
f1:=f_d+'user.txt';
cmdline:='\/c query user >'+ f1;
if ShellExecute(0,nil, PChar('cmd'),PChar(cmdline),nil,1)=0 then;
Sleep(500); \/\/ je kunt ook langer wachten totdat het bestand voor lezen wordt aangemaakt2.2 We verwerken het bestand (alleen significante regels code zijn aangegeven):
StringGrid1.Cells[0,i]:=fL[1]; StringGrid1.Cells[2,i]:=fL[3]; \/\/ we voegen dit in een lus toe aan StringGrid1
login1:=StringReplace(fL[1],' ','',[rfReplaceall, rfIgnoreCase]); \/\/ spaties uit de login verwijderen
if (SearchArr(login1)>=0) then \/\/ zoeken in de array van punt 1. login en opslaan in de tabel FIO
StringGrid1.Cells[1,i]:=fam[1,SearchArr(login1)]
else StringGrid1.Cells[1,i]:='+'; \/\/ of we zetten een plusteken:
.... \/\/ afhankelijk van de keuze van de gebruiker sorteren en formatteren op basis van de gegevens
if (b_id.Checked=true) then SortGrid(0) else SortGrid(1);
StringGrid1.AutoSizeColumn(0);StringGrid1.AutoSizeColumn(1); StringGrid1.AutoSizeColumn(2); 3. Het eigenlijke verbinding maken bij klikken op de rij met de gebruiker en het nummer van zijn sessie:
id:=(StringGrid1.Row);\/\/ we krijgen het rijnummer IntToStr(StringGrid1.Row)
ids:=StringGrid1.Cells[2,id]; \/\/ we krijgen de identificatie van de rdp
cmdline:='\/c mstsc \/shadow:'+ ids; \/\/ en we verbinden....
if (b_rdp.Checked=True) then if ShellExecute(0,nil, PChar('cmd'),PChar(cmdline),nil,1) =0 then; 4. Er zijn nog een paar versieringen gemaakt, zoals sorteren op klik op de radioknop, en berichten voor de gebruiker, of voor alle gebruikers.

ā De volledige broncode is beschikbaar
III. Gebruik van AdminLink ā wat ik heb gezien:
AdminLink genereert inderdaad een snelkoppeling die verwijst naar de locatie van de tool admilaunch.exe, en een persoonlijke kopie van de uitvoertool AdmiRun.Exe die zich in de gebruikersmap bevindt, bijvoorbeeld vasya, zoals C:UsersvasyaWINDOWS. Over het geheel genomen, het is niet zo slecht: met toegangsrechten tot het snelkoppelingbestand en andere, voor het zuiveren van zijn eigen admin-geweten, kan men spelen.
Bron: habr.com
