Временная ошибка Active Directory при массовом использовании командлета ActiveDirectory - PullRequest
0 голосов
/ 26 ноября 2018

У меня есть система, которая синхронизирует пользователей из источника данных.Источник данных состоит из информации пользователя.Когда новый пользователь синхронизируется, запускается задача PowerShell, которая создает или обновляет пользователя.Это все нормально, но когда количество новых / обновленных пользователей становится слишком большим, некоторые задачи завершаются с некоторыми интересными ошибками, такими как:

"Сервер вернул следующую ошибку: недопустимый контекст перечисления. "

или

" Соединение с каталогом, в котором обрабатывается запрос, было недоступно. Вероятно, это временное условие. "

При устранении неполадок кажется очевидным, что причиной возникновения этих ошибок является нехватка ресурсов.Это связано с тем, что все одновременно запускаемые задачи импортируют модуль в свой сеанс PS.

Итак, я попробовал разные вещи и измерил скорость Import-Module и т. Д. Итак, я пришел к выводу, что быстрее запустить Import-Module, а затем, например, Get-ADUser, затем просто Get-ADUser (чтотакже импортирует модуль).

Measure-Command {Import-Module ActiveDirectory}

Среднее время 340 мс

Measure-Command {Get-ADUser -Filter *}

Среднее время 420 мс

Get-ADUser после того, как модуль импортирован

Среднее время 10 мс

Но эти предельные различия не помогут.Так что мне пришлось смотреть дальше.Я считаю, что отключение диска может помочь ускорить процесс, поэтому я добавил следующее перед импортом модуля:

$Env:ADPS_LoadDefaultDrive = 0
Measure-Command {Import-Module ActiveDirectory}

Среднее время 85 мс

В 4 раза быстрее!Но все же ошибка сохраняется при большом количестве пользователей одновременно (например, 50 задач).Поэтому я подумал об опросе доступности в скрипте или создании цикла do..while.Или, может быть, система, которая запускает отдельные задачи, должна быть переработана, чтобы иметь какую-то очередь.

Кто-нибудь знает эту ситуацию?Или есть какие-то мысли, которыми они хотели бы поделиться на эту тему?

1 Ответ

0 голосов
/ 26 ноября 2018

Это потому, что все одновременно запускаемые задачи импортируют модуль в свой сеанс PS.

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

  1. Ограничить количество задач, которые запускаются одновременно (возможно, 5 одновременно).
  2. Сделать это одной задачей, которая может работать с несколькимиСчета.Таким образом, модуль загружается только один раз.

Я думаю, что вариант 2 - лучшее решение.Например, вместо того, чтобы запускать сценарий сразу, ваша задача синхронизации может просто записать имя пользователя в файл (или даже в память), а после того, как он найдет всех пользователей, он запускает сценарий PowerShell и передает список (или сценарий).мог прочитать файл, который был записан).У вас есть варианты - все, что работает лучше.

Обновление: Весь .NET доступен в PowerShell, поэтому другой вариант - изменить весь сценарий на использование .NET DirectoryEntry вместомодуль ActiveDirectory, который будет использовать гораздо меньше памяти.Есть даже ярлыки для этого в PowerShell.Например, [ADSI]"LDAP://$distinguishedName" создаст для пользователя объект DirectoryEntry.Это существенная перезапись, но производительность намного выше (скорость и потребление памяти).

Вот несколько примеров поиска с помощью DirectorySearcher (с использованием ярлыка [ADSISearcher]): https://blogs.technet.microsoft.com/heyscriptingguy/2010/08/23/use-the-directorysearcher-net-class-and-powershell-to-search-active-directory/

А вот пример создания учетных записей с DirectoryEntry: https://www.petri.com/creating-active-directory-user-accounts-adsi-powershell

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