O problema durante o período de corentena da empresa converteuse no seguinte: é realmente necesario minimizar o número de visitas ás oficinas de especialistas que prestan servizo e consulta sobre software de aplicación e, francamente, os usuarios adoitan abusar da axuda dos especialistas sen querer profundar. o tema en si, din que "virán, axudarán, farano, pero eu fumarei/bebei café, etc". A consulta telefónica ao compartir un servidor é máis eficaz se ves a pantalla remota.
Despois da "invención" da nosa bicicleta, apareceu información sensata sobre o tema do artigo:
Toda a información a continuación está destinada a aqueles que tolera normalmente perversións anormais para obter o resultado desexado, inventando métodos innecesarios.
Para non "tirar do gato polo rabo", comezarei polo último: a bicicleta funciona para o usuario medio que usa a utilidade
I. Consola e RDP sombra.
Desde o uso con dereitos de administrador da consola Server Manager -> QuickSessionCollection -> facendo clic na sesión do usuario de interese, seleccionando Sombra no menú contextual para o persoal que ensina o uso do software, non é unha opción, considerouse outro método "de madeira", a saber:
1. Descubra o ID RDP da sesión:
query user | findstr Administrator
ou:
qwinsta | findstr Administrator
Ademais "| Administrador findstr"Só era conveniente cando sabías o que exactamente Administrador necesitas ou usa só a primeira parte para ver a todos os que iniciaron sesión no servidor.
2. Conéctate a esta sesión, sempre que no dominio políticas de grupo A opción "Configurar regras de control remoto para sesións de usuarios dos Servizos de Escritorio remoto" está seleccionada con polo menos a opción "Monitorizar sesión con permiso de usuario" (
mstsc /shadow:127
Teña en conta que a lista só conterá os inicios de sesión dos usuarios.
Repito que sen dereitos de administrador obterás o seguinte:
Pero para a depuración preliminar do programa que se discutirá, usei unha conta con dereitos de administrador.
II. Programa
Entón, o enunciado do problema: crear unha interface gráfica sinxela para conectarse co sentido de sombra do usuario co seu permiso, enviando unha mensaxe ao usuario. A contorna de programación escollida é Lazarus.
1. Recibimos a lista completa de dominios de usuarios "iniciar sesión" - "nome completo" do administrador, ou de novo a través da consola:
wmic useraccount get Name,FullName
ninguén prohibe nin sequera isto:
wmic useraccount get Name,FullName > c:testusername.txt
Direi de inmediato que foi Lázaro o que tivo un problema ao procesar este ficheiro, xa que por defecto a súa codificación é UCS-2, polo que só tiven que convertelo manualmente a UTF-8 normal. Hai moitas pestanas na estrutura do ficheiro, ou mellor dito moitos espazos, que se decidiu procesar mediante programación; tarde ou cedo resolverase o problema de codificación e o ficheiro actualizarase mediante programación.
Así, a idea é ter un cartafol accesible para os usuarios do programa, por exemplo c:test, no que haberá 2 ficheiros: o primeiro con login e nome completo, o segundo con id_rdp e login de usuarios. A continuación, procesamos estes datos o mellor posible :).
Mentres tanto, para asociarnos coa lista de sesións, transferimos este contido (inicio de sesión e nome completo) a unha 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 desculpas polo "lote de código", os seguintes puntos serán máis concisos.
2. Usando o mesmo método do parágrafo anterior, lemos o resultado do procesamento da lista no elemento StringGrid, mentres darei un anaco de código "significativo":
2.1 Recibimos a lista actual de sesións RDP nun ficheiro:
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 Procesar o ficheiro (só se indican liñas 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. Conexión directa facendo clic na liña co usuario e o seu 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. Fixéronse un par de adornos máis, como a ordenación facendo clic no radiobotón, e as mensaxes ao usuario ou a todos os usuarios.
→ Pódese ver o código fonte completo
III. Usando AdminLink - o que vin:
AdminLink xera un atallo que fai referencia á localización da utilidade admilaunch.exe, e unha copia persoal da utilidade de inicio AdmiRun.Exe que se atopa no cartafol do usuario, por exemplo Vasia, tipo C: UsersvasyaWINDOWS. En xeral, non todo é tan malo: podes xogar cos dereitos de acceso ao ficheiro de atallo e outros para limpar a túa propia conciencia de administrador.
Fonte: www.habr.com