2016-08-24 35 views
0

以下代码将查询我的环境中的所有控制器,以确保获得最新的登录时间戳。它非常适合为我工作的奇怪用户获取数据。但是,我发现需要评估AD中的800多个用户。 它在完成之前会吃掉1.5gb,并使内存不足错误导致脚本崩溃。在函数完成后有没有办法回收内存,或者强制垃圾收集的方法?我曾尝试删除变量和其他变体。我试图强制偶尔的系统垃圾收集无济于事。获取多个用户的上次登录时间戳

我的猜测是所有的AD查询,只是不知道如何处理它们,一旦我完成。

对这个函数的调用来自一个foreach循环,这个foreach循环从我在函数调用之前拉出的列表中发送每个用户。预先感谢我的任何帮助。

的$域变量,只是假装它是“example.contoso.ca”

function getDateTimeStamp 
{ 
    param 
    (
    [string]$userID, 

    [string]$domain, 

    [string]$attribute #this is an AD attribute in this case i used "lastlogon" 
) 
$domainSuffix = '*.'+$domain 
    $myForest = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest() 
    $domaincontrollers = $myForest.Sites | % { $_.Servers } | Select-Object Name | Where-Object Name -like $domainSuffix 
    $realUserDate = $null 
    foreach ($domainController in $domainControllers) 
    { 
     $userDateTime = Get-ADUser -Identity $userID -Properties $attribute -Server $domainController.Name 
     $userLastDateTime = $userDateTime.$attribute 
     if($userLastDateTime -eq $null){$userLastDateTime = 0} 
     elseif($userLastDateTime -eq 9223372036854775807){$userLastDateTime = 0} 
     if($userLastDateTime -is 'DateTime'){$tempUserDate = get-date -Date ($userLastDateTime)} 
     else{$tempUserDate = [DateTime]::FromFileTime([Int64]::Parse($userLastDateTime))} 
     if ($realUserDate -le $tempUserDate){$realUserDate = $tempUserDate} 
    } 
    return $realUserDate 
} 
+0

见我的答案在这里,但尝试的foreach对象 http://superuser.com/questions/675484/why-does-foreach-object-behave-differently-when-called-as-foreach –

+0

我尝试foreach($物品$ x) ,我试过$ items | foreach-object {} 既没有在列表中一直工作。 – icomeinpieces

+0

我没有看到你定义'$ attribute'的地方。如果使用LastLogonDate作为'$ attribute',则不必将'[Int64]'转换为'[DateTime]'。另外,你需要确切的LastLogon,还是可以使用LastLogonTimestamp?这是重复的,并且在我相信的11天内准确无误。 – TheMadTechnician

回答

0

只是一个快速职,有点着急的。这是一个如何让你的函数进程成为管道的例子。如果它在管道上工作,则只需分配任何内存(几乎不需要)。

function Get-ADDateTime 
{ 
    param 
    (
     [Parameter(ValueFromPipelineByPropertyName = $true)] 
     [Alias('SamAccountName')] 
     [string]$userID, 

     [Parameter(Mandatory = $true)] 
     [string]$domain, 

     [Parameter(Mandatory = $true)] 
     [string]$attribute 
    ) 

    begin { 
     $domainSuffix = '*.'+$domain 
     $myForest = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest() 
     $domaincontrollers = $myForest.Sites.Servers | Where-Object Name -like $domainSuffix 
    } 

    process { 
     # Pick an epoch, any epoch 
     $date = Get-Date '01/01/1601' 
     foreach ($domainController in $domainControllers) 
     { 
      $adUser = Get-ADUser -Identity $userID -Properties $attribute -Server $domainController.Name 
      if ($adUser.$attribute -notin $null, 9223372036854775807, 0) { 
       if ($adUser.$attribute -is [DateTime]) { 
        $thisDate = $adUser.$attribute 
       } else { 
        $thisDate = [DateTime]::FromFileTime([Int64]::Parse($adUser.$attribute)) 
       } 

       if ($thisDate -gt $date) { 
        $date = $thisDate 
       } 
      } 
     } 
     if ($date -eq (Get-Date '01/01/1601')) { $date = $null } 

     [PSCustomObject]@{ 
      UserID = $UserID 
      LastLogon = $date 
     } 
    } 
} 

Get-ADUser | Get-ADDateTime -Attribute $lastLogon -Domain 'domain'