我想从所有域控制器的所有Active Directory用户获取所有lastlogon日期。这将生成包含所有用户及其最新登录日期的列表。我的脚本工作正常,但是可以将它更多地并行化吗?
目前只需一个用户查询所有20个域控制器大约需要1秒钟(Invoke-Parallel正在帮助很多)。
这里的问题是我们有~120k用户
以下是代码:
. 'D:\scripts\InPa\Invoke-Parallel-lite-nolog.ps1'
function Get-UsersLastLogon{
$AllDCs = ([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().domainControllers).Name
$AllUser = ((New-Object System.DirectoryServices.DirectorySearcher("(&(objectCategory=User))")).FindAll().Properties).samaccountname
foreach($SamAccountName in $AllUser){
$Latest = $AllDCs | Invoke-Parallel -Throttle 60 -ScriptBlock {
$de=[adsi]"LDAP://$_"
$UserSeacher = (New-Object System.DirectoryServices.DirectorySearcher($de,"(&(objectCategory=User)(samaccountname=$Using:SamAccountName))")).FindAll().Properties
$co = New-Object System.Object
$co | Add-Member -type NoteProperty -name SamAccountName -value $Using:SamAccountName
$co | Add-Member -type NoteProperty -name lastlogon -value ([datetime]::FromFileTime([string]$UserSeacher.lastlogon))
$co
}
$Latest | Sort-Object -Property lastlogon -Descending | Select-Object -First 1
}
}
Get-UsersLastLogon | Export-Csv -Path D:\UsersLastLogon.csv -Delimiter ';' -NoTypeInformation
你有想法加快这个速度吗?
答案 0 :(得分:6)
假设您有20个域控制器,那么您目前正在进行20 * 120000 + 2个LDAP查询 - 这几乎是250个查询。
您可以执行的操作是查询每个DC 一次,并按照每个DC一次性检索所有用户:
function Get-UsersLastLogon{
# Gather all DC names
$AllDCs = ([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().domainControllers).Name
# In parallel, query the DCs for ALL users
$AllEntries = $AllDCs | Invoke-Parallel -Throttle 60 -ScriptBlock {
$de=[adsi]"LDAP://$_"
$UserSeacher = New-Object System.DirectoryServices.DirectorySearcher($de,"(&(objectCategory=User))")
[void]$UserSeacher.PropertiesToLoad.Add('lastLogon')
$Users = $UserSeacher.FindAll().Properties
foreach($User in $Users){
New-Object psobject -Property @{
SamAccountName = $User.SamAccountName
LastLogon = ([datetime]::FromFileTime([string]$User.lastlogon))
}
}
}
# Group all the results by user name
foreach($UserEntry in $AllEntries |Group-Object SamAccountName){
# Emit the newest entry per username
$UserEntry.Group |Sort-Object -Property LastLogon -Descending | Select-Object -First 1
}
}