2017-03-09 81 views
3

我想从所有域控制器的所有Active Directory用户获取所有lastlogon日期。这将导致列出所有用户及其最新登录日期。我的脚本工作正常,但可以更平行呢?Parallelise Active Directory查询

目前,只有一个用户查询全部20个域控制器需要大约1秒的时间(Invoke-Parallel正在帮助很多)。

这里的问题是,我们有12万〜用户

下面是代码:

. '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 

你有一个想法,以更加快这?

+1

每个用户为什么搜索?为什么不在初始查询中检索所有用户的lastlogon属性? –

+0

因为您只能从一个域控制器获取最后一次登录日期。此属性不会同步到其他DC,因此每个DC都有一个用户唯一的lastlogon日期。 – psott

+2

我知道,但没有什么能阻止你一次做*每个域控制器* :-) –

回答

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 
    } 
} 
+0

看起来很有希望。我会尽快测试并尽快给出反馈。谢谢 – psott

+1

哇谢谢你!它快了10倍以上 – psott