Utilitário para sombra humana que conecta não-administrador a sessões de usuário RDP no WinServer 2012R2

O problema durante o período de quarentena da empresa era o seguinte: é realmente necessário minimizar o número de visitas a gabinetes por especialistas que prestam serviços de manutenção e aconselham sobre software de aplicativos e, francamente, os usuários frequentemente abusam da ajuda de especialistas que não desejam se aprofundar na pergunta, dizendo "eles virão - eles ajudarão, eles farão isso; e enquanto fumo / tomo café, etc. " A consulta por telefone ao compartilhar um servidor é mais eficaz ao exibir uma tela remota.



Já após a "invenção" de nossa bicicleta, surgiram informações sãs sobre o tópico do artigo: RDS Shadow - conexão de sombra às sessões de usuário RDP no Windows Server 2012 R2 ou modo Shadow de um usuário não privilegiado no servidor Windows ou Delegamos o gerenciamento de sessões RDP . Todos eles implicam o uso de um console, mesmo com elementos de um simples diálogo.

Todas as informações abaixo destinam-se a quem normalmente tolera perversões anormais para obter o resultado desejado, inventando métodos desnecessários.
Para não "puxar o gato pela cauda", começarei com o último: a bicicleta funciona para o usuário comum usando o utilitário AdmiLink , pelo qual agradeço ao autor.

I. Console e sombra RDP.

Como o uso do console do Gerenciador do Servidor com direitos de administrador -> QuickSessionCollection -> clicando na sessão do usuário de seu interesse, selecionar Shadow no menu de contexto para a equipe que instrui no trabalho com o software não é uma opção, outro método "de madeira" foi considerado, a saber:

1. aprendemos a id de sessão RDP:

query user | findstr Administrator

ou:

qwinsta | findstr Administrator 

E o " | findstr Administrator " era conveniente apenas quando você sabe o que precisa do administrador ou usa apenas a primeira parte para ver todos os logons no servidor.



2. Estamos conectados a esta sessão, desde que nas políticas de grupo de domínio a opção "Defina as regras de controle remoto para sessões de usuário dos Serviços de Área de Trabalho Remota" seja selecionada pelo menos "Monitorar a sessão com permissão do usuário" ( mais ):

mstsc /shadow:127

Observe que a lista conterá apenas logins de usuários.

Repito que, sem direitos de administrador, você receberá o seguinte:



Mas, para depuração preliminar do programa que será discutido, usei uma conta com direitos de administrador.

II Programa

Portanto, a declaração do problema: criar um tipo de interface gráfica simples para conectar-se ao sensor de sombra do usuário com sua permissão, enviando uma mensagem ao usuário. O ambiente de programação é selecionado pelo Lazarus.

1. Nós obtemos a lista de domínio completa dos usuários "login" - "nome completo" do administrador ou novamente através do console:

wmic useraccount get Name,FullName 

ninguém proíbe nem isso:

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

Devo dizer imediatamente que foi o Lazarus quem teve o problema de processar este arquivo, já que sua codificação padrão é UCS-2, então eu apenas tive que convertê-lo manualmente para UTF-8 regular. Existem muitas guias na estrutura do arquivo, ou melhor, muitos espaços que foram decididos a serem programados, mais cedo ou mais tarde o problema de codificação será resolvido e o arquivo será atualizado programaticamente.

Portanto, na ideia da pasta, acessível aos usuários do programa, por exemplo c: \ test, na qual haverá 2 arquivos: o primeiro com login e nome completo, o segundo com id_rdp e usuários de login. Além disso, processamos esses dados como podemos :).

Enquanto isso, para associar à lista de sessões, transferimos esse conteúdo (login e nome completo) para uma 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;

Peço desculpas pelo "lote de código", os seguintes pontos serão mais concisos.

2. Da mesma forma, usando o método do parágrafo anterior, lemos o resultado do processamento da lista em um elemento StringGrid, enquanto darei um trecho de código "significativo":

2.1 Obtenha a lista atual de sessões RDP em um arquivo:

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 Processamos o arquivo (apenas linhas de código significativas são indicadas):

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. A conexão em si quando você clica na linha com o usuário e seu número de sessão:

  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. Mais algumas decorações foram feitas, como ordenar clicando no botão de opção e mensagens para o usuário ou todos os usuários.



→ O código fonte completo pode ser visto aqui

III. Aplicativo AdminLink - o que vi: o

AdminLink realmente gera um atalho que se refere à localização do utilitário admilaunch.exe e uma cópia pessoal do utilitário de inicialização AdmiRun.Exe localizado na pasta do usuário, por exemplo, vasya , como C: \ Users \ vasya \ WINDOWS \ . Em geral, nem tudo é tão ruim: você pode brincar com os direitos de acesso ao arquivo de atalho e outros, para limpar sua própria consciência de administrador.

All Articles