#powershell
#powershell
Вопрос:
Я пытаюсь получить всех подрядчиков и сотрудников из нашего AD с включенным true для фильтра. Сам AD очень большой и содержит много данных, что может привести к ограничению времени ожидания при запуске сценария powershell. Я получаю эту ошибку, когда я помещаю ее в переменную, и если я выполняю прямой экспорт, я получаю ограничение по времени ожидания.
Есть ли какой-либо способ собрать все данные подрядчика и сотрудника с включенными сотрудниками с big AD без возникновения этой проблемы? Я получаю вывод, но не уверен, что вывод осуществим, поскольку я получаю сообщение об ошибке.
Спасибо
Param(
[Parameter(Mandatory = $true,ValueFromPipeline = $false,HelpMessage = "Specify a output file name and path.")]
[string]
$OutputFileNamePath = $null
)
$Storage = @()
Write-Host "**********************************************************" -ForegroundColor Green
Write-Host "* On Process *" -ForegroundColor Green
Write-Host "**********************************************************" -ForegroundColor Green
$filter = @("CONTRACTOR", "EMPLOYEE")
$Storage = Get-ADUser -Filter * -Properties EmployeeNumber,Name,SamAccountName,employeeType,PasswordLastSet,LastLogonDate | Where {($_.Enabled -eq $True) -and $filter -contains $_.employeeType} | Select EmployeeNumber,Name,SamAccountName,employeeType,PasswordLastSet,LastLogonDate
$Storage | Export-Csv -Path $OutputFileNamePath".csv" -Force
Write-Host "**********************************************************" -ForegroundColor Green
Write-Host "* Done *" -ForegroundColor Green
Write-Host "**********************************************************" -ForegroundColor Green
Ответ №1:
Эта статья TechNet дает нам подсказку о том, почему может возникнуть эта ошибка, в основном:
- Get-ADUser использует подкачку (по умолчанию 256 объектов на страницу)
- Запрашивать новые страницы должен клиент
- При конвейерной передаче объектов AD чем дольше обрабатывается код в конвейере, тем медленнее мы извлекаем данные из веб-служб Active Directory
- Если из-за более медленной обработки время поиска превышает 30 минут, то контекст перечисления истекает
Скорее всего, ваш запрос выполняется в течение 30 минут, что приводит к этому исключению. Решение этой проблемы заключается в создании более эффективного запроса, чтобы он завершался до этого времени или, что не рекомендуется MS:
Увеличьте значение «MaxEnumContextExpiration» для веб-службы Active Directory. Есть много причин не использовать этот подход.
Вы можете использовать LDAPFilter
для повышения производительности вашего запроса, Where-Object
в этом случае использование не требуется:
$properties = 'EmployeeNumber', 'employeeType', 'PasswordLastSet', 'LastLogonDate'
$filter = '(amp;(!userAccountControl:1.2.840.113556.1.4.803:=2)(|(employeeType=CONTRACTOR)(employeeType=EMPLOYEE)))'
Get-ADUser -LDAPFilter $filter -Properties $properties
Чтобы преобразовать фильтр LDAP во что-то читаемое:
amp;
— Логический И Операторный|
— Логический оператор OR(!userAccountControl:1.2.840.113556.1.4.803:=2)
— Включен пользовательский объект(|(employeeType=CONTRACTOR)(employeeType=EMPLOYEE))
—employeeType
является «Подрядчиком» ИЛИ «сотрудником»(amp;(...)(|(...)(...)))
— Все предложения должны быть выполнены. Мы можем прочитать это как:
(Пользователь включен) И (пользовательemployeeType
— «Подрядчик» ИЛИ «Сотрудник»)
Для дальнейшего использования Active Directory: фильтры синтаксиса LDAP
Комментарии:
1. Спасибо! Это работает для меня!
2. @Den10102020 рад помочь 😉
Ответ №2:
Я изменил ваш скрипт, но я просто собрал всех пользователей в $Users
массив, а затем запустил ForEach
цикл для каждого отдельного пользователя. Внутри есть If
функция, которая проверяет, включен ли пользователь и что EmployeeType является -like
CONTRACTOR или EMPLOYEE . Если они есть, он добавляет их в $Storage
массив, а затем экспортирует его после завершения цикла.
У меня это сработало, но дайте мне знать, если у вас возникнут какие-либо вопросы:
Param(
[Parameter(Mandatory = $true,ValueFromPipeline = $false,HelpMessage = "Specify a output file name and path.")]
[string]
$OutputFileNamePath = $null
)
$Storage = @()
Write-Host "----------------------------------------------------------" -ForegroundColor Green
Write-Host "- On Process -" -ForegroundColor Green
Write-Host "----------------------------------------------------------" -ForegroundColor Green
$Users = Get-ADUser -Filter * -Properties EmployeeNumber,Name,SamAccountName,employeeType,PasswordLastSet,LastLogonDate
Foreach($user in $users){
If(($User.Enabled -eq $True) -and (($User.EmployeeType -like "*CONTRACTOR*") -or (($User.EmployeeType -like "*EMPLOYEE*")))){
$Storage = $User
}
}
$Storage | Export-Csv -Path $OutputFileNamePath".csv" -NoTypeInformation -Force
Write-Host "----------------------------------------------------------" -ForegroundColor Green
Write-Host "- Done -" -ForegroundColor Green
Write-Host "----------------------------------------------------------" -ForegroundColor Green
Комментарии:
1. Привет, Джош! Спасибо за помощь, но у меня такая же проблема на моей стороне. Решение LDAP работает для меня
2. @Den10102020 Нет проблем! Я видел комментарий выше, рад, что он смог определить, в чем заключалась ошибка, и помочь вам ее устранить.
3. Он отличное соединение! Большинство моих проблем с PowerShell были решены г-ном Скварзоном