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

递归PowerShell函数无法自调用:AD OU结构遍历失败排查

问题排查与修正方案

原代码核心问题分析

  1. DN数组操作逻辑错误:
    原代码中$ChildOUs | ForEach-Object{$_.DN.Remove($_.Name)}会移除当前OU名称,导致子OU的DN列表残留父OU名称,触发if($cOU.DN){ Continue }被跳过,直接忽略子OU的处理。
  2. 递归参数传递错误:
    调用递归函数时未将当前OU名称作为新的父OU传递,而是沿用初始的$ParentOU,导致缩进和子OU筛选完全失效。
  3. 缩进逻辑不足:
    仅用固定空格区分有无父OU,无法适配多层嵌套的缩进需求。
  4. 子OU筛选不准确:
    使用$_.DN -contains $Parent无法精准匹配直接父OU,因为DN数组是叶子到根的顺序,容易误匹配非直接父级的OU。

修正后的完整代码

function Display-OU {
    param(
        [String]$ParentOU,
        [PSObject[]]$AllOUs,
        [int]$Depth = 0
    )
    # 根据递归深度计算缩进,每深一层增加2个空格
    $spacing = "  " * $Depth

    # 筛选当前父OU下的直接子OU
    $childOUs = if ($ParentOU) {
        $AllOUs | Where-Object { $_.ParentOU -eq $ParentOU }
    } else {
        # 顶级OU:直接隶属于域的OU(无父OU)
        $AllOUs | Where-Object { -not $_.ParentOU }
    }

    foreach ($ou in $childOUs) {
        # 输出当前OU(带对应缩进)
        "$spacing$($ou.Name)"
        # 递归处理当前OU的子OU,深度+1
        Display-OU -ParentOU $ou.Name -AllOUs $AllOUs -Depth ($Depth + 1)
    }
}

# 获取所有OU并预处理父OU信息
$rawOUs = Get-ADOrganizationalUnit -Filter * | Select-Object Name, DistinguishedName

$processedOUs = foreach ($ou in $rawOUs) {
    # 拆分DistinguishedName,提取所有OU层级(去掉DC部分)
    $ouHierarchy = ($ou.DistinguishedName -split ',') | Where-Object { $_ -match '^OU=' } | ForEach-Object { $_ -replace '^OU=' }
    # 直接父OU是层级中的第二个元素(DistinguishedName格式为 OU=子,OU=父,...)
    $parentOU = if ($ouHierarchy.Count -gt 1) { $ouHierarchy[1] } else { $null }

    [PSCustomObject]@{
        Name     = $ou.Name
        ParentOU = $parentOU
        Domain   = ($ou.DistinguishedName -split ',') | Where-Object { $_ -match '^DC=' } | ForEach-Object { $_ -replace '^DC=' } -join '.'
    }
}

# 按域分组输出OU结构
$processedOUs | Group-Object Domain | ForEach-Object {
    Write-Host "[$($_.Name)]"
    Display-OU -AllOUs $_.Group
}

修正说明

  1. 递归函数重构:
    • 新增$Depth参数控制缩进深度,支持任意多层嵌套的缩进格式。
    • 使用$AllOUs传递全量OU数据,避免修改原数据导致的筛选错误。
    • 通过ParentOU属性精准筛选直接子OU,逻辑清晰且不易出错。
  2. OU数据预处理:
    • 直接从DistinguishedName中提取每个OU的直接父OU名称,简化层级判断逻辑。
    • 正确拆分并拼接域名称,确保跨域场景下的分组输出正确。
  3. 递归逻辑修复:
    递归调用时传递当前OU名称作为新的ParentOU,同时将深度+1,保证缩进和子OU筛选的连贯性。

预期输出效果

针对示例OU结构,运行后会输出:

[Domain.local]
Domain Controllers
Users
  Internal
  External

内容的提问来源于stack exchange,提问作者Al D. J.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 03:31:37