Utilidad para la sombra humana que conecta sesiones de usuario no administrativas a RDP en WinServer 2012R2

El problema durante el período de cuarentena de la empresa fue el siguiente: es realmente necesario minimizar el número de visitas a los gabinetes por parte de especialistas que prestan servicio y asesoran sobre el software de aplicación, y francamente, los usuarios a menudo abusan de la ayuda de especialistas que no quieren profundizar en la pregunta en sí misma, diciendo "vendrán, ayudarán, lo harán, y mientras fumo / bebo café, etc. " Consultar por teléfono cuando se comparte un servidor es más efectivo cuando se visualiza una pantalla remota.



Ya después de la "invención" de nuestra bicicleta, apareció información sensata sobre el tema del artículo: RDS Shadow: conexión oculta a sesiones de usuario RDP en Windows Server 2012 R2 o modo Shadow de un usuario no privilegiado en Windows Server o delegamos la administración de sesiones RDP . Todos ellos implican el uso de una consola, incluso con elementos de un diálogo simple.

Toda la información a continuación está destinada a aquellos que normalmente toleran distorsiones anormales para obtener el resultado deseado, inventando métodos innecesarios.
Para no "jalar al gato por la cola", comenzaré con el último: la bicicleta funciona para el usuario promedio que usa la utilidad AdmiLink , por lo que su autor y gracias.

I. Consola y sombra RDP.

Dado que el uso de la consola de Server Manager con derechos de administrador -> QuickSessionCollection -> al hacer clic en la sesión del usuario de interés, seleccionar Shadow en el menú contextual para que el personal instruya a trabajar con el software no es una opción, se consideró otro método "de madera", a saber:

1. Aprendemos la identificación de la sesión RDP:

query user | findstr Administrator

o:

qwinsta | findstr Administrator 

Además, " | findtr Administrator " era conveniente solo cuando sabía exactamente qué necesita Administrador , o usa solo la primera parte para ver todos los usuarios registrados en el servidor.



2. Nos conectamos a esta sesión, siempre que en las políticas de grupo de dominio , la opción "Establezca las reglas de control remoto para las sesiones de usuario de Servicios de escritorio remoto" esté seleccionada al menos "Supervisar la sesión con permiso del usuario" ( más ):

mstsc /shadow:127

Tenga en cuenta que la lista solo contendrá los inicios de sesión de los usuarios.

Repito que sin derechos de administrador, recibirá lo siguiente:



Pero para la depuración preliminar del programa que se discutirá, utilicé una cuenta con derechos de administrador.

II Programa

Entonces, el enunciado del problema: crear una especie de interfaz gráfica simple para conectarse con el sentido de sombra del usuario con su permiso, enviando un mensaje al usuario. El entorno de programación es seleccionado por Lazarus.

1. Obtenemos la lista completa de dominios de usuarios "inicio de sesión" - "nombre completo" del administrador, o nuevamente a través de la consola:

wmic useraccount get Name,FullName 

nadie prohíbe incluso esto:

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

Debo decir de inmediato que fue Lazarus quien tuvo el problema con el procesamiento de este archivo, ya que su codificación predeterminada es UCS-2, por lo que solo tuve que convertirlo manualmente a UTF-8 normal. Hay muchas pestañas en la estructura del archivo, o más bien muchos espacios que se decidieron programar después de todo, tarde o temprano se resolverá el problema de codificación y el archivo se actualizará mediante programación.

Entonces, en la idea de la carpeta, accesible para los usuarios del programa, por ejemplo c: \ test, en el que habrá 2 archivos: el primero con inicio de sesión y nombre completo, el segundo con id_rdp y usuarios de inicio de sesión. Además procesamos estos datos como podemos :).

Mientras tanto, para asociarnos con la lista de sesiones, transferimos este contenido (inicio de sesión y nombre completo) a una matriz:

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;

Pido disculpas por el "lote de código", los siguientes puntos serán más concisos.

2. De manera similar, usando el método del párrafo anterior, leemos el resultado del procesamiento de la lista en un elemento StringGrid, mientras que daré un fragmento de código "significativo":

2.1 Obtenemos la lista real de sesiones RDP en un archivo:

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 Procesamos el archivo (solo se indican líneas de código significativas):

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. La conexión en sí cuando hace clic en la línea con el usuario y su número de sesión:

  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. Se hicieron un par de decoraciones más, como ordenar haciendo clic en el botón de radio y enviar mensajes al usuario o a todos los usuarios.



→ El código fuente completo se puede ver aquí

III. Aplicación AdminLink: lo que vi:

AdminLink realmente genera un acceso directo que se refiere a la ubicación de la utilidad admilaunch.exe y una copia personal de la utilidad de inicio AdmiRun.Exe ubicada en la carpeta del usuario, por ejemplo, vasya , como C: \ Users \ vasya \ WINDOWS \ . En general, no todo es tan malo: puedes jugar con los derechos de acceso al archivo de acceso directo y otros, para limpiar tu propia conciencia administrativa.

All Articles