Dienstprogramm für menschliche Shadow-Verbindungen von Nicht-Administratoren zu RDP-Sitzungen von Benutzern in WinServer 2012R2

Das Problem während der Quarantänezeit des Unternehmens war folgendes: Es ist wirklich notwendig, die Anzahl der Besuche in den Büros der Fachleute, die Beratungen zum Anwendungssoftware anbieten, zu minimieren. Außerdem müssen wir ehrlich sagen, dass die Benutzer oft die Hilfe der Fachleute ausnutzen, ohne sich mit den Fragen wirklich auseinanderzusetzen, sie denken: "Sie kommen — helfen — machen, und ich kann währenddessen eine rauchen oder einen Kaffee trinken." Eine telefonische Beratung beim gemeinsamen Zugriff auf den Server ist effektiver, wenn der Remote-Bildschirm angesehen wird.

Dienstprogramm für menschliche Shadow-Verbindungen von Nicht-Administratoren zu RDP-Sitzungen von Benutzern in WinServer 2012R2

Bereits nach der "Erfindung" unseres Rades erschien sinnvolle Information zu dem Thema des Artikels: RDS Shadow – Schattenverbindung zu RDP-Sitzungen von Benutzern in Windows Server 2012 R2 oder Der Schattenmodus des nicht privilegierten Benutzers in Windows-Server oder Betrieb von RDP-Sitzungen delegieren. Sie alle setzen die Nutzung der Konsole voraus, sogar mit Elementen eines einfachen Dialogs.

Alle unten aufgeführten Informationen sind für diejenigen gedacht, die normalerweise mit abnormalen Abweichungen umgehen können um das gewünschte Ergebnis zu erzielen, indem sie unnötige Methoden erfinden.
Um "nicht den Kater am Schwanz zu ziehen", beginne ich mit dem Letzten: Das Fahrrad funktioniert beim normalen Benutzer mit Hilfe des Dienstprogramms AdmiLink, dafür ein Dankeschön an den Autor.

I. Konsole und Shadow RDP.

Da die Nutzung der Konsole des Servermanagers mit administrativen Rechten -> QuickSessionCollection -> durch Klicken auf die Sitzung des gewünschten Benutzers und Auswahl von Shadow (Schattenkopie) für das Personal, das in der Nutzung der Software anweist, war keine Option, daher wurde eine andere "holprige" Methode in Betracht gezogen:

1. Wir erfahren die RDP-Sitzungs-ID:

query user | findstr Administrator

oder:

qwinsta | findstr Administrator 

Dabei war "| findstr Administrator" nur praktisch, wenn man weiß, dass genau das Administrator benötigt wird oder man nur den ersten Teil nutzt, um alle eingeloggten Benutzer auf dem Server zu sehen.

Dienstprogramm für menschliche Shadow-Verbindungen von Nicht-Administratoren zu RDP-Sitzungen von Benutzern in WinServer 2012R2

2. Wir verbinden uns mit dieser Sitzung, vorausgesetzt in den Domänen- Gruppenrichtlinien ist die Einstellung "Legt die Regeln für die Remoteverwaltung der Benutzersitzungen des Remote Desktop Services fest" mindestens auf "Überwachung der Sitzung mit Genehmigung des Benutzers" eingestellt (mehr Details):

mstsc /shadow:127

Bitte beachten Sie, dass in der Liste nur Benutzeranmeldungen angezeigt werden.

Ich wiederhole, dass Sie ohne administrative Rechte folgendes erhalten werden:

Dienstprogramm für menschliche Shadow-Verbindungen von Nicht-Administratoren zu RDP-Sitzungen von Benutzern in WinServer 2012R2

Für die vorläufige Fehlersuche des zu behandelnden Programms habe ich ein Konto mit Administratorrechten verwendet.

II. Programm

Die Aufgabenstellung lautet: Erstellung einer einfachen grafischen Oberfläche zur Verbindung mit dem Shadow-Sensor des Benutzers mit dessen Zustimmung und zum Versenden einer Nachricht an den Benutzer. Die Programmierumgebung wurde auf Lazarus gewählt.

1. Erhalten Sie die vollständige Domänenliste der Benutzer "Login" - "Vollständiger Name" vom Administrator oder erneut über die Konsole:

wmic useraccount get Name,FullName 

Niemand hindert Sie daran, es auch so zu tun:

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

Ich möchte gleich sagen, dass Lazarus Probleme bei der Verarbeitung dieser Datei hatte, da sie standardmäßig in der Kodierung UCS-2 vorliegt. Daher musste sie manuell in das gängige UTF-8 umgewandelt werden. Die Struktur der Datei enthält viele Tabulatoren, genauer gesagt viele Leerzeichen, die beschlossen wurden, trotzdem programmgesteuert zu verarbeiten. Früher oder später wird das Problem mit der Kodierung gelöst, und die Datei wird programmgesteuert aktualisiert.

Die Idee ist, einen Ordner zur Verfügung zu stellen, der für die Benutzer des Programms zugänglich ist, z.B. c:test, in dem sich zwei Dateien befinden: die erste mit Login und Vollständigem Namen, die zweite mit ID_RDP und Login der Benutzer. Diese Daten werden dann bearbeitet, wie wir können:).

Um es mit der Sitzungsliste zu verknüpfen, übertragen wir den Inhalt (Login und Vollständiger Name) in ein Array:

procedure Tf_rdp.UserF2Array;
var 
  F:TextFile;   i:integer;   f1, line1:String;   fL: TStringList;
begin //f_d globaler Pfad zur Ablage der Dateien 
f1:=f_d+'user_name.txt';     // Aufgabe besteht darin, den Inhalt der Datei in ein Array zu lesen
fL := TStringList.Create; // die Zeile wird Metamorphosen mit Trennzeichen unterzogen
fL.Delimiter := '|'; fL.StrictDelimiter := True;
AssignFile(F,f1); 
try // Datei zum Lesen öffnen
  reset(F); ReadLn(F,line1);
  i:=0;
while not eof(F) do // Zeilen lesen, bis das Ende der Datei erreicht ist
begin
ReadLn(F,line1);
line1:= StringReplace(line1, '  ', '|',[]); // ersetzt das erste gefundene Doppelleerzeichen mit dem Trennzeichen |
// entfernt alle doppelten Leerzeichen
while pos('  ',line1)>0 do line1:= StringReplace(line1, '  ', ' ', [rfReplaceAll]);
begin
if (pos('|',line1)>0) then
begin // wenn das Trennzeichen existiert, fügen Sie es in das Array ein
fL.DelimitedText :=line1; // zerlegen in Spalten
if (fL[0]'' ) then // wenn das Konto einen Namen hat
begin // fügt es in das Array ein
 inc(i); // entfernt mögliche einzelne Leerzeichen im Login
 fam[0,i]:=StringReplace(fL[1],' ','',[rfReplaceall, rfIgnoreCase]);
 fam[1,i]:=fL[0];
 end;end;end;end; // Fertig. Datei schließen.
 CloseFile(F);
 Fl.Free;
 except
 on E: EInOutError do  ShowMessage('Fehler bei der Verarbeitung der Datei. Details: '+E.Message);
 end;end;

Ich bitte um Entschuldigung für den "vielen Code", die nächsten Punkte werden prägnanter sein.

2. Entsprechend der Methode aus dem vorherigen Punkt lesen wir das Ergebnis der Verarbeitung der Liste in das Element StringGrid ein, dabei bringe ich einen "bedeutenden" Code-Ausschnitt:

2.1 Wir erhalten die aktuelle Liste der RDP-Sitzungen in eine Datei:

f1:=f_d+'user.txt';
cmdline:='\/c query user >'+ f1;
if ShellExecute(0,nil, PChar('cmd'),PChar(cmdline),nil,1)=0 then;
Sleep(500); \/\/ man kann auch länger warten, während die Datei zur Lesung erstellt wird

2.2 Wir verarbeiten die Datei (es werden nur wesentliche Codezeilen angegeben):

StringGrid1.Cells[0,i]:=fL[1]; StringGrid1.Cells[2,i]:=fL[3]; \/\/ wir fügen in der Schleife in StringGrid1 ein
login1:=StringReplace(fL[1],' ','',[rfReplaceall, rfIgnoreCase]); \/\/ wir entfernen Leerzeichen aus dem Login
if (SearchArr(login1)>=0) then \/\/ wir suchen im Array aus P1. das Login und schreiben es in die Tabelle FIO
StringGrid1.Cells[1,i]:=fam[1,SearchArr(login1)]
else StringGrid1.Cells[1,i]:='+'; \/\/ oder wir schreiben ein Pluszeichen:)
.... \/\/ je nach Wahl des Nutzers sortieren und formatieren wir die Daten
if (b_id.Checked=true) then SortGrid(0) else SortGrid(1);
StringGrid1.AutoSizeColumn(0);StringGrid1.AutoSizeColumn(1); StringGrid1.AutoSizeColumn(2);  

3. Direkt die Verbindung bei einem Klick auf die Zeile mit dem Nutzer und der Nummer seiner Sitzung:

  id:=(StringGrid1.Row);\/\/ wir erfahren die Zeilennummer  IntToStr(StringGrid1.Row)
  ids:=StringGrid1.Cells[2,id]; \/\/ wir erhalten die RDP-ID
  cmdline:='\/c mstsc \/shadow:'+ ids; \/\/ und verbinden uns....
 if (b_rdp.Checked=True) then  if ShellExecute(0,nil, PChar('cmd'),PChar(cmdline),nil,1) =0 then;       

4. Es sind noch ein paar Verschönerungen wie die Sortierung durch einen Klick auf den Radiobutton und Nachrichten an den Nutzer oder alle Nutzer gemacht worden.

Dienstprogramm für menschliche Shadow-Verbindungen von Nicht-Administratoren zu RDP-Sitzungen von Benutzern in WinServer 2012R2

→ Den vollständigen Quellcode kann man sehen hier

III. Anwendung von AdminLink – was ich gesehen habe:

AdminLink generiert tatsächlich eine Verknüpfung, die auf den Speicherort des Tools verweist admilaunch.exe, und einer persönlichen Kopie des Starttools AdmiRun.Exe , die sich im Benutzerordner befindet, zum Beispiel vasya, entsprechend C:UsersvasyaWINDOWS. Im Großen und Ganzen ist nicht alles so schlecht: Mit dem Zugriffsrecht auf die Datei der Verknüpfung und anderen Aspekten kann man zum eigenen administischen Gewissen spielen.

Quelle: habr.com

60GB SSD 8Gb DDR4