I have a code to check if the user is a member of a group. I am using this at my login.
Please note I have a domain user and local user eg. testdomain\administrator
and administrator
.
This is the code I use:
using (DirectoryEntry groupEntry = new DirectoryEntry("WinNT://./" + userGroupName + ",group"))
{
foreach (object member in (IEnumerable)groupEntry.Invoke("Members"))
{
using (DirectoryEntry memberEntry = new DirectoryEntry(member))
{
string completeName = memberEntry.Name;
DirectoryEntry domainValue = GUIUtility.FindDomain(memberEntry);
if (domainValue != null)
{
completeName = domainValue.Name + "\\" + memberEntry.Name;
}
Global.logger.Info("completeName from " + userGroupName + " = " + completeName);
if (userName.Equals(completeName, StringComparison.InvariantCultureIgnoreCase))
{
Global.logger.Debug("IsUserPartOfWindowsGroup returned True with username =" + userName + " , UserGroupName = " + userGroupName);
return true;
}
}
}
Global.logger.Debug("IsUserPartOfWindowsGroup returned false for username =" + userName + " , UserGroupName = " + userGroupName);
return false;
}
This code works, but
DirectoryEntry domainValue = GUIUtility.FindDomain(memberEntry);
is taking a lot of time in the profiler as I see it. Is there a better/ faster way to handle this?
public static DirectoryEntry FindDomain(DirectoryEntry memberEntry)
{
if (memberEntry.Parent != null)
{
if (memberEntry.Parent.SchemaClassName.Equals("domain", StringComparison.InvariantCultureIgnoreCase))
{
return memberEntry.Parent;
}
}
return null;
}
another way:
DirectoryEntry entry = new DirectoryEntry("LDAP://" + domain, userName, Password);
DirectorySearcher mySearcher = new DirectorySearcher(entry);
mySearcher.Filter = "(&(objectClass=user)(|(cn=" + userName + ")(sAMAccountName=" + userName + ")))";
SearchResult result = mySearcher.FindOne();
Global.logger.Info("result == " + result.Path);
foreach (string GroupPath in result.Properties["memberOf"])
{
if (GroupPath.Contains(adminGroupName))
{
Global.logger.Info(compUsrNameForEncryption + "exists in " + adminGroupName);
}
}
This is pretty close to what I use:
public bool IsUserInGroup(string userName, string groupName)
{
using (var context = new PrincipalContext(ContextType.Machine))
{
using (var searcher = new PrincipalSearcher(new UserPrincipal(context) { SamAccountName = userName }))
{
using (var user = searcher.FindOne() as UserPrincipal)
{
return user != null && user.IsMemberOf(context, IdentityType.SamAccountName, groupName);
}
}
}
}
I haven't tested it for local users though. The logic works in my domain, I just changed PrincipalContext(ContextType.Machine)
so it should look at local users now.
Don't forget to add a reference and using statement for System.DirectoryServices.AccountManagement