الأداة المساعدة للظل البشري الذي يربط غير المسؤول بجلسات مستخدم RDP في WinServer 2012R2

كانت المشكلة خلال فترة الحجر الصحي للمؤسسة على النحو التالي: من الضروري حقًا تقليل عدد زيارات الخزانات من قبل المتخصصين الذين يقدمون الخدمات وتقديم المشورة بشأن البرامج التطبيقية ، وبصراحة ، غالبًا ما يسيء المستخدمون استخدام المتخصصين الذين لا يريدون الخوض في السؤال نفسه ، قائلين "سيأتون - سوف يساعدون ، سيفعلون ذلك ، و بينما أدخن / أشرب القهوة ، إلخ. " تعتبر الاستشارة عبر الهاتف عند مشاركة الخادم أكثر فعالية عند عرض شاشة بعيدة.



بالفعل بعد "اختراع" دراجتنا ، ظهرت معلومات عقلانية حول موضوع المقالة: اتصال RDS Shadow - shadow لجلسات مستخدم RDP في Windows Server 2012 R2 أو Shadow لمستخدم غير مميز في خادم Windows أو نقوم بتفويض إدارة جلسات RDP . جميعها تعني استخدام وحدة التحكم ، حتى مع عناصر حوار بسيط.

جميع المعلومات الواردة أدناه مخصصة لأولئك الذين يتحملون عادةً التشوهات غير الطبيعية للحصول على النتيجة المرجوة ، ويبتكرون طرقًا غير ضرورية.
لكي لا "تسحب القطة من الذيل" ، سأبدأ بالقطعة الأخيرة: تعمل الدراجة للمستخدم العادي باستخدام أداة AdmiLink ، والتي كتبها مؤلفها وشكرا لك.

I. وحدة التحكم والظل RDP.

نظرًا لأن استخدام وحدة تحكم إدارة الخادم مع حقوق المسؤول -> QuickSessionCollection -> من خلال النقر على جلسة المستخدم محل الاهتمام ، فإن تحديد الظل من قائمة السياق للموظفين الموجهين للعمل مع البرنامج ليس خيارًا ، فقد تم التفكير في طريقة "خشبية" أخرى ، وهي:

1. نتعلم معرف جلسة RDP:

query user | findstr Administrator

أو:

qwinsta | findstr Administrator 

علاوة على ذلك ، كان " | findstr Administrator " ملائمًا فقط عندما تعرف بالضبط ما تحتاجه المسؤول ، أو تستخدم الجزء الأول فقط لرؤية كل تسجيل الدخول إلى الخادم.



2. نحن متصلون بهذه الجلسة ، بشرط أن يتم تحديد المعلمة "تعيين قواعد التحكم عن بعد لجلسات المستخدم لخدمات سطح المكتب البعيد" في سياسات مجموعة المجال على الأقل "مراقبة الجلسة بإذن المستخدم" ( المزيد ):

mstsc /shadow:127

يرجى ملاحظة أن القائمة ستحتوي فقط على تسجيلات دخول المستخدم.

أكرر أنه بدون حقوق المسؤول ، ستتلقى ما يلي:



ولكن من أجل التصحيح الأولي للبرنامج الذي سيتم مناقشته ، استخدمت حسابًا مع حقوق المسؤول.

II. برنامج

إذن بيان المشكلة: إنشاء واجهة مستخدم رسومية بسيطة للاتصال بمعنى ظل المستخدم بإذنه ، وإرسال رسالة للمستخدم. يتم اختيار بيئة البرمجة بواسطة Lazarus.

1. نحصل على قائمة المجال الكاملة للمستخدمين "تسجيل الدخول" - "الاسم الكامل" من المسؤول ، أو مرة أخرى من خلال وحدة التحكم:

wmic useraccount get Name,FullName 

لا أحد يمنع حتى هذا:

wmic useraccount get Name,FullName > c:\test\username.txt

يجب أن أقول على الفور أن Lazarus كان لديه مشكلة في معالجة هذا الملف ، لأن ترميزه الافتراضي هو UCS-2 ، لذلك كان علي فقط تحويله يدويًا إلى UTF-8 العادي. هناك الكثير من علامات التبويب في بنية الملف ، أو بالأحرى الكثير من المساحات التي تقرر برمجتها بعد كل شيء ، عاجلاً أم آجلاً سيتم حل مشكلة الترميز ، وسيتم تحديث الملف برمجيًا.

لذلك ، في فكرة المجلد ، يمكن لمستخدمي البرنامج الوصول إليها ، على سبيل المثال c: \ test ، حيث سيكون هناك ملفان: الأول مع تسجيل الدخول والاسم الكامل ، والثاني مع id_rdp ومستخدمي تسجيل الدخول. علاوة على ذلك نقوم بمعالجة هذه البيانات بقدر ما نستطيع :).

في غضون ذلك ، للربط بقائمة الجلسات ، ننقل محتويات (تسجيل الدخول والاسم الكامل) إلى مصفوفة:

procedure Tf_rdp.UserF2Array;
var 
  F:TextFile;   i:integer;   f1, line1:String;   fL: TStringList;
begin //f_d      
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, '  ', '|',[]); //  .2  |
//    
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. تم عمل المزيد من الأوسمة ، مثل الفرز بالضغط على زر الراديو ، والرسائل الموجهة إلى المستخدم أو جميع المستخدمين.



→ يمكن رؤية كود المصدر الكامل هنا

III. تطبيق AdminLink - ما رأيته:

ينشئ AdminLink حقًا اختصارًا يشير إلى موقع الأداة المساعدة admilaunch.exe ، ونسخة شخصية من أداة تشغيل AdmiRun.Exe الموجودة في مجلد المستخدم ، على سبيل المثال ، vasya ، مثل C: \ Users \ vasya \ WINDOWS \ . بشكل عام ، ليس كل شيء سيئًا للغاية: يمكنك اللعب بحقوق الوصول إلى ملف الاختصار وغيره ، لتطهير ضمير المشرف الخاص بك.

All Articles