Как видно из ошибки, вы получаете ADServerDownException
.Вы можете перехватывать и обрабатывать определенные исключения, например, такие:
try {
$currentUser = Get-ADUser $user.SamAccountName |
Get-ADObject -Server $hostname -Properties lastLogon
} catch [Microsoft.ActiveDirectory.Management.ADServerDownException] {
# handle AD server unreachable
} catch {
# handle all other exceptions
}
Одеяло catch
в конце может быть опущено, если вы хотите, чтобы все другие исключения просто передавались вызывающей стороне, а не обрабатывали их самостоятельно.
Это, однако, не ускорит ваш код, потому что исключение будет выдано только после истечения времени ожидания.Чтобы уменьшить время выполнения вашего кода, вы можете
проверить, доступен ли сервер, прежде чем пытаться с ним взаимодействовать, например,
if (Test-Connection -Computer $hostname -Count 2 -Quiet) {
$currentUser = ...
...
}
используйте фоновые задания для параллельного выполнения операций
$jobs = foreach ($dc in $dcs) {
Start-Job -ScriptBlock {
Param($username, $hostname)
Get-ADUser $username |
Get-ADObject -Server $hostname -Properties lastLogon
} -ArgumentList $user.SamAccountName, $dc.HostName
}
$jobs | Wait-Job | Receive-Job
$jobs | Remove-Job
Однако, возможно, самое большое узкое место в вашем коде - это то, что он сначала получает всех пользователей из AD (Get-ADUser -Filter *
), затем запрашивает каждого пользователя индивидуально снова для каждого DC (Get-ADUser $user.SamAccountName
), , а затем выполняет фактический запрос к конкретному DC (Get-ADObject
).
Вы должны быть в состоянии значительно ускорить код, выполнив всего один запрос для всех пользователей к каждому DC.Сгруппируйте результаты по SamAccountName
и выберите запись с самой последней отметкой времени из каждой группы, затем экспортируйте результаты в CSV.
$fltr = '(&(objectClass=user)(objectCategory=person))'
$props = 'SamAccountName', 'LastLogon'
Get-ADDomainController -Filter * |
Select-Object -Expand HostName |
Where-Object { Test-Connection -Computer $_ -Count 2 -Quiet } |
ForEach-Object { Get-ADObject -LDAPFilter $fltr -Properties $props -Server $_ } |
Select-Object Name, SamAccountName,
@{n='LastLogon';e={[DateTime]::FromFileTime($_.LastLogon)}} |
Group-Object SamAccountName |
ForEach-Object { $_.Group | Sort-Object LastLogon | Select-Object -Last 1 } |
Export-Csv $exportFilePath -NoType