WinServer 2012R2 中非管理员与 RDP 用户会话的人影连接实用程序

企业隔离期间的问题是:确实有必要尽量减少对应用软件进行服务和咨询的专家到办公室的次数,坦白说,用户经常滥用专家的帮助而不想深入研究。就问题本身而言,他们说“他们会来 - 他们会帮忙 - 他们会做,但我会抽烟/喝咖啡,等等。” 共享服务器时,如果查看远程屏幕,电话咨询会更有效。

WinServer 2012R2 中非管理员与 RDP 用户会话的人影连接实用程序

在我们的自行车“发明”之后,出现了有关本文主题的理智信息: RDS Shadow – Windows Server 2012 R2 中 RDP 用户会话的影子连接 или Windows服务器中的非特权用户影子模式 или 委派 RDP 会话管理。 所有这些都涉及控制台的使用,甚至包括简单对话的元素。

以下所有信息适用于那些 通常能够容忍异常的变态 为了获得想要的结果,发明了不必要的方法。
为了不“牵着猫的尾巴”,我将从最后一个开始:自行车适用于使用该实用程序的普通用户 管理链接,为此感谢其作者。

I. 控制台和影子 RDP。

由于与使用 服务器管理器控制台的管理员权限 -> QuickSessionCollection -> 单击感兴趣的用户的会话,从上下文菜单中选择 Shadow 供人员指导如何使用该软件,不是一个选择,考虑了另一种“木”方法,即:

1. 找出会话的 RDP id:

query user | findstr Administrator

或:

qwinsta | findstr Administrator 

而且 ”| 查找str管理员“只有当你知道到底是什么时才方便 管理员 您需要,或者仅使用第一部分来查看登录到服务器的每个人。

WinServer 2012R2 中非管理员与 RDP 用户会话的人影连接实用程序

2. 连接到此会话,前提是在域中 团体政策 параметр «Устанавливает правила удаленного управления для пользовательских сеансов служб удаленных рабочих столов» выбран параметр как минимум «Наблюдение за сеансом с разрешения пользователя» ():

mstsc /shadow:127

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

我再说一遍,如果没有管理员权限,您将获得以下信息:

WinServer 2012R2 中非管理员与 RDP 用户会话的人影连接实用程序

但为了对即将讨论的程序进行初步调试,我使用了具有管理员权限的帐户。

二. 程序

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

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

wmic useraccount get Name,FullName 

甚至没有人禁止这一点:

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

我马上就会说是 Lazarus 在处理这个文件时遇到了问题,因为默认情况下它的编码是 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. 还做了一些装饰,例如通过单击单选按钮进行排序,以及向用户或所有用户发送消息。

WinServer 2012R2 中非管理员与 RDP 用户会话的人影连接实用程序

→ 完整源代码可见 这里

三. 使用 AdminLink - 我所看到的:

AdminLink 确实会生成一个引用该实用程序位置的快捷方式 admilaunch.exe,以及启动实用程序的个人副本 AdmiRun.exe 例如,它位于用户的文件夹中 vasya, 类型 C:UsersvasyaWINDOWS。 一般来说,并不是一切都那么糟糕:您可以尝试使用快捷方式文件和其他文件的访问权限来澄清您自己的管理良心。

来源: habr.com

添加评论