You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多OU查询AD禁用未登录计算机时的对象缺失与结果重复问题解决咨询

多OU查询AD禁用未登录计算机时的对象缺失与结果重复问题解决咨询

我来帮你拆解下遇到的两个核心问题:目标OU下的禁用计算机未出现在结果中,以及查询结果出现重复条目,结合你的代码和输出逐一分析解决:

一、结果重复的原因与解决方法

你的代码里同时指定了两个存在层级关系的OU:

$OUs = @(
    'OU=DISABLED COMPUTERS,OU=DISABLED,DC=CONTOSO,DC=DOMAIN'
    'OU=COMPUTERS,OU=DISABLED COMPUTERS,OU=DISABLED,DC=CONTOSO,DC=DOMAIN'
)

而Get-ADComputer的默认搜索范围(SearchScope)是Subtree——也就是会递归查询当前OU及其所有子OU的对象。这就导致:

  • 查询父OU(DISABLED COMPUTERS)时,已经把子OU(COMPUTERS)里的所有计算机都查出来了
  • 再单独查询子OU时,又把这些对象重复获取了一次
    最终输出自然就出现了重复条目。

解决重复的两种方案:

  1. 只查询父OU即可
    既然默认会递归子OU,完全不需要单独指定子OU,修改$OUs数组为只保留父OU:

    $OUs = @(
        'OU=DISABLED COMPUTERS,OU=DISABLED,DC=CONTOSO,DC=DOMAIN'
    )
    

    这样一次查询就能获取父OU和所有子OU的符合条件的对象,不会重复。

  2. 限制搜索范围为当前OU的直接对象
    如果确实需要同时查询多个独立OU(比如后续要扩展其他非层级OU),可以给Get-ADComputer加上-SearchScope OneLevel参数,让每个OU只查询直接下属的对象,不递归子OU:

    foreach ($OU in $OUs) {
        $inactiveComputers += Get-ADComputer -Properties LastLogonTimeStamp `
            -Filter {LastLogonTimeStamp -lt $LastLogonDate -and serviceprincipalname -notlike "*MSClusterVirtualServer*" -and Enabled -eq $false } `
            -SearchBase $OU `
            -SearchScope OneLevel | 
            Select-Object distinguishedName,Name, @{Name='LastLogonTimeStamp'; Expression={[DateTime]::FromFileTime($_.LastLogonTimeStamp)}}
    }
    

二、父OU下禁用计算机缺失的原因排查

你提到OU=DISABLED COMPUTERS下有一个禁用的计算机对象但未出现在结果中,大概率是这个对象不符合你的过滤条件,建议按以下步骤排查:

  1. 单独查询该对象,确认属性值
    运行以下命令查看这个计算机的关键属性:

    Get-ADComputer -Identity "那个缺失的计算机名" -Properties LastLogonTimeStamp, Enabled, serviceprincipalname
    

    重点检查:

    • Enabled是否为False(确认是禁用状态)
    • LastLogonTimeStamp是否存在,且转换为日期后确实早于90天前(如果该计算机从未登录过,LastLogonTimeStamp会是$null,这时候你的过滤条件LastLogonTimeStamp -lt $LastLogonDate会直接排除它)
    • serviceprincipalname是否包含MSClusterVirtualServer(如果包含会被过滤掉)
  2. 调整过滤条件,兼容未登录过的计算机
    如果该计算机从未登录过(LastLogonTimeStamp为$null),需要修改过滤条件,把这类对象也包含进来:

    -Filter { (LastLogonTimeStamp -lt $LastLogonDate -or LastLogonTimeStamp -notlike "*") -and serviceprincipalname -notlike "*MSClusterVirtualServer*" -and Enabled -eq $false }
    

    这里LastLogonTimeStamp -notlike "*"用来匹配$null或者空值的情况。

  3. 检查权限问题
    确认运行脚本的账号是否有读取该计算机对象属性的权限,权限不足也可能导致对象无法被查询到。

修改后的完整示例代码

结合上面的优化,最终的脚本可以写成这样:

$LastLogonDate = (Get-Date).AddDays(-90)
# 只查询父OU,自动递归子OU
$OUs = @(
    'OU=DISABLED COMPUTERS,OU=DISABLED,DC=CONTOSO,DC=DOMAIN'
)
$inactiveComputers = @()

foreach ($OU in $OUs) {
    $inactiveComputers += Get-ADComputer -Properties LastLogonTimeStamp `
        -Filter { (LastLogonTimeStamp -lt $LastLogonDate -or LastLogonTimeStamp -notlike "*") -and serviceprincipalname -notlike "*MSClusterVirtualServer*" -and Enabled -eq $false } `
        -SearchBase $OU | 
        Select-Object distinguishedName,Name, @{Name='LastLogonTimeStamp'; Expression={
            if ($_.LastLogonTimeStamp) { [DateTime]::FromFileTime($_.LastLogonTimeStamp) }
            else { "从未登录" } # 给未登录的对象标注说明
        }}
}

# 如果需要导出到CSV,加上这行
$inactiveComputers | Export-Csv -Path "InactiveDisabledComputers.csv" -NoTypeInformation -Encoding UTF8

$inactiveComputers

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 07:53:05