powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Active directory список пользователей и компов
18 сообщений из 18, страница 1 из 1
Active directory список пользователей и компов
    #39232991
mlc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем привет. Вопрос такой: как получить список компов и залогиненных на этих компах пользователей. Другими словами, есть комп и есть человек, который на нем работает. Получить список пользователей через UserPrincipal могу, получить список компов через ComputerPrincipal тоже могу, а вот соединить их между собой не получается. Прошу помощи.

Список пользователей Active Directory. С компами тоже самое, только меняем UserPrincipal на ComputerPrincipal.
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
Func<DirectoryEntry, bool> IsActive = de => de.NativeGuid == null ? false : !Convert.ToBoolean((int)de.Properties["useraccountcontrol"].Value & 0x0002);

            using (var context = new PrincipalContext(ContextType.Domain))
            {
                using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
                {
                    foreach (var result in searcher.FindAll())
                    {
                        using (var de = result.GetUnderlyingObject() as DirectoryEntry)
                        {
                            if(IsActive(de))
                            {
                                Console.WriteLine("{0} - {1}", result.DisplayName, result.SamAccountName);
                                i++;
                            }
                        }
                    }
                }
            }            
            Console.ReadLine();
...
Рейтинг: 0 / 0
Active directory список пользователей и компов
    #39233025
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
базовыми средствами ActiveDirectory сделать это нельзя.
есть 2 пути:
а) ты подключаешься к каждому компьютеру и проверяешь список активный сессий (на 1 компьютере могут работать несколько пользователей, особенно если это сервер терминалов)
б) создаешь скрипт на вход и выход из системы, которые будет делать соответствующие записи в AD (в созданное или существующее в схеме поле), а дальше делать реализацию через эти поля. Тут собственно тоже масса подводных камней, так как нет ни каких гарантий, что сессия завершится корректно и что при включении компьютера в момент выполнения скрипта сеть и каталог LDAP будут доступны.
...
Рейтинг: 0 / 0
Active directory список пользователей и компов
    #39233031
mlc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman Mejtesа) ты подключаешься к каждому компьютеру и проверяешь список активный сессий (на 1 компьютере могут работать несколько пользователей, особенно если это сервер терминалов)
это случайно не WMI?
...
Рейтинг: 0 / 0
Active directory список пользователей и компов
    #39233041
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
mlcRoman Mejtesа) ты подключаешься к каждому компьютеру и проверяешь список активный сессий (на 1 компьютере могут работать несколько пользователей, особенно если это сервер терминалов)
это случайно не WMI?
Да хоть через WMI, хоть напрямую через удаленное чтение реестра.

Есть еще один способ - разрешить пользователям входить только с определенного компьютера, но он тоже может принести много гемороя
...
Рейтинг: 0 / 0
Active directory список пользователей и компов
    #39234319
mlc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cat2Да хоть через WMI, хоть напрямую через удаленное чтение реестра.

Попробовал оба. Спасибо за заданное направление. Прикладываю решение.

WMI
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
        static void Main(string[] args)
        {
            string serverName = Environment.MachineName;    // my machine name
            foreach (var user in GetLoggedUser(serverName))
            {
                Console.WriteLine("{0} - {1}", serverName, user);
            }
            Console.Read();
        }

        private static IEnumerable<string> GetLoggedUser(string machineName)
        {   
            var scope = GetManagementScope(machineName);
            scope.Options.Timeout = TimeSpan.FromMinutes(1);
            scope.Connect();

            // Interactive (2) : Intended for users who are interactively using the machine, 
            // such as a user being logged on by a terminal server, remote shell, or similar process.
            var Query = new SelectQuery("SELECT LogonId FROM Win32_LogonSession Where LogonType = 2");
            var Searcher = new ManagementObjectSearcher(scope, Query);
            var regName = new System.Text.RegularExpressions.Regex(@"(?<=Name="").*(?="")");

            foreach (ManagementObject WmiObject in Searcher.Get())
            {
                foreach (ManagementObject LWmiObject in WmiObject.GetRelationships("Win32_LoggedOnUser"))
                {
                    yield return regName.Match(LWmiObject["Antecedent"].ToString()).Value;
                }
            }
        }

        private static ManagementScope GetManagementScope(string machineName)
        {
            ManagementScope Scope;

            if (machineName.Equals("localhost", StringComparison.OrdinalIgnoreCase))
                Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", "."), GetConnectionOptions());
            else
            {
                Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", machineName), GetConnectionOptions());
            }
            return Scope;
        }

        private static ConnectionOptions GetConnectionOptions()
        {
            return new ConnectionOptions
            {
                EnablePrivileges = true,
                Authentication = AuthenticationLevel.PacketPrivacy,
                Impersonation = ImpersonationLevel.Impersonate,
            };
        }



read Remote Registry. У удаленного компа должна быть включена служба Удаленный Реестр
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
            string machineName = Environment.MachineName,,
                   location = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI";
            var registryView = Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32;
            using (var hive = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, machineName, registryView))
            {
                using (var key = hive.OpenSubKey(location))
                {
                    var item = key.GetValue("LastLoggedOnUser");
                    string itemValue = item == null ? "No Logon Found" : item.ToString();
                    Console.WriteLine(itemValue);
                }
            }
            Console.Read();



P.S. Чтобы получить инфу нужно иметь соответствущие права.
...
Рейтинг: 0 / 0
Active directory список пользователей и компов
    #39234331
mlc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mlc,

Еще, как оказалось, можно попробовать через чтение Security Event log. Правда пока не понятно, что именно я должен искать в этом логе.
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
            string logType = "Application",
                   machineName = System.Environment.MachineName;

            EventLog ev = new EventLog(logType, machineName);
            int LastLogToShow = ev.Entries.Count;
            if (LastLogToShow <= 0)
                Console.WriteLine("No Event Logs in the Log :" + logType);
            // Read the last 2 records in the specified log. 

            foreach (var lg in ev.Entries.Cast<EventLogEntry>())          //  Необходимо найти события 4634 и 4624 => .Where(x => x.EventID == 4634)
            {
                Console.WriteLine("Event ID : " + lg.EventID);
                Console.WriteLine("Entry Type : " + lg.EntryType.ToString());
                Console.WriteLine("Message :  " + lg.Message + "\n");
            }
            ev.Close();
            Console.Read();
...
Рейтинг: 0 / 0
Active directory список пользователей и компов
    #39234372
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mlc,

логи могут быть ооооооочень большими, читать их как по мне нерационально.
у меня на рабочем компе бывало даже такое, что Securety лог на компе переполнялся и нельзя было после этого зайти на комп ^_^
...
Рейтинг: 0 / 0
Active directory список пользователей и компов
    #39234453
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
mlc,

1. На Wundows XP нет раздела "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI".

Кусочек моего говнокода.
Следующая функция вычисляет SID текущего пользователя. Если пользователей несколько залогинилось - берет интерактивного. Если таких несколько - берет первого попавшегося который залогинился интерактивно. Ну и куча перестраховок, потому что функция должна вернуть хоть что-то и не сгенерировать ошибку.


Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
public static string GetUserSIDFromIp(string ip, out string Domain, out string username, out string Error)
        {
            string SID = "";
            username = Domain = Error = "";


            using (RegistryKey rk = RegistryKey.OpenRemoteBaseKey(RegistryHive.Users, ip))
                try
                {
                    Regex reg = new Regex(@"S-1-5-\d{2}[-\d]+$");
                    string[] currentusers = rk.GetSubKeyNames().Where(c => reg.IsMatch(c)).ToArray();
                    foreach (string cu in currentusers)
                    {
                        string regPath = string.Format(@"{0}\Volatile Environment", cu);
                        RegistryKey key = rk.OpenSubKey(regPath);
                        {
                            if (key != null)
                            {
                                SID = cu;
                                Domain = key.GetValue("USERDOMAIN", "").ToString().Split('.')[0];
                                if (Domain.Length == 0)
                                {
                                    Domain = key.GetValue("USERDNSDOMAIN", "").ToString().Split('.')[0];
                                    if (Domain.Length == 0)
                                        Domain = key.GetValue("LOGONSERVER", "").ToString().Replace(@"\", "");
                                }
                                username = key.GetValue("USERNAME", "").ToString();
                                if (username.Length == 0)
                                {
                                    username = key.GetValue("HOMEPATH", "").ToString();
                                    username = Path.GetFileName(username);
                                }

                                string[] SubKeyNames = key.GetSubKeyNames();
                                if (SubKeyNames.Length > 0)
                                {
                                    regPath = string.Format(@"{0}\Volatile Environment\{1}", cu, SubKeyNames[0]);
                                    key = rk.OpenSubKey(regPath);
                                }


                                if (key.GetValue("SESSIONNAME").ToString() == "Console")
                                {
                                    break;
                                }
                            }
                        }

                    }
                }
                catch (Exception e)
                {
                    Error = e.Message;
                }
            return SID;
        }





2. string machineName = Environment.MachineName - это имя машины с которой запускается программа, а не той которую надо смотреть.

3. "SELECT LogonId FROM Win32_LogonSession Where LogonType = 2" . Мне несколько раз попадалось, что у нормального интерактивного доменного пользователя был LogonType = 9.

Лучше UserName из Win32_ComputerSystem.
...
Рейтинг: 0 / 0
Active directory список пользователей и компов
    #39234468
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
mlcЕще, как оказалось, можно попробовать через чтение Security Event log.

Долго очень, особенно если пользователь в пятницу машину не выключал, а в понедельник к ней не притрагивался
...
Рейтинг: 0 / 0
Active directory список пользователей и компов
    #39234612
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cat2mlcЕще, как оказалось, можно попробовать через чтение Security Event log.

Долго очень, особенно если пользователь в пятницу машину не выключал, а в понедельник к ней не притрагивался
пфффф :) да я комп на работе вообще не выключаю, пока сам не зависнет :)
а вообще, вроде блокировка и разблокировка так же в Securety Log логируется или логирует при определенных настройках, точно уже не помню, но это точно можно врубить.
но идея с логами говно при любом раскладе, очень тормозно будет работать
...
Рейтинг: 0 / 0
Active directory список пользователей и компов
    #39234655
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Roman Mejtesвроде блокировка и разблокировка так же в Securety Log логируется

Да. Сработал переход в спящий режим - вышел из системы. Нажал на клавишу - вошел. Даже если не настроен вход после блокировки с паролем.
Там казалось бы все просто. Ловим код события - вход. Ловим код входа - интерактивно.

Однако меня смутила фраза, которую я прочитал в доке от Микрософта, что коды входа уникальны на одной машине, но могут повторятся на другой.

Я так понял, что коды входа каждая машина генерит произвольно! То есть нельзя найти число, которое будет кодом входа интерактивного пользователя на всех машинах.
========

В поиске пользователя и диагностикуе ПК вообще ловушек море.

10% машин имеют неработоспособный WMI. Ну да ладно, есть способы его наладить. Правда в 1% случаев для этого надо переустановить ось с нуля. Мне и команде так и не удалось найти способ, который бы восстанавливал бы WMI всегда.

Так же для удаленного доступа через WMI нужно что бы был открыт 135 порт и разрешен вsзов через RPC.

Вы, конечно, молодец, чо определили что для работы через реестр нужны соответсвующие права на машине и запущена служба "Удаленный доступ к реестру".

Это правильно! Но кроме того должен быть открыт 445 порт и запущена служба "Сервер". Да и права на машине могут быть перекрыты явным запретом читать ветвь реестра всем Администраторам.

Бывает и такое. Чего только не бывает! Любая гадость, которая может случится , обязательно случиться! Вплоть до повреждения ветвей реестра, который вроде должен храниться как зеница ока.
...
Рейтинг: 0 / 0
Active directory список пользователей и компов
    #39234663
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cat2,

как по мне, проще накидать сервис на 2 строки, который каждые 5 минут будет писать в базу или АД, информацию о том, кто на компе работает или на каком компе пользователь работает и дату записи, если дата больше 5 минут, данные не актуальны.
При таком варианте пользовательский ПК выступает в роли клиента, а не в роли сервера, следовательно все выше перечисленные проблемы отпадают, за исключением конечно проблемы установки самого сервиса, которая решается через GPO
...
Рейтинг: 0 / 0
Active directory список пользователей и компов
    #39234678
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Roman MejtesCat2,

как по мне, проще накидать сервис на 2 строки, который каждые 5 минут будет писать в базу или АД, информацию о том, кто на компе работает или на каком компе пользователь работает и дату записи, если дата больше 5 минут, данные не актуальны.
При таком варианте пользовательский ПК выступает в роли клиента, а не в роли сервера, следовательно все выше перечисленные проблемы отпадают, за исключением конечно проблемы установки самого сервиса, которая решается через GPO
Увы. На моих 300 000 компов от Сахалина до Калининграда этот прекрасный способ не прокатывает.

Если бы мне дали полную волю, то я бы повесил политиками логонный скрипт, который бы писал в АД.

Как об этом и говорил в самом начале -
Roman Mejtesб) создаешь скрипт на вход и выход из системы, которые будет делать соответствующие записи в AD (в созданное или существующее в схеме поле), а дальше делать реализацию через эти поля. Тут собственно тоже масса подводных камней, так как нет ни каких гарантий, что сессия завершится корректно и что при включении компьютера в момент выполнения скрипта сеть и каталог LDAP будут доступны.
...
Рейтинг: 0 / 0
Active directory список пользователей и компов
    #39234840
mlc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman Mejtes,

про Security log уже убедился, когда начал долбать компы пользователей. Не вариант.

Cat210% машин имеют неработоспособный WMI. Ну да ладно, есть способы его наладить. Правда в 1% случаев для этого надо переустановить ось с нуля. Мне и команде так и не удалось найти способ, который бы восстанавливал бы WMI всегда.Cat2,

и с этим тоже уже успел столкнулся. Я так понимаю нет универсального способа. Ни реестр, ни wmi не дает 100% гарантии.

Cat2Если бы мне дали полную волю, то я бы повесил политиками логонный скрипт, который бы писал в АД.А можно поподробнее, чтобы я смог объяснить админам, что от них хочу.
...
Рейтинг: 0 / 0
Active directory список пользователей и компов
    #39234938
mlc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Active directory список пользователей и компов
    #39236307
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
mlcА можно поподробнее, чтобы я смог объяснить админам, что от них хочу.

В домене с помощью групповых политик можно сделать так, что при входе пользовался запускался некий скрипт.

Вернее это может быть не обязательно скрипт, но и консольная программа.

http://www.winblog.ru/win2003/1147763440-06020701.html

Данный скрипт должен запускаться от имени пользователя, иначе его имя получить не получится.
Далее простор для творчества.

Можно записать имя пользователя в локальный файл, в свою ветку реестра или в описание компьютера.
Разумеется должны быть соответствующие права.

Но лучше писать юзеру его комп или наоборот в AD
Разумеется должны быть делегированы соответствующие права.
http://www.osp.ru/win2000/2011/05/13009842/

Прав можно давать в другом логонном скрипте, который запускается после логина юзера.
Первый раз ему ничего записать не удасться, но при следующем логине все будет нормально.

=================
Еще вспомнил
1. Есть такая утилита bgInfo, которая запускается политиками много чего интересного пишет в XLS-файл, который хранится в профиле пользователя.
...
Рейтинг: 0 / 0
Active directory список пользователей и компов
    #39236939
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cat2mlcА можно поподробнее, чтобы я смог объяснить админам, что от них хочу.

В домене с помощью групповых политик можно сделать так, что при входе пользовался запускался некий скрипт.

Вернее это может быть не обязательно скрипт, но и консольная программа.

http://www.winblog.ru/win2003/1147763440-06020701.html

Данный скрипт должен запускаться от имени пользователя, иначе его имя получить не получится.
Далее простор для творчества.

Можно записать имя пользователя в локальный файл, в свою ветку реестра или в описание компьютера.
Разумеется должны быть соответствующие права.

Но лучше писать юзеру его комп или наоборот в AD
Разумеется должны быть делегированы соответствующие права.
http://www.osp.ru/win2000/2011/05/13009842/

Прав можно давать в другом логонном скрипте, который запускается после логина юзера.
Первый раз ему ничего записать не удасться, но при следующем логине все будет нормально.

=================
Еще вспомнил
1. Есть такая утилита bgInfo, которая запускается политиками много чего интересного пишет в XLS-файл, который хранится в профиле пользователя.
большая часть полей для класса пользователь открыты для обладателя на запись. То есть, сам пользователь в рамках своей учётки, может менять значение атрибутов (в зависимости от прав в схеме. конечно же). По этому, проще записывать имя компа в объект пользователя (user;person), а не имя пользователь в объекты ПК.
...
Рейтинг: 0 / 0
Active directory список пользователей и компов
    #39237522
mlc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cat2, Roman Mejtes,

спасибо за ценную инфу.
...
Рейтинг: 0 / 0
18 сообщений из 18, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Active directory список пользователей и компов
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]