Извлечь список пользователей (миллионы) в Active Directory с помощью Powershell

У нас есть Active Directory с 5 миллионами пользователей. Мы получаем сообщение об ошибке «Get-ADUser: эта операция возвращена из-за истечения времени ожидания» при попытке извлечь пользователей с помощью сценария powershell.

Уже пробовал искать в сети оптимизированный скрипт. Ниже то, что у нас есть. Это отлично работает для ~ 500 тыс. пользователей.

Import-Module ActiveDirectory

$Users = Get-ADUser -SearchBase "CN=Users,DC=*****,DC=*****,DC=*****" -Server "*****" -ResultPageSize 1 -LDAPFilter "(&(objectCategory=User)(whenCreated>=20190101000000.0Z)(whenCreated<=20190131235959.0Z))" -Properties WhenCreated | Select-Object Name, WhenCreated

$Users | Export-Csv C:\Temp\January2019.csv -NoTypeInformation

Почему вы устанавливаете ResultPageSize на 1 ?? С таким количеством пользователей я бы предпочел увеличить значение по умолчанию 256 до [Int32]::MaxValue (2147483647). См. Get-ADUser

Theo 08.04.2019 10:05

Я уже пытался изменить его значение на 100/500/1000, а также не использовать ResultPageSize, но все равно получил ошибку.

jeen15 08.04.2019 10:38

вместо этого попробуйте adsisearcher и размер ResultPage от 200 или меньше до 100

alexsuslin 08.04.2019 12:30

Будет ли это работать, если вы направите Get-ADuser напрямую в csv, а не сохраните его в переменной? Вы также можете попробовать увеличить доступную для powershell память: vmwareinsight.com/Tips/2016/6/5798868/…

Scepticalist 08.04.2019 13:16

В вашей организации, вероятно, есть много дочерних подразделений внутри Users OU. Возможно, было бы лучше создать массив этих вложенных OU и перебирать их по одному, добавляя в CSV-файл по ходу дела.

Theo 08.04.2019 14:07
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
1 331
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Get-ADUser и все другие командлеты, которые PowerShell предоставляет вам, удобны, но ужасны, когда дело доходит до производительности.

Вам лучше использовать .NET DirectorySearcher, для которого в PowerShell есть сокращение: [ADSISearcher]. Кода больше, да, но на много быстрее. Вот пример, который должен делать то, что вы хотите (не забудьте изменить первые две строки для вашего подразделения и сервера):

$server = "****"
$ou = "CN=Users,DC=*****,DC=*****,DC=*****"

$searcher = [ADSISearcher]"(&(objectCategory=User)(whenCreated>=20190101000000.0Z)(whenCreated<=20190131235959.0Z))"
$searcher.PropertiesToLoad.Add("whenCreated") #We only want the whenCreated attribute
$searhcer.PageSize = 200 #Get the users in pages of 200
$searcher.SearchRoot = [ADSI]"LDAP://$server/$ou"

$ADObjects = @()
foreach($result in $searcher.FindAll()) {
    #The SearchResultCollection doesn't output in PowerShell very well, so here we create
    #a PSObject for each results with the properties that we can export later

    [Array]$propertiesList = $result.Properties.PropertyNames
    $obj = New-Object PSObject
    foreach($property in $propertiesList) { 
        $obj | add-member -membertype noteproperty -name $property -value ([string]$result.Properties.Item($property))
    }
    $ADObjects += $obj
}

$ADObjects | Export-Csv C:\Temp\January2019.csv -NoTypeInformation
Ответ принят как подходящий

Спасибо за вашу помощь. Вместо использования Get-ADUser я смог без проблем извлекать пользователей с помощью CSVDE (вариант LDIFDE, который позволяет экспортировать данные в файлы CSV).

CSVDE -f D:\Temp\ADUseru.csv -d "CN=Users,DC=*****,DC=*****,DC=*****" -r "(&(objectClass= пользователь)(objectCategory=person)(whenCreated>=20120101000000.0Z)(whenCreated<=20121231235959.0Z))" -l "имя, whenCreated, memberOf, sAMAccountName"

Другие вопросы по теме