排查PowerShell跨域重复AD机器查询的异常输出问题
排查PowerShell跨域查询重复AD机器异常的思路
兄弟,我来帮你捋捋这个问题——用PowerShell跨两个AD域找重复机器,还得挑登录最早的不活跃设备,结果输出不对,对吧?咱们一步步拆解可能踩的坑:
1. 先确认「重复机器」的判定逻辑是否准确
你是靠什么字段判断两台机器是“重复”的?是机器名Name?还是SamAccountName?或是安全标识符SID?
- 如果只按
Name匹配,跨域里很可能出现同名但实际是不同设备的情况(毕竟不同域的SID前缀不一样),这会直接导致你把非重复机器当成目标处理。得先明确你的“重复”定义:是同一台设备在两个域都有记录,还是只要名字相同就算?
2. 检查LastLogonTimestamp的处理是否正确
这个AD属性是个大坑,稍不注意就出问题:
- 数值转换:它是Int64类型的文件时间,必须用
[DateTime]::FromFileTime($_.LastLogonTimestamp)转成可读日期。如果直接拿原始数值比较,逻辑是对的,但如果转日期时漏了这一步,或者部分机器没转,就会出现异常。 - 空值/0值处理:有些机器的
LastLogonTimestamp会是0(表示从未登录或AD未同步该属性),转成日期会变成1601年,直接会被误判成“最早登录”的不活跃机器。你有没有提前过滤掉LastLogonTimestamp -eq 0的设备? - 跨域同步问题:不同域的DC之间,
LastLogonTimestamp的同步可能有延迟,如果你是从普通DC而非全局编录(GC)查询的,拿到的数值可能不是最新/最准确的。
3. 管道与Where-Object的逻辑是否有漏洞
你是怎么遍历两个数组找重复的?比如是不是用了嵌套循环?
foreach ($a in $DomainAComputers) { $match = $DomainBComputers | Where-Object { $_.Name -eq $a.Name } if ($match) { # 比较LastLogonTimestamp逻辑 } }
- 如果B域里有多个同名机器,
$match会是一个数组,这时候直接取$match.LastLogonTimestamp会拿到多个值,比较逻辑自然会乱。得先处理这种一对多的场景,比如只取匹配的第一个,或者明确筛选唯一目标。 - 另外,判断「不活跃」的布尔条件有没有问题?比如是不是用了
$lastLogon -lt (Get-Date).AddDays(-90)?要确保这里的$lastLogon是已经转好的DateTime类型,不然日期比较会失效。
4. 数组存储的属性是否完整
你在获取DomainAComputers和DomainBComputers的时候,有没有明确指定要拉取LastLogonTimestamp?
比如必须用:
$DomainAComputers = Get-ADComputer -Server "DomainA.com" -Properties LastLogonTimestamp, Name, SamAccountName -Filter *
如果没加-Properties LastLogonTimestamp,默认返回的AD计算机对象里没有这个属性,数组里的对应值就是null,后续比较肯定出问题。可以用$DomainAComputers[0] | Select-Object *查看属性是否正确获取。
5. 简化测试定位问题
建议先拿几个已知的重复机器做小范围测试:
# 取一台测试机器 $testA = $DomainAComputers | Where-Object { $_.Name -eq "TestPC01" } $testB = $DomainBComputers | Where-Object { $_.Name -eq "TestPC01" } # 输出关键属性,手动验证 Write-Host "A域TestPC01登录时间: $([DateTime]::FromFileTime($testA.LastLogonTimestamp))" Write-Host "B域TestPC01登录时间: $([DateTime]::FromFileTime($testB.LastLogonTimestamp))"
看看输出的时间是否符合你的预期,再对照脚本里的比较逻辑,就能快速定位是判断条件错了,还是属性获取出了问题。
内容的提问来源于stack exchange,提问作者Bean
相关产品推荐
相关产品推荐

