简体   繁体   English

无法使用 C# 枚举 AD 组的成员

[英]Failure to enumerate AD Group's members using C#

Could you please help me?请你帮助我好吗? I am trying to enumerate an AD group's members from a remote machine by using the following code:我正在尝试使用以下代码从远程计算机枚举 AD 组的成员:

using (var entry = new DirectoryEntry(..
{
    foreach (object member in (IEnumerable)entry.Invoke("Members", null))
    {

This code works well except for one environment.除了一种环境外,此代码运行良好。

In this specific env, when I try to enumerate the members of an AD group, it throws the following exception:在这个特定的环境中,当我尝试枚举 AD 组的成员时,它会引发以下异常:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. System.Reflection.TargetInvocationException:调用的目标已抛出异常。

System.ArgumentException: Value does not fall within the expected range. System.ArgumentException: 值不在预期范围内。 --- End of inner exception stack trace --- --- 内部异常堆栈跟踪结束 ---

at System.DirectoryServices.DirectoryEntry.Invoke(String methodName, Object[] args)在 System.DirectoryServices.DirectoryEntry.Invoke(String methodName, Object[] args)

I run the same commands via power shell (script copied below) and got the same error:我通过 power shell(下面复制的脚本)运行相同的命令并得到相同的错误:

Exception calling "Invoke" with "2" argument(s): "Value does not fall within the expected range.使用“2”个参数调用“Invoke”的异常:“值不在预期范围内。

At C:\\Temp\\PSTest_AD_Group_Members2.ps1:23 char:5在 C:\\Temp\\PSTest_AD_Group_Members2.ps1:23 字符:5

  • $members = $DirectoryEntry.Invoke("Members", $null) $members = $DirectoryEntry.Invoke("Members", $null)
  • CategoryInfo : NotSpecified: (:) [], MethodInvocationException CategoryInfo : NotSpecified: (:) [], MethodInvocationException
  • FullyQualifiedErrorId : DotNetMethodTargetInvocation FullQualifiedErrorId : DotNetMethodTargetInvocation

Please note that请注意

  1. I tried reproduce it against several DCs in different domains unsuccessfully.我尝试在不同域中的几个 DC 上复制它,但没有成功。 It only happens in one specific environment它只发生在一种特定的环境中
  2. I tried searching for this exception online but did not find anything relevant我尝试在线搜索此异常,但没有找到任何相关内容
  3. I am using a domain admin to run this code我正在使用域管理员来运行此代码
  4. The code is running on Windows Server 2016 with latest updates代码在带有最新更新的 Windows Server 2016 上运行
  5. I have a PowerShell script that produce the same behavior (copied below)我有一个产生相同行为的 PowerShell 脚本(复制如下)
  6. I see no relevant entry in the event viewer indicating that something went wrong on both the source and target machines我在事件查看器中没有看到相关条目表明源计算机和目标计算机都出现了问题

Can someone help me understand why this code fail to get the AD group's members only in that one specific environment?有人可以帮助我理解为什么此代码无法仅在该特定环境中获取 AD 组的成员吗?

Is there a way on the DC side to understand what went wrong? DC方面有没有办法了解出了什么问题? perhaps a DC log for incoming/attempted commands?也许是传入/尝试命令的 DC 日志?

Thanks for your help谢谢你的帮助

=========================== powershell script ==============================

Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$cred = Get-Credential
$domain = "<domain name>"
$groupname = "<group name>"
$results = "<result csv file path>"

cls

$ctx = New-Object 'DirectoryServices.AccountManagement.PrincipalContext' ([DirectoryServices.AccountManagement.ContextType]::Domain, $domain, $cred.UserName, $cred.GetNetworkCredential().Password)
$timing = Measure-Command {$group = [System.DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity($ctx, $groupname)}
$props = [ordered]@{
    'Type' = $group.StructuralObjectClass
    'Name' = $group.SamAccountName
    'SID' = $group.sid
    'RetrivedIn(s)' = $timing.TotalSeconds
    'Retrievedcount' = $group.count
    'UserPrincipalName' = $group.UserPrincipalName
}
New-Object -TypeName PSObject -Property $props | Export-Csv -Path $results -NoTypeInformation

$timing = Measure-Command {
    $DirectoryEntry = New-Object System.DirectoryServices.DirectoryEntry ("LDAPS://$($group.DistinguishedName)", $cred.UserName, $cred.GetNetworkCredential().Password)
    
$members = $DirectoryEntry.Invoke("Members")
}

$props = [ordered]@{
    'Type' = $members.gettype().name
    'Name' = "GroupDirectoryEntry"
    'SID' = "n/a"
    'RetrivedIn(s)' = $timing.TotalSeconds
    'Retrievedcount' = ($members | Measure-Object).count
    'UserPrincipalName' = "n/a"
}
New-Object -TypeName PSObject -Property $props | Export-Csv -Path $results -Append -NoTypeInformation

$members |
ForEach-Object {
    $bytesSid = $_.gettype().InvokeMember("objectSid","GetProperty",$null,$_,$null)
    $sid = New-Object System.Security.Principal.SecurityIdentifier ($bytesSid, 0)
    $timing = Measure-Command {$acct = [DirectoryServices.AccountManagement.Principal]::FindByIdentity($ctx, 4, $sid.value)}
    $props = [ordered]@{
        'Type' = $acct.StructuralObjectClass
        'Name' = $acct.SamAccountName
        'SID' = $acct.Sid
        'RetrivedIn(s)' = $timing.TotalSeconds
        'Retrievedcount' = $acct.count
        'UserPrincipalName' = $acct.UserPrincipalName
    }
    New-Object -TypeName PSObject -Property $props | Export-Csv -Path $results -Append -NoTypeInformation
}
============================= end of powershell script ================================

Why not use GroupPrincipal instead of reflection?为什么不使用GroupPrincipal而不是反射?

It would be as simple as this:就像这样简单:

PrincipalContext ctx = new PrincipalContext(ContextType.Domain,                                                                      
                                            "fabrikam.com",   
                                            "DC=fabrikam,DC=com",   
                                            "administrator",   
                                            "SecretPwd123");  

GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx,   
                                                   IdentityType.Name,   
                                                   "Domain Admins");  

if (grp != null)  
{  
    foreach (Principal p in grp.GetMembers(true))  
    {  
         Console.WriteLine(p.Name);  
    }  
    grp.Dispose();  
}  

ctx.Dispose();

The error is pretty explanatory:该错误非常具有解释性:

target of an invocation.调用的目标。 That is the Members function那是Members函数

System.ArgumentException: Value does not fall within the expected range This most probably refers to the null value. System.ArgumentException:值不在预期范围内 这很可能是指null值。

I find out what was the problem.我找出了问题所在。 the troubled environment has a customization in its AD environment due to the use of a third-party product that prepares its active directory for support.由于使用了准备其活动目录以获得支持的第三方产品,问题环境在其 AD 环境中进行了自定义。 As part of the integration, it run an schema update that adds a "members" attribute to their AD schema.作为集成的一部分,它运行架构更新,将“成员”属性添加到其 AD 架构。 this is causing a conflict when we invoke members on the directory entry.当我们在目录条目上调用成员时,这会导致冲突。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM