【问题标题】:Powershell - latest lastLogon from multiple DCsPowershell - 来自多个 DC 的最新 lastLogon
【发布时间】:2022-01-23 13:08:22
【问题描述】:

我需要将我域中所有 PC 的一些属性导出到 *.csv 表。 lastLogOn 是必需的属性之一。问题是我有两个域控制器,所以我需要从中选择最新的 lastLogOn。

我有一个解决方案,但需要很长时间(大约 1 分钟)才能为我提供最终的计算机阵列。这里是:

function getComputers([string]$dc) {
    return Get-ADComputer -SearchBase ‘DC=mydomain,DC=com’ -Server $dc -Filter * `
    -Properties name, samAccountName, DistinguishedName, lastLogOn, OperatingSystem | `
    Sort samAccountName
}
function getComputersFromsBothDCs {
    $compsDC1 = getComputers 'dc1'
    $compsDC2 = getComputers 'dc2'
    $comps = @()
    for ($i = 0; $i -le $compsDC1.Length - 1; $i++) {
        $comp1 = $compsDC1[$i]
        $comp2 = $compsDC2[$i]
        if ($comp1.lastLogOn -ge $comp2.lastLogOn) {
            $comps += $comp1
        } else {
            $comps += $comp2
        }
    }
    return $comps
}

$comps = getComputersFromsBothDCs
# Then export and some other stuff

getComputers功能每1个DC大约需要1秒,主要问题是选择lastLogon最新的PC。

有没有更快的解决方案?

【问题讨论】:

标签: powershell active-directory


【解决方案1】:

试试这个,应该会跑得更快。考虑一下,这个脚本只会找到设置了 lastLogon 属性的计算机,它还会添加一个新属性 (LastLogonDate),它是 lastLogon 的转换FromFileTime。

$AllDCs = Get-ADDomainController -Filter * # Get all DCs in the Domain
$logons = [System.Collections.Generic.Dictionary[string,object]]::new()

$params = @{
    LDAPFilter = '(LastLogon=*)' # Only find computers that have this Property
    SearchBase = 'DC=mydomain,DC=com'
    Properties = @(
        'Name'
        'samAccountName'
        'DistinguishedName'
        'lastLogon'
        'OperatingSystem'
    )
}

foreach($DC in $AllDCs)
{
    $params.Server = $DC
    # Find all computers using this target DC
    $computerList = Get-ADComputer @params |
    Select-Object @(
        $params.Properties
        @{
            Name = 'LastLogonDate'
            Expression = { [datetime]::FromFileTime($_.LastLogon) }
        }
    )
    
    foreach($computer in $computerList)
    {
        if($logons[$computer.samAccountName].lastLogonDate -lt $computer.lastLogonDate)
        {
            # On first loop iteration should be always entering this
            # condition:
            # $null -lt $true # => True
            # Assuming $computer.LastLogon is always a populated attribute
            # which also explains my LDAPFilter = '(LastLogon=*)' from before

            $logons[$computer.samAccountName] = $computer
        }
    }
}

$logons.Values # => Is your export

【讨论】:

  • 第一次查询lastlogonTimeStamp 可能会更有效。然后对于任何小于 14 天的值,查询每个计算机帐户的每个域控制器并进行算术运算。比较方法之间的执行时间会很有趣。我并不是说这种方法很糟糕,只是想知道它是否可以更有效一点。这取决于是否有很多陈旧的计算机帐户,我预计。
  • @LeeM 我不会为此使用lastlogon,只需遵循 OP 的代码即可。问题是,iirc lastLogonTimeStamp 和我相信 lastLogon 也不会跨域控制器复制,过滤器必须不那么严格,才能找到以前在其他 DC 上找不到的计算机。但我同意,它会改善运行时间。
  • LastLogonTimeStamp is 实际上已复制 - 这就是为什么它最多延迟 14 天(LastLogon 是未复制的最新 per-DC 属性)。如果您使用的是 AD Powershell 模块,它也别名为 LastLogonDate,所以我建议您不要在翻译 LastLogon 的代码中使用相同的别名 - 一开始我对此感到困惑。 AD-PS LastLogonDate 是 LastLogonTimeStamp 作为 [datetime] 属性。 social.technet.microsoft.com/wiki/contents/articles/…
【解决方案2】:

我们可以按照下面的方法获取最新Lastlogon值的电脑

(1)- 从两个 DC 获取 ADComputers 列表并将结果保存在单个变量中

$DCs = ("DC01,"Dc02")
$ComputersList = @()

foreach ($DC in $DCs){
    $ComputersList += Get-ADComputer -filter {Enabled -eq $true } -Properties lastlogon,OperatingSystem -Server $DC | where {$_.lastlogon -ne $null} | Sort-Object -Property SamAccountName
}

(2) - 按 SamAccountName 属性对对象进行分组,并按“lastlogon”属性对分组结果进行排序,然后仅选择最新值

$LatestList = $ComputersList | Group-Object -Property SamAccountName | % {$_.group | Sort-Object -Property lastlogon | select -Last 1}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-16
    • 1970-01-01
    • 2013-06-06
    • 1970-01-01
    • 2014-09-16
    • 2017-06-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多