O problema durante o período de quarentena da empresa passou a ser o seguinte: é realmente necessário minimizar o número de visitas aos escritórios de especialistas atendendo e prestando consultoria em software aplicativo e, falando francamente, os usuários muitas vezes abusam da ajuda de especialistas sem querer se aprofundar a questão em si, eles dizem “eles virão - eles vão ajudar - eles farão isso, mas eu vou fumar/beber café, etc.” A consulta por telefone ao compartilhar um servidor é mais eficaz se você visualizar a tela remota.
Após a “invenção” da nossa bicicleta, surgiram informações sensatas sobre o tema do artigo:
Todas as informações abaixo são destinadas àqueles que tolera perversões anormais normalmente para obter o resultado desejado, inventando métodos desnecessários.
Para não “puxar o gato pelo rabo”, vou começar pela última: a bike funciona para o usuário médio usando o utilitário
I. Console e sombra RDP.
Desde o uso com direitos de administrador do console do Server Manager -> QuickSessionCollection -> clicando na sessão do usuário de interesse, selecionando Shadow no menu de contexto para pessoal que instrui como usar o software, não é uma opção, foi considerado outro método “de madeira”, nomeadamente:
1. Descubra o ID RDP da sessão:
query user | findstr Administrator
ou:
qwinsta | findstr Administrator
Além disso "| Administrador findstr"Só era conveniente quando você sabia exatamente o que Administrador você precisa, ou use apenas a primeira parte para ver todos logados no servidor.
2. Conecte-se a esta sessão, desde que no domínio políticas de grupo A opção "Configurar regras de controle remoto para sessões de usuário de Serviços de Área de Trabalho Remota" é selecionada com pelo menos a opção "Monitorar sessão com permissão do usuário" selecionada (
mstsc /shadow:127
Observe que a lista conterá apenas logins de usuários.
Repito que sem direitos de administrador você obterá o seguinte:
Mas para a depuração preliminar do programa que será discutido, usei uma conta com direitos de administrador.
II. Programa
Portanto, a definição do problema: criar uma interface gráfica simples para conectar-se ao sentido da sombra do usuário com sua permissão, enviando uma mensagem ao usuário. O ambiente de programação escolhido é o Lazarus.
1. Obtemos a lista completa de usuários de domínio “login” - “nome completo” do administrador ou novamente por meio do console:
wmic useraccount get Name,FullName
ninguém proíbe nem isso:
wmic useraccount get Name,FullName > c:testusername.txt
Direi desde já que foi o Lazarus quem teve problemas com o processamento deste arquivo, já que por padrão sua codificação é UCS-2, então só tive que convertê-lo manualmente para UTF-8 normal. Existem muitas abas na estrutura do arquivo, ou melhor, muitos espaços, que foi decidido processar programaticamente, mais cedo ou mais tarde o problema de codificação será resolvido e o arquivo será atualizado programaticamente.
Então, a ideia é ter uma pasta acessível aos usuários do programa, por exemplo c:test, na qual estarão 2 arquivos: o primeiro com login e nome completo, o segundo com id_rdp e login de usuários. A seguir, processamos esses dados da melhor maneira possível :).
Enquanto isso, para associar à lista de sessões, transferimos esse conteúdo (login e nome completo) para um array:
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 “muito código”, os pontos a seguir serão mais concisos.
2. Usando o mesmo método do parágrafo anterior, lemos o resultado do processamento da lista no elemento StringGrid, enquanto darei um trecho de código “significativo”:
2.1 Recebemos 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 Processe o arquivo (apenas linhas significativas de código 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. Conexão direta clicando 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 classificação 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
III. Usando AdminLink - o que vi:
AdminLink gera um atalho que faz referência à localização do utilitário admilaunch.exee uma cópia pessoal do utilitário de inicialização AdmiRun.Exe que está localizado na pasta do usuário, por exemplo Vasya vasya, tipo C:UsuáriosvasyaWINDOWS. Em geral, nem tudo é tão ruim: você pode brincar com os direitos de acesso ao arquivo de atalho e outros para limpar sua consciência administrativa.
Fonte: habr.com