![跨 AD 服务器的 Active Directory 上次登录复制](https://linux22.com/image/608027/%E8%B7%A8%20AD%20%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%9A%84%20Active%20Directory%20%E4%B8%8A%E6%AC%A1%E7%99%BB%E5%BD%95%E5%A4%8D%E5%88%B6.png)
我们需要运行一个查询,该查询将在 n 天不活动后自动禁用帐户。有人告诉我,由于我们有多个 AD 服务器,如果用户登录,比如说登录到 ADserver1,则上次登录信息不会复制到 ADserver2。我如何才能在所有 AD 服务器上复制上次登录信息?
答案1
这是 Richard Mueller 编写的 Powershell 脚本,我发现它很有用。它会查询您域中的所有 AD 服务器并报告所有用户/计算机的最近登录时间,因此可能需要进行一些手动编辑才能满足您的需求。不过,这是一个很好的起点。
# PSLastLogon.ps1
# PowerShell script to determine when each user in the domain last
# logged on.
#
# ----------------------------------------------------------------------
# Copyright (c) 2011 Richard L. Mueller
# Hilltop Lab web site - http://www.rlmueller.net
# Version 1.0 - March 16, 2011
#
# This program queries every Domain Controller in the domain to find the
# largest (latest) value of the lastLogon attribute for each user. The
# last logon dates for each user are converted into local time. The
# times are adjusted for daylight savings time, as presently configured.
#
# You have a royalty-free right to use, modify, reproduce, and
# distribute this script file in any way you find useful, provided that
# you agree that the copyright owner above has no warranty, obligations,
# or liability for such use.
Trap {"Error: $_"; Break;}
$D = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$Domain = [ADSI]"LDAP://$D"
$Searcher = New-Object System.DirectoryServices.DirectorySearcher
$Searcher.PageSize = 200
$Searcher.SearchScope = "subtree"
# Switch this to search for computers or users
$Searcher.Filter = "(&(objectCategory=computer))"
# $Searcher.Filter = "(&(objectCategory=user))"
$Searcher.PropertiesToLoad.Add("distinguishedName") > $Null
$Searcher.PropertiesToLoad.Add("lastLogon") > $Null
# Create hash table of users and their last logon dates.
$arrUsers = @{}
# Enumerate all Domain Controllers.
ForEach ($DC In $D.DomainControllers)
{
$Server = $DC.Name
$Searcher.SearchRoot = "LDAP://$Server/" + $Domain.distinguishedName
$Results = $Searcher.FindAll()
ForEach ($Result In $Results)
{
$DN = $Result.Properties.Item("distinguishedName")
$LL = $Result.Properties.Item("lastLogon")
If ($LL.Count -eq 0)
{
$Last = [DateTime]0
}
Else
{
$Last = [DateTime]$LL.Item(0)
}
If ($Last -eq 0)
{
$LastLogon = $Last.AddYears(1600)
}
Else
{
$LastLogon = $Last.AddYears(1600).ToLocalTime()
}
If ($arrUsers.ContainsKey("$DN"))
{
If ($LastLogon -gt $arrUsers["$DN"])
{
$arrUsers["$DN"] = $LastLogon
}
}
Else
{
$arrUsers.Add("$DN", $LastLogon)
}
}
}
# Output latest last logon date for each user.
$Users = $arrUsers.Keys
ForEach ($DN In $Users)
{
$Date = $arrUsers["$DN"]
If ($Date -eq "01/01/1601 00:00:00") {$Date = "1/1/1900 12:00:00"}
$DN = [regex]::Match($DN,'CN=([^,]+)').Groups[1].Value
"`"$DN`",$Date"
}
答案2
最后的登录信息会在域控制器之间自动复制。
如果它不在您的环境中,那么复制就会中断,并且检索用户的上次登录时间就是您最不关心的问题,因为您的 AD 实现已发生不可挽回的损坏(或者当您的域控制器开始相互墓碑化时很快就会发生损坏)。
顺便,看来这篇关于 lastLogontimestamp 的文章可能会让你感兴趣。
每次用户或计算机登录域时,lastLogontimeStamp 属性都不会更新。更新值的决定基于当前日期减去(ms-DS-Logon-Time-Sync-Interval 属性减去随机百分比 5)的值。如果结果等于或大于 lastLogontimeStamp,则更新该属性。对于 lastLogontimeStamp 的复制没有特殊考虑。如果更新了该属性,则像任何其他属性更新一样进行复制。
此属性不会被复制,而是在域中的每个域控制器上单独维护。要获取用户在域中的上次登录的准确值,必须从域中的每个域控制器检索用户的 Last-Logon 属性。检索到的最大值是该用户的真实上次登录时间。