Im trying to get all users of a particular group in AD but i am getting Exception : "The specified directory service attribute or value does not exist."
//using (var principalContext = new PrincipalContext(ContextType.Domain))
using (var principalContext = new PrincipalContext(ContextType.Domain, "domainName"))
{
//using (var group = GroupPrincipal.FindByIdentity(context, windowsGroup.TrimEnd('*')))
using (var groupPrincipal = GroupPrincipal.FindByIdentity(principalContext, IdentityType.SamAccountName, "groupName"))
{
if (groupPrincipal != null)
{
var users = groupPrincipal.GetMembers();
foreach (UserPrincipal userPrincipal in users)
{
//user variable has the details about the user
}
}
}
}
use container to specify your root
using (var principalContext = new PrincipalContext(ContextType.Domain, "TEST.COM", "DC=TEST,DC=COM"))
{
//using (var group = GroupPrincipal.FindByIdentity(context, windowsGroup.TrimEnd('*')))
using (var groupPrincipal = GroupPrincipal.FindByIdentity(principalContext, IdentityType.SamAccountName, "groupName"))
{
if (groupPrincipal != null)
{
var users = groupPrincipal.GetMembers();
foreach (UserPrincipal userPrincipal in users)
{
//user variable has the details about the user
}
}
}
}
Related
I have some code to check if a domain user is a member of the machines administrators group:
public static bool ActiveDirectoryGroupMembershipOk(string userid, string groupName)
{
using (PrincipalContext ctx = new PrincipalContext(ContextType.Machine, "my_pc_name"))
{
using (GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, "administrators"))
{
if (grp != null)
{
foreach (Principal p in grp.GetMembers(false))
{
if (p is UserPrincipal && p.SamAccountName.Equals(userid, StringComparison.InvariantCultureIgnoreCase))
{
return true;
}
}
}
}
}
return false;
}
It works, but the below code line takes some seconds to complete:
using (GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, "administrators"))
Is there a faster way to lookup the membership?
I don't know if it is important or not, but the userid is a Domain User and the windows group is on the local PC.
I found that it seems to be faster not to look up the user in a group but instead to check the user's role membership.
Here is the code that performs faster than the code in my question:
public static bool ActiveDirectoryGroupMembershipOk(string userid, string groupName)
{
bool membershipOk = false;
using (var pc = new PrincipalContext(ContextType.Machine, "my_pc_name"))
{
using (var p = Principal.FindByIdentity(pc, IdentityType.SamAccountName, userid))
{
// if user account exists, check the group membership
if(p != null)
{
System.Security.Principal.WindowsIdentity wi = new System.Security.Principal.WindowsIdentity(userid);
System.Security.Principal.WindowsPrincipal wp = new System.Security.Principal.WindowsPrincipal(wi);
membershipOk = wp.IsInRole(groupName);
}
}
}
return membershipOk;
}
I found a better way to do this still (assuming an AD domain), using part of Mr. Blonde's answer:
public static bool ActiveDirectoryGroupMembershipOk(String userid, String groupname)
{
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, userid);
GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, groupname);
return user.IsMemberOf(group);
}
I'm trying to get all the user's groups in the active directory with c# code.
This is my code:
private List<GroupPrincipal> GetGroups()
{
string userName = User.Identity.Name;
string host = Request.Url.Host.ToLower();
List<GroupPrincipal> result = new List<GroupPrincipal>();
UserPrincipal user = UserPrincipal.FindByIdentity(new PrincipalContext(ContextType.Domain, host), IdentityType.SamAccountName, userName);
foreach (GroupPrincipal group in user.GetGroups())
{
result.Add(group);
}
return result;
}
I receive an error on the row that starts with UserPrincipal user that says that the server could not be connected. I'm running my code from the server itself so I can connect it.
What am i doing wrong?
Thank you in advance!
To connect with Active Directory, Create PrincipalContext object.
PrincipalContext insPrincipalContext = new PrincipalContext(ContextType.Domain, "MyDomain",
"DC=MyDomain,DC=com");
Code to get all Groups:
Create GroupPrincipal object and call SearchGroups() which returns list of all groups of given domain.
private void ListGroups(){
GroupPrincipal insGroupPrincipal = new GroupPrincipal(insPrincipalContext);
insGroupPrincipal.Name = "*";
SearchGroups(insGroupPrincipal);}
private void SearchGroups(GroupPrincipal parGroupPrincipal)
{
List<Principal> oList = new List<Principal>();
PrincipalSearcher insPrincipalSearcher = new PrincipalSearcher();
insPrincipalSearcher.QueryFilter = parGroupPrincipal;
PrincipalSearchResult<Principal> results = insPrincipalSearcher.FindAll();
foreach (Principal p in results)
{
oList.Add(p);
}
}
This link will also help you -
http://www.codeproject.com/Articles/38344/Using-System-DirectoryServices-AccountManagement
I'm trying to get informations (members of groups).
I get every time the message "Information about the domain could not be retrieved (1355)"
For getting the groups, it helped to try it just 2 times. The first time doesn't work, but the second time brings me the groups. But for getting the Members of a group, I have no work aroung.
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "192.168.178.105:3268", "DC=ibcdev,DC=local", ContextOptions.Negotiate, "Administrator", "123");
// define a "query-by-example" principal - here, we search for a GroupPrincipal
GroupPrincipal qbeGroup = new GroupPrincipal(ctx);
// create your principal searcher passing in the QBE principal
PrincipalSearcher srch = new PrincipalSearcher(qbeGroup);
// find all matches
try
{
var re2s = srch.FindAll().ToList();
}
catch (Exception)
{
}
var res = srch.FindAll();
foreach (Principal found in res)
{
Console.WriteLine(found.SamAccountName);
var group = GroupPrincipal.FindByIdentity(ctx, found.Name);
foreach (var user in group.Members)
{
Console.WriteLine(user.SamAccountName);
}
}
Does somebody know what I am doing wrong?
Regards
This is what I use for finding a groups members in a domain:
public List<String> GetIDs(string domainName, string groupName)
{
using(PrincipalContext ctx = new PrincipalContext(ContextType.Domain, domainName))
using(GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, groupName))
return (from x in grp.GetMembers(true).AsParallel() select x.SamAccountName).ToList();
}
How do I search all the user accounts in a domain in .NET?
Not the computer names in the domain, but the user accounts, that's what you are using to log on Windows.
You can try the following.
PrincipalContext ctx = new PrincipalContext(ContextType.Machine,Environment.MachineName);
UserPrincipal user = new UserPrincipal(ctx);
user.Name = "*";
PrincipalSearcher ps = new PrincipalSearcher();
ps.QueryFilter = user;
PrincipalSearchResult<Principal> result = ps.FindAll();
foreach (Principal p in result)
{
using (UserPrincipal up = (UserPrincipal)p)
{
MessageBox.Show(up.Name);
}
}
Or this:
using System.Management;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
SelectQuery query = new SelectQuery("Win32_UserAccount");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
foreach (ManagementObject envVar in searcher.Get())
{
Console.WriteLine("Username : {0}", envVar["Name"]);
}
Console.ReadLine();
}
See also How to list all Windows Users.
You can use something like the following:
List<string> LdapUsers = new List<string>();
if (String.IsNullOrWhiteSpace(domain))
{
string username = WindowsIdentity.GetCurrent().Name;
domain = username.Substring(0, username.IndexOf("\\"));
}
PrincipalContext context;
if (!String.IsNullOrWhiteSpace(user) && !String.IsNullOrWhiteSpace(password) && !String.IsNullOrWhiteSpace(domain))
context = new PrincipalContext(ContextType.Domain, domain, user, password);
if (!String.IsNullOrWhiteSpace(domain))
context = new PrincipalContext(ContextType.Domain, domain);
else
context = new PrincipalContext(ContextType.Domain);
UserPrincipal userP = new UserPrincipal(context);
userP.Enabled = true;
PrincipalSearcher pS = new PrincipalSearcher();
pS.QueryFilter = userP;
PrincipalSearchResult<Principal> result = pS.FindAll();
foreach (Principal p in result)
LdapUsers.Add(domain + "\\" + p.SamAccountName);
One more way to search for domain users:
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
using (var domain = Domain.GetCurrentDomain())
using (var directoryEntry = domain.GetDirectoryEntry())
using (var directorySearcher = new DirectorySearcher(directoryEntry, "(&(objectCategory=person)(objectClass=user))"))
{
directorySearcher.PageSize = 1000;
using (var searchResults = directorySearcher.FindAll())
{
foreach (SearchResult searchResult in searchResults)
{
using (var userEntry = searchResult.GetDirectoryEntry())
{
Console.WriteLine(userEntry.Properties["cn"][0]);
}
}
}
}
How to remove windows user account using C#?
Clause Thomsen was close, you need to pass the DirectoryEntry.Remove method a DirectoryEntry paramenter and not a string, like:
DirectoryEntry localDirectory = new DirectoryEntry("WinNT://" + Environment.MachineName.ToString());
DirectoryEntries users = localDirectory.Children;
DirectoryEntry user = users.Find("userName");
users.Remove(user);
Something like this should do the trick(not tested):
DirectoryEntry localMachine = new DirectoryEntry("WinNT://" + Environment.MachineName);
DirectoryEntries entries = localMachine.Children;
DirectoryEntry user = entries.Remove("User");
entries.CommitChanges();
Alternatively using System.DirectoryServices.AccountManagement in .NET 3.5:-
http://msdn.microsoft.com/en-us/library/bb924557.aspx
using System;
using System.DirectoryServices.AccountManagement;
namespace AdministratorsGroupSample
{
class Program
{
static void Main(string[] args)
{
PrincipalContext ctx = new PrincipalContext(ContextType.Machine);
GroupPrincipal grpp = new GroupPrincipal(ctx);
UserPrincipal usrp = new UserPrincipal(ctx);
PrincipalSearcher ps_usr = new PrincipalSearcher(usrp);
PrincipalSearchResult<Principal> fr_usr = ps_usr.FindAll();
PrincipalSearcher ps_grp = new PrincipalSearcher(grpp);
PrincipalSearchResult<Principal> fr_grp = ps_grp.FindAll();
foreach (var usr in fr_usr)
{
Console.WriteLine($"Name:{usr.Name} SID:{usr.Sid} Desc:{usr.Description}");
Console.WriteLine("\t Groups:");
foreach (var grp in usr.GetGroups())
{
Console.WriteLine("\t" + $"Name:{grp.Name} SID:{grp.Sid} Desc:{grp.Description}");
}
Console.WriteLine();
}
Console.WriteLine();
foreach (var grp in fr_grp)
{
Console.WriteLine($"{grp.Name} {grp.Description}");
}
Console.ReadLine();
}
private void Delete(string userName)
{
PrincipalContext ctx = new PrincipalContext(ContextType.Machine);
UserPrincipal usrp = new UserPrincipal(ctx);
usrp.Name = userName;
PrincipalSearcher ps_usr = new PrincipalSearcher(usrp);
var user = ps_usr.FindOne();
user.Delete();
}
}
}