我正在尝试构建所有本地组及其受尊敬成员的集合,但是我对列出的代码所带来的挑战是“管理员”组成员是空的,服务器上的所有其他组只返回其成员不是管理员。任何想法?
private void BuildGroupMembership(string remoteHost, string targetdomain, string userName, string password, bool domainOnly)
{
var groupsList = new List<string>();
PrincipalContext pContext = null;
PrincipalContext searchContext = null;
if (string.IsNullOrEmpty(remoteHost))
{
remoteHost = Environment.MachineName;
}
if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(password))
{
pContext = new PrincipalContext(ContextType.Machine, remoteHost, null, ContextOptions.Negotiate, userName, password);
searchContext = new PrincipalContext(ContextType.Domain, targetdomain, null, ContextOptions.Negotiate, userName, password);
}
else
{
pContext = new PrincipalContext(ContextType.Machine, remoteHost, null, ContextOptions.Negotiate);
searchContext = new PrincipalContext(ContextType.Domain, targetdomain, null, ContextOptions.Negotiate);
}
try
{
var pSearcher = new PrincipalSearcher(new GroupPrincipal(pContext));
foreach (var principal in pSearcher.FindAll().Where(principal => !groupsList.Contains(principal.Name))) groupsList.Add(principal.Name);
foreach (var group in groupsList)
try
{
var groupItem = new Group {GroupName = group};
Groups.Add(groupItem);
var grp = GroupPrincipal.FindByIdentity(pContext, group);
if (grp != null)
{
var allmembers = grp.GetMembers(false).ToList();
var members = domainOnly ? allmembers.Where(x => x.ContextType == ContextType.Domain).ToList() : allmembers.ToList();
foreach (var p in members)
try
{
var adGroup = GroupPrincipal.FindByIdentity(searchContext, IdentityType.Sid, p.Sid.Value);
if (adGroup != null)
{
groupItem.GroupMembers.Add(new GroupMember
{
MemberDomain = adGroup.DistinguishedName.Substring(adGroup.DistinguishedName.IndexOf("DC="), adGroup.DistinguishedName.Length - adGroup.DistinguishedName.IndexOf("DC=")).Replace("DC=", "").Replace(",", "."),
MemberName = p.SamAccountName,
MemberSID = p.Sid.ToString(),
IsGroup = true
});
continue;
}
var adUser = UserPrincipal.FindByIdentity(searchContext, IdentityType.Sid, p.Sid.ToString());
if (adUser != null)
{
groupItem.GroupMembers.Add(new GroupMember
{
MemberDomain = adUser.DistinguishedName.Substring(adUser.DistinguishedName.IndexOf("DC="), adUser.DistinguishedName.Length - adUser.DistinguishedName.IndexOf("DC=")).Replace("DC=", "").Replace(",", "."),
MemberName = p.SamAccountName,
MemberSID = p.Sid.ToString(),
IsGroup = false
});
}
}
catch
{
// ignored
}
grp.Dispose();
}
}
catch
{
}
pContext.Dispose();
searchContext.Dispose();
}
catch (COMException ex)
{
throw new AuthenticationException(ex.Message);
}
}
答案 0 :(得分:0)
这完全不能回答您的问题,但可能会对您有所帮助。使用WMI比使用PrincipalContext
快得多......(至少在我的情况下)。在我的应用中只需要管理员和用户。
static Regex partComponentRegex = new Regex("^[^:]+:Win32_UserAccount.Domain=\"(?<Domain>.+?)\",Name=\"(?<Name>.+?)\"$");
static IEnumerable<User> GetUsersFromSidType(WellKnownSidType wellKnownSidType)
{
string gName = GetGroupName(wellKnownSidType);
using (ManagementObjectSearcher groupSearcher = new ManagementObjectSearcher(
string.Format("SELECT * FROM Win32_GroupUser WHERE GroupComponent =\"Win32_Group.Domain='{0}',Name='{1}'\"",
Environment.MachineName,
gName)))
{
foreach (var group in groupSearcher.Get())
{
Match m = partComponentRegex.Match(group["PartComponent"].ToString());
if (m.Success)
{
using (ManagementObjectSearcher userSearcher = new ManagementObjectSearcher(
string.Format("SELECT * FROM Win32_UserAccount WHERE Name='{0}' AND Domain='{1}'",
m.Groups["Name"], m.Groups["Domain"])))
{
foreach (var user in userSearcher.Get())
{
yield return new User()
{
Disabled = (bool)user["Disabled"],
Domain = user["Domain"].ToString(),
FullName = user["FullName"].ToString(),
Name = user["Name"].ToString(),
SID = user["SID"].ToString()
};
}
}
}
}
}
}
static string GetGroupName(WellKnownSidType wellKnownSidType)
{
SecurityIdentifier sid = new SecurityIdentifier(wellKnownSidType, null);
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(
string.Format("SELECT * FROM Win32_Group WHERE SID='{0}'",
sid.Value)))
{
var e = searcher.Get().GetEnumerator();
if (e.MoveNext())
return e.Current["Name"].ToString();
return null;
}
}