root.local
的域rootgroup
(即ROOT\rootgroup
)child.root.local
,其中包含childuser
成员的用户CHILD\childuser
(即ROOT\rootgroup
)。PrincipalContext
,并且希望能够根据其SID解析ROOT\rootgroup
。我在PowerShell中使用Get-ADGroup进行了快速的健全性测试,以验证通过全局编录端口似乎可以获得正确的结果
$> Get-ADGroup –Server child.root.local -Filter 'sid -eq $groupSid'
$> # No result
$> Get-ADGroup –Server child.root.local:3268 -Filter 'sid -eq $groupSid'
DistinguishedName : CN=rootgroup,CN=Users,DC=root,DC=local
GroupCategory : Security
GroupScope : Universal
Name : rootgroup
ObjectClass : group
ObjectGUID : 0c65063f-4ba9-4469-a3a5-142f6f8efaf5
SamAccountName : rootgroup
SID : S-1-5-21-2643412326-2562497744-373403-4104
$>
一切似乎都很好所以我在我的C#项目中使用使用域和端口构建的PrincipalContext
实现了它,但是当我去测试代码时它失败了。为了简化操作并清除执行用户权限等错误,我在PowerShell中对相关逻辑进行了原型设计。
dsam = "System.DirectoryServices.AccountManagement"
$rtn = [reflection.assembly]::LoadWithPartialName($dsam)
$domain = "child.root.local:3268"
$context = New-Object System.DirectoryServices.AccountManagement.PrincipalContext( `
[System.DirectoryServices.AccountManagement.ContextType]::Domain, `
$domain)
$user = [System.DirectoryServices.AccountManagement.UserPrincipal]::FindByIdentity( `
$context, `
[System.DirectoryServices.AccountManagement.IdentityType]::SamAccountName, `
"child\childuser")
$obj = $user.GetUnderlyingObject() -as [System.DirectoryServices.DirectoryEntry]
$obj.RefreshCache(@("tokenGroups"))
$groups = $obj.Properties["tokenGroups"]
for ($i=0; $i -lt $groups.Count; $i++)
{
$sid = New-Object System.Security.Principal.SecurityIdentifier($groups[$i],0)
$group = [System.DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity( `
$context, `
[System.DirectoryServices.AccountManagement.IdentityType]::Sid, `
$sid.Value)
Write-Host ("Group: '{0}'; Sid: '{1}" -f $group,$sid.Value)
}
我在构建PrincipalContext
child.root.local:3268
child:3268
DCServer.child.root.local:3268
它们似乎都不允许我在根域中获取组的结果。
...
Group: ''; Sid: 'S-1-5-21-2643412326-2562497744-373403-4104
...
我已经确认使用DirectorySearcher
执行全局编录查询也成功找到了该组
$ds = "System.DirectoryServices"
$rtn = [reflection.assembly]::LoadWithPartialName($ds)
$entry = New-Object System.DirectoryServices.DirectoryEntry("GC://$forest")
$searcher = New-Object System.DirectoryServices.DirectorySearcher($entry)
for ($i=0; $i -lt $groups.Count; $i++)
{
$sid = New-Object System.Security.Principal.SecurityIdentifier($groups[$i],0)
$searcher.Filter = "(&(ObjectSid=$($sid.Value)))"
$res = $searcher.FindOne()
$res.Properties.samaccountname
}