J
Jeff Williams
How can I get a list of the Groups both Local and Domain groups a User
belongs to.
belongs to.
You'll have to use P/Invoke for this, of course![]()
Mark Rae said:You'll have to use P/Invoke for this, of course![]()
System.DirectoryServices will do all of this, and much more, for you without recourse to
p/invoke...
using System;
using System.Collections.Generic;
using System.DirectoryServices;
public static List<string> GetGroupsForUser(string pstrUser)
{
/// <summary>
/// Gets the groups a user is a member of
/// </summary>
/// <param name="pstrGroup">ActiveDirectory group to evaluate</param>
/// <returns>List<string> of groups for pstrUser</returns>
DirectorySearcher objDS = null;
SearchResult objSR = null;
DirectoryEntry objUser = null;
List<string> lstGroups = new List<string>();
try
{
objDS = new DirectorySearcher("objectCategory=User");
objDS.Filter = "(SAMAccountName=" + pstrUser + ")";
objSR = objDS.FindOne();
objUser = new DirectoryEntry(objSR.Path);
PropertyCollection colProperties = objUser.Properties;
PropertyValueCollection colPropertyValues = colProperties["memberOf"];
foreach (string strGroup in colPropertyValues)
{
lstGroups.Add(GetSAMAccountName(strGroup).ToLower());
}
return lstGroups;
}
catch (Exception)
{
throw;
}
finally
{
if (objUser != null)
{
objUser.Close();
objUser.Dispose();
objUser = null;
}
if (objSR != null)
{
objSR = null;
}
if (objDS != null)
{
objDS.Dispose();
objDS = null;
}
}
}
public static string GetSAMAccountName(string pstrPath)
{
/// <summary>
/// Gets a SAM Account Name from a given LDAP path
/// </summary>
/// <param name="pstrPath">LDAP path to bind to</param>
DirectoryEntry objADEntry = null;
try
{
objADEntry = new DirectoryEntry("LDAP://" + pstrPath);
return objADEntry.Properties["SAMAccountName"].Value.ToString();
}
catch (System.Runtime.InteropServices.COMException)
{
return String.Empty;
}
catch (System.NullReferenceException)
{
return String.Empty;
}
catch (Exception)
{
throw;
}
finally
{
if (objADEntry != null)
{
objADEntry.Close();
objADEntry.Dispose();
objADEntry = null;
}
}
}
You may simplify your code... <snip>
Mark Rae said:You'll have to use P/Invoke for this, of course![]()
System.DirectoryServices will do all of this, and much more, for you
without recourse to p/invoke...
using System;
using System.Collections.Generic;
using System.DirectoryServices;
public static List<string> GetGroupsForUser(string pstrUser)
{
/// <summary>
/// Gets the groups a user is a member of
/// </summary>
/// <param name="pstrGroup">ActiveDirectory group to evaluate</param>
/// <returns>List<string> of groups for pstrUser</returns>
DirectorySearcher objDS = null;
SearchResult objSR = null;
DirectoryEntry objUser = null;
List<string> lstGroups = new List<string>();
try
{
objDS = new DirectorySearcher("objectCategory=User");
objDS.Filter = "(SAMAccountName=" + pstrUser + ")";
objSR = objDS.FindOne();
objUser = new DirectoryEntry(objSR.Path);
PropertyCollection colProperties = objUser.Properties;
PropertyValueCollection colPropertyValues = colProperties["memberOf"];
foreach (string strGroup in colPropertyValues)
{
lstGroups.Add(GetSAMAccountName(strGroup).ToLower());
}
return lstGroups;
}
catch (Exception)
{
throw;
}
finally
{
if (objUser != null)
{
objUser.Close();
objUser.Dispose();
objUser = null;
}
if (objSR != null)
{
objSR = null;
}
if (objDS != null)
{
objDS.Dispose();
objDS = null;
}
}
}
public static string GetSAMAccountName(string pstrPath)
{
/// <summary>
/// Gets a SAM Account Name from a given LDAP path
/// </summary>
/// <param name="pstrPath">LDAP path to bind to</param>
DirectoryEntry objADEntry = null;
try
{
objADEntry = new DirectoryEntry("LDAP://" + pstrPath);
return objADEntry.Properties["SAMAccountName"].Value.ToString();
}
catch (System.Runtime.InteropServices.COMException)
{
return String.Empty;
}
catch (System.NullReferenceException)
{
return String.Empty;
}
catch (Exception)
{
throw;
}
finally
{
if (objADEntry != null)
{
objADEntry.Close();
objADEntry.Dispose();
objADEntry = null;
}
}
}
Good stuff, but correct me if I'm wrong here. That won't get the local
groups so the user will still have to use my method anyway.
Mark Rae said:No it won't, but it can with a fairly trivial modification:
http://www.experts-exchange.com/Programming/Programming_Languages/Dot_Net/Q_20658471.html
That's great![]()
Dave Sexton said:Hi Mark,
Good stuff, but correct me if I'm wrong here. That won't get the local groups so the user
will still have to use my method anyway.
--
Willy Denoyette said:Dave Sexton said:Hi Mark,
Good stuff, but correct me if I'm wrong here. That won't get the local
groups so the user will still have to use my method anyway.
--
No, you can use the WinNT provider to connect to the local SAM, like this:
private static List<string> AccountGroups(string userAccount)
{
List<string> lstGroups = new List<string>(10);
string adsPath = "WinNT://<domain>/<machine>"; // or
WinNT://<machine > if not a domain member.
using (DirectoryEntry groupEntry = new DirectoryEntry(adsPath
+",computer"))
{
IADsContainer cont = groupEntry.NativeObject as IADsContainer;
object[] filter = {"Group"};
cont.Filter = filter;
foreach (IADsGroup group in cont) {
if(group.IsMember(adsPath + "/" + userAccount))
lstGroups.Add(group.Name);
}
}
return lstGroups;
}
the problem here is that you need to set a reference to activeds.tlb. Also
note that the above sample does not account for nested groups!!
Note that you can also use WindowsIdentity.Groups, the problem here is
that you also get the pseudo accounts returned.
A better solution is to use System.Management (and WMI classes
"Win32_UserAccount" and "Win32_Group") to check local account and group
membership.
Willy.
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.