Le problème pendant la période de quarantaine de l'entreprise est devenu le suivant : il est vraiment nécessaire de minimiser le nombre de visites dans les bureaux de spécialistes de l'entretien et du conseil sur les logiciels d'application, et franchement, les utilisateurs abusent souvent de l'aide de spécialistes sans vouloir approfondir le problème lui-même, ils disent « ils viendront – ils aideront – ils le feront, mais je fumerai/boire du café, etc. » La consultation téléphonique lors du partage d'un serveur est plus efficace si vous visualisez l'écran distant.
Après « l’invention » de notre vélo, des informations sensées sur le sujet de l’article sont apparues :
Toutes les informations ci-dessous sont destinées à ceux qui tolère normalement les perversions anormales pour obtenir le résultat souhaité, inventer des méthodes inutiles.
Afin de ne pas « tirer le chat par la queue », je commencerai par le dernier : le vélo fonctionne pour l'utilisateur moyen utilisant l'utilitaire
I. Console et RDP fantôme.
Depuis son utilisation avec droits d'administrateur de la console du Gestionnaire de serveur -> QuickSessionCollection -> en cliquant sur la session de l'utilisateur qui vous intéresse, en sélectionnant Shadow dans le menu contextuel pour le personnel expliquant comment utiliser le logiciel, n’est pas une option, une autre méthode « en bois » a été envisagée, à savoir :
1. Découvrez l'identifiant RDP de la session :
query user | findstr Administrator
ou:
qwinsta | findstr Administrator
De plus "| Administrateur findstr"C'était seulement pratique quand on savait exactement quoi Administrateur dont vous avez besoin, ou utilisez uniquement la première partie pour voir toutes les personnes connectées au serveur.
2. Connectez-vous à cette session, à condition que dans le domaine politiques de groupe L'option « Configurer des règles de contrôle à distance pour les sessions utilisateur des services Bureau à distance » est sélectionnée avec au moins l'option « Surveiller la session avec l'autorisation de l'utilisateur » sélectionnée (
mstsc /shadow:127
Veuillez noter que la liste ne contiendra que les connexions des utilisateurs.
Je répète que sans droits d'administrateur, vous obtiendrez ce qui suit :
Mais pour le débogage préliminaire du programme dont il sera question, j'ai utilisé un compte avec des droits d'administrateur.
II. Programme
D'où l'énoncé du problème : créer une interface graphique simple pour se connecter au sens de l'ombre de l'utilisateur avec sa permission, en envoyant un message à l'utilisateur. L'environnement de programmation choisi est Lazarus.
1. Nous obtenons la liste complète du domaine des utilisateurs « login » - « nom complet » auprès de l'administrateur, ou encore via la console :
wmic useraccount get Name,FullName
personne n'interdit même cela :
wmic useraccount get Name,FullName > c:testusername.txt
Je dirai tout de suite que c'est Lazarus qui a eu un problème avec le traitement de ce fichier, puisque par défaut son encodage est UCS-2, j'ai donc juste dû le convertir manuellement en UTF-8 standard. Il y a beaucoup d'onglets dans la structure du fichier, ou plutôt beaucoup d'espaces, qu'il a été décidé de traiter par programme ; tôt ou tard, le problème d'encodage sera résolu et le fichier sera mis à jour par programme.
Donc, l'idée est d'avoir un dossier accessible aux utilisateurs du programme, par exemple c:test, dans lequel il y aura 2 fichiers : le premier avec login et nom complet, le second avec id_rdp et login des utilisateurs. Ensuite, nous traitons ces données du mieux que nous pouvons :).
En attendant, pour associer à la liste des sessions, nous transférons ce contenu (login et nom complet) vers un tableau :
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;
Je m'excuse pour le "beaucoup de code", les points suivants seront plus concis.
2. En utilisant la même méthode du paragraphe précédent, nous lisons le résultat du traitement de la liste dans l'élément StringGrid, tandis que je donnerai un morceau de code « significatif » :
2.1 Nous recevons la liste actuelle des sessions RDP dans un fichier :
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 Traiter le fichier (seules les lignes de code significatives sont indiquées) :
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. Connexion directe elle-même en cliquant sur la ligne avec l'utilisateur et son numéro de session :
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. Quelques décorations supplémentaires ont été apportées, comme le tri en cliquant sur le bouton radio et les messages à l'utilisateur ou à tous les utilisateurs.
→ Le code source complet peut être vu
III. Utilisation d'AdminLink - ce que j'ai vu :
AdminLink génère un raccourci qui fait référence à l'emplacement de l'utilitaire admilaunch.exe, et une copie personnelle de l'utilitaire de lancement AdmiRun.Exe qui se trouve dans le dossier de l'utilisateur, par exemple Vassia, taper C:UtilisateursvasyaWINDOWS. En général, tout n'est pas si mal : vous pouvez jouer avec les droits d'accès au fichier de raccourci et autres pour vous débarrasser de votre propre conscience d'administrateur.
Source: habr.com