用于在WinServer 2012R2中将非管理员连接到RDP用户会话的人类影子实用程序

企业隔离期间的问题如下:确实有必要最大程度地减少为应用软件提供服务并提供建议的专家对内阁的访问次数,并且坦率地说,用户经常滥用专家的帮助,而不希望自己深入研究问题本身,他们说:“他们会来-他们会帮助,他们会做的,并且而我吸烟/喝咖啡等。”共享服务器时,通过电话进行咨询在查看远程屏幕时更为有效。



在“发明”我们的自行车之后,就出现了以下话题的理智信息:RDS影子-Windows Server 2012 R2中与RDP用户会话的影子连接Windows服务器中非特权用户的影子模式,或者我们委派了RDP会话的管理。所有这些都暗示着使用控制台,即使带有简单对话的元素也是如此。

下面的所有信息供那些通常可以容忍异常失真以获得期望结果的人使用,从而发明了不必要的方法。
为了不让猫被尾巴拉扯,我将从后者开始:自行车使用AdmiLink实用程序普通用户使用,为此我感谢作者。

I.控制台和影子RDP。

由于使用具有管理员权限 -> QuickSessionCollection->并通过单击感兴趣的用户的会话来使用服务器管理器控制台,因此从上下文菜单中选择Shadow来指示工作人员使用该软件的工作人员不可行的,因此考虑了另一种“木本”的方法,即:

1.我们了解RDP会话ID:

query user | findstr Administrator

要么:

qwinsta | findstr Administrator 

仅当您知道所需的管理员或仅使用第一部分来查看所有已登录到服务器的| findstr Administrator ”时,它才很方便 2.我们已连接到该会话,但前提是在域组策略中至少选择了“为远程桌面服务的用户会话设置远程控制规则”参数“使用用户权限监视会话”(更多):





mstsc /shadow:127

请注意,该列表仅包含用户登录名。

我重复一遍,没有管理员权限,您将收到以下信息:



但是,对于将要讨论的程序的初步调试,我使用了具有管理员权限的帐户。

二。程序

So问题的陈述:创建一种简单的图形界面,以在用户允许的情况下连接到用户的阴影感,并向用户发送消息。编程环境由Lazarus选择。

1.我们从管理员或通过控制台再次获得用户“登录”-“全名”的完整域列表:

wmic useraccount get Name,FullName 

没有人禁止这样做:

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

我必须立即说,是拉撒路处理此文件时遇到了问题,因为其默认编码为UCS-2,所以我只需要手动将其转换为常规UTF-8。文件结构中有许多选项卡,或者说毕竟是决定要编程的很多空间,迟早将解决编码问题,并且将以编程方式更新文件。

因此,就文件夹的想法而言,程序的用户可以访问该文件夹,例如c:\ test,其中将有2个文件:第一个具有登录名和全名,第二个具有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.进行了更多装饰,例如通过单击单选按钮进行排序,以及向用户或所有用户发送消息。



→完整的源代码可以在此处查看

AdminLink应用程序-我所看到的:

AdminLink确实生成了一个快捷方式,该快捷方式引用了admilaunch.exe实用程序的位置以及位于用户文件夹中的AdmiRun.Exe启动实用程序的个人副本,例如vasya,例如C:\ Users \ vasya \ WINDOWS \通常,并非一切都那么糟糕:您可以使用对快捷方式文件和其他文件的访问权限,以清除自己的管理良心。

All Articles