Как получить список пользователей операционной системы или домена на стороне сервера в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе разработки часто возникает задача получить список пользователей домена или локальных учетных записей непосредственно в серверном модуле, например, для регламентного задания или заполнения справочника сотрудников. Однако стандартная функция ПользователиОС() имеет существенное ограничение: она доступна только в контексте тонкого и толстого клиента. Попытка вызвать ее на сервере приведет к ошибке компиляции или выполнения.

Разберем подробно, почему так происходит, и проанализируем основные способы решения этой задачи с использованием системных механизмов Windows и внешних интерфейсов.

Причина ограничения функции ПользователиОС()

Прежде чем переходить к решениям, выясним причину. Функция ПользователиОС() работает в контексте текущего интерактивного пользователя. На сервере же процесс rphost (или служба сервера 1С) запущен под технической учетной записью (обычно это USR1CV8 или LocalSystem). Прямой доступ к спискам пользователей через встроенные методы платформы на сервере ограничен в целях безопасности и из-за архитектурных особенностей клиент-серверного взаимодействия.

Ниже мы рассмотрим пять эффективных методов реализации этой задачи в серверном коде.

Способ 1. Использование COM-объектов и ADSI (LDAP)

Для работы в доменной среде наиболее надежным и быстрым способом является использование провайдера ADsDSOObject. Этот метод позволяет выполнять SQL-подобные запросы к контроллеру домена через интерфейс ADSI (Active Directory Service Interfaces). Проанализируем пример кода для получения списка всех активных пользователей домена.

Рассмотрим алгоритм реализации:


// Создаем соединение с Active Directory
Соединение = Новый COMОбъект("ADODB.Connection");
Соединение.Provider = "ADsDSOObject";
Соединение.Open("Active Directory Provider");

// Формируем запрос к LDAP
// Замените DC=domain,DC=local на ваши параметры домена
ТекстЗапроса = "SELECT samAccountName, displayName, mail FROM 'LDAP://DC=yourdomain,DC=com' WHERE objectCategory='person' AND objectClass='user'";

Команда = Новый COMОбъект("ADODB.Command");
Команда.ActiveConnection = Соединение;
Команда.CommandText = ТекстЗапроса;

Выборка = Команда.Execute();

Пока НЕ Выборка.EOF Цикл
    Логин = Выборка.Fields("samAccountName").Value;
    ФИО = Выборка.Fields("displayName").Value;
    Почта = Выборка.Fields("mail").Value;
    
    // Обработка полученных данных
    Выборка.MoveNext();
КонецЦикла;

Соединение.Close();

Важный момент: Учетная запись, под которой работает служба сервера 1С, должна обладать правами на чтение данных из Active Directory. В большинстве случаев прав обычного пользователя домена для этого достаточно.

Способ 2. Использование объекта WinNT для локальных и доменных групп

Если задача заключается в получении списка пользователей конкретной группы или локальных пользователей сервера, удобнее использовать провайдер WinNT. Этот метод проще в написании, хотя и работает медленнее при больших объемах данных.

Разберем по шагам, как перебрать пользователей:


ИмяКомпьютера = "SERVER_NAME"; // Или имя домена
Контейнер = ПолучитьОбъект("WinNT://" + ИмяКомпьютера + ",computer");
Контейнер.Filter = СоздатьМассивИзСтроки("user"); // Фильтруем только пользователей

Для Каждого ПользовательОС Из Контейнер Цикл
    Сообщить("Логин: " + ПользовательОС.Name);
    Сообщить("Полное имя: " + ПользовательОС.FullName);
КонецЦикла;

Для создания фильтра в 1С можно использовать объект COMSafeArray, если прямой перебор коллекции вызывает сложности.

Способ 3. Вызов PowerShell из кода 1С

Современным стандартом администрирования Windows является PowerShell. Мы можем запустить скрипт из 1С, который выгрузит данные во временный файл, а затем прочитать этот файл на сервере. Это избавляет от необходимости сложной настройки COM-объектов.

Посмотрим на пример реализации через временный JSON-файл:


ПутьКФайлу = ПолучитьИмяВременногоФайла("json");
Скрипт = "Get-ADUser -Filter * | Select-Object SamAccountName, Name | ConvertTo-Json | Out-File -FilePath '" + ПутьКФайлу + "' -Encoding utf8";

// Запускаем PowerShell
ЗапуститьПриложение("powershell -Command """ + Скрипт + """", , Истина);

// Читаем файл
ЧтениеТекста = Новый ЧтениеТекста(ПутьКФайлу, КодировкаТекста.UTF8);
ДанныеJSON = ЧтениеТекста.Прочитать();
ЧтениеТекста.Закрыть();

// Далее используем ЧтениеJSON для разбора структуры

Преимущество этого метода в гибкости: с помощью командлетов Get-ADUser можно легко фильтровать заблокированных пользователей или выбирать только определенные подразделения (OU).

Способ 4. Использование WMI (Windows Management Instrumentation)

Объект WMI позволяет опрашивать систему через SQL-подобные запросы к классам Windows. Для получения учетных записей используется класс Win32_UserAccount.

Проанализируем ситуацию использования WMI:


Локатор = Новый COMОбъект("WbemScripting.SWbemLocator");
СервисWMI = Локатор.ConnectServer(".", "root\cimv2");
СписокПользователей = СервисWMI.ExecQuery("SELECT Name, FullName FROM Win32_UserAccount WHERE LocalAccount = True");

Для Каждого ОбъектПользователь Из СписокПользователей Цикл
    // Доступ к свойствам через ОбъектПользователь.Name
КонецЦикла;

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

Способ 5. Решение для серверов на Linux

Если ваш сервер 1С работает под управлением Linux, COM-объекты Windows недоступны. В этом случае мы используем системные утилиты. Выясним, как это сделать:

  1. Использование команды ldapsearch для опроса Active Directory.
  2. Чтение файла /etc/passwd для получения списка локальных пользователей системы.

Для этого в 1С используется объект ЗапуститьПриложение, который направляет вывод команды в текстовый поток или файл, который затем парсится серверным кодом.

Сравнение методов и рекомендации

Подведем итог и выберем оптимальный путь:

LDAP (Способ 1) — лучшее решение для высокопроизводительных систем и больших корпоративных доменов. Позволяет получать максимум атрибутов пользователя (телефон, департамент, фото) за один запрос.

PowerShell (Способ 3) — наиболее простой в отладке метод для администраторов. Легко масштабируется и не требует глубоких знаний объектной модели ADSI.

Передача с клиента (Способ 6) — если список пользователей нужен однократно для формы, которую открыл пользователь, можно вызвать ПользователиОС() на клиенте и передать массив на сервер. Однако помните, что этот метод не подходит для фоновых заданий, так как там нет клиентского контекста.

При реализации любого из этих методов обязательно учитывайте контекст безопасности учетной записи службы 1C:Enterprise Server. Если код возвращает пустой список или ошибку "Доступ запрещен", необходимо проверить права системной учетной записи в домене или локальной политике безопасности сервера.

← На главную