获取多个用户的上次登录时间戳

时间:2016-08-24 18:03:00

标签: function loops powershell memory active-directory

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

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

对此函数的调用来自foreach循环,该循环从我在函数调用之前提取的列表中发送每个用户。提前感谢您提供的任何帮助。

$ domain变量,只是假装它是" 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
}

1 个答案:

答案 0 :(得分: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'