powershell - 在具有多个受信任的林和域的网络中为数百万 AD 组获取 AD 成员资格的更快方法

标签 powershell active-directory ldap

首先,我无法了解为什么需要这些数据,也无法了解有关网络的细节。您必须相信我,除了运行 LDAP 查询的 PowerShell 脚本之外,没有其他方法可以获取这些数据。

我正在使用具有多个林和多个域的网络。所有森林之间都存在信任。我登录到其中一个森林的一个域,但由于信任,我可以查询所有这些域。

我有一个包含数百万广告组的 CSV 文件。我需要找到数百万广告组中每个人的所有直接成员。很多成员都是跨域的,这意味着我不能只使用 member AD 组的属性,而是必须查询每个域并检查 memberOf .

我有一个获取这些数据的 PowerShell 脚本。由于各种原因,我无法分享我的代码,但它的作用如下:

  • 创建 System.DirectoryServices.DirectorySearcher 的数组我所有域的对象
  • 遍历包含每个 AD 组及其 DN 列表的 CSV 文件
  • 对于每个 DN , 循环 DirectorySearcher数组并查找所有属于 memberOf 的对象那个 DirectorySearcher 中的 AD 组( (memberOf=$adGroupDN) )

  • 该代码有效。但是由于我正在处理一个包含数百万广告组的输入列表,所以脚本非常慢。根据我的测试运行计算,获得我需要的所有数据需要 2 周多的时间。

    我想知道是否有更好/更快的方法来做到这一点?

    我想也许我可以使用线程或其他东西,但我不确定这是否会有所帮助,也不知道从哪里开始。

    非常感谢任何建议。

    添加一些额外的细节...
  • 我的输入列表是数百万个唯一组 DN
  • 我有多个不同的森林/域
  • 我的输入组 DN 分布在所有森林/域
  • 我的组 DN 输入列表中的组跨越不同的林/域(我的输入列表中的 domain1\group1domain2\group2 作为成员)
  • 我需要获得 完整我的输入列表
  • 中的组中的每个组的列表
  • 由于跨域成员资格,我不能依赖 member我的输入组的属性。我知道获得它的唯一方法是查询所有组的每个 DC/域 memberOf我的输入列表中的组。
  • 我只能使用 PowerShell
  • 我没有 ActiveDirectory 模块,只能使用 .NET DirectorySearcher
  • 在高层次上,我的代码如下所示:
    $arrayOfDirectorySearcherObjectsForEachDCInMyNetwork = ... code to create an array of System.DirectoryServices.DirectorySearcher objects, one for each DC/domain in my network
    
    Foreach ($groupDN in $inputListOfUniqueGroupDNs)
    {
        Foreach ($domain in $arrayOfDirectorySearcherObjectsForEachDCInMyNetwork)
        {
            ...
    
  • 我能想到让它更快的唯一方法是多线程第二个 for 循环,它使用运行空间同时查询多个 DC/域,但我不知道如何做到这一点......
  • 最佳答案

    如果可以的话,在域 Controller 上运行脚本会给您带来一点优势。但否则多线程可能是你最好的选择。

    研究使用 Start-Job .有一个例子here .

    也就是说,我质疑这个:

    A lot of memberships are cross-domain which means I cannot just use the member property of the AD group and have to, instead, query every domain and check for memberOf.



    组范围在这里很重要。如果您的所有组都是通用的,那么任何一种方式都不会产生影响(无论您查看组上的 member 还是查看用户上的 memberOf)。

    但重要的是要注意 memberOf不会显示不同域上的域本地组组(即使在同一个林中)。
    member组上的属性始终是成员的权威来源。是的,获取受信任域上帐户的详细信息有点困难,但可以做到。

    这是一个 PowerShell 函数,它将提取组中每个成员的“域\用户名”,包括嵌套组中的成员。
    function OutputMembers {
        param([string] $groupDn)
    
        foreach ($m in ([ADSI]("LDAP://" + $groupDn)).member) {
            $member = [ADSI]("LDAP://" + $m)
            $member.objectClass
            if ($member.objectClass -eq "group") {
                #this member is a group so pull the members of that group
                OutputMembers $member.distinguishedName
            } else {
                #"msDS-PrincipalName" is not loaded by default, so we have to tell it to get it
                $member.Invoke("GetInfoEx", @("msDS-PrincipalName"), 0)
                if ([string]::IsNullOrEmpty($member."msDS-PrincipalName")) {
                    #member is on a trusted domain, so we have to go look it up
                    $sid = New-Object System.Security.Principal.SecurityIdentifier ($member.objectSid[0], 0)
                    $sid.Translate([System.Security.Principal.NTAccount]).value
                } else {
                    $member."msDS-PrincipalName"
                }
            }
        }
    }
    

    这样,您可以使用 distinguishedName 调用该函数。每个组的,例如:
    OutputMembers "CN=MyGroup,OU=Groups,DC=domain,DC=com"
    

    关于powershell - 在具有多个受信任的林和域的网络中为数百万 AD 组获取 AD 成员资格的更快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48712248/

    相关文章:

    windows - 如何区分使用相同名称的不同进程?

    powershell - Robocopy 作为另一个用户

    azure - 在 Azure Active Directory 中正确实现 Multi-Tenancy

    oracle - 如何在 Oracle 中授权用户/应用程序组合?

    c - 此 LDAP 错误是什么意思? "00000057: LdapErr: DSID-0C090B0B, comment: Error processing control, data 0, v3839"

    azure - Windows 计算机文件复制 - DevOps 任务和 IP 地址

    用于从 csv 文件创建计划任务的 Powershell 脚本

    ldap - 使用带重音字符的 ldapsearch

    java - 如何使用 xml 配置文件、JAVA、Spring security 通过 LDAP 对用户进行身份验证

    具有ldap授权的Git