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();
}
Related
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
}
}
}
}
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 am trying to grab the current windows user and see if that user is part of a certain group in Active Directory. The username information finds "Harper\TSmith" which seems fine but when I get to the
UserPrincipal uPrincipal = Psearch.FindOne() as UserPrincipal
Line UPrincipal is null. Can not figure out why. I also have at the bottom a validator class that as a bool method to see if they are part of that particular group.
PrincipalContext principalCtx = new PrincipalContext(ContextType.Domain);
UserPrincipal findUser = new UserPrincipal(principalCtx);
//findUser.Name = Environment.UserName;
findUser.Name = WindowsIdentity.GetCurrent().Name;
PrincipalSearcher pSearch = new PrincipalSearcher();
pSearch.QueryFilter = findUser;
UserPrincipal uPrincipal = pSearch.FindOne() as UserPrincipal;
Validator validate = new Validator();
//validate.IsUserInGroup("VisualOne", uPrincipal);
if (validate.IsUserInGroup("MyGroup", uPrincipal))
{
var MemberShipForm = new Membership();
MemberShipForm.Show();
}
public bool IsUserInGroup(string groupName, UserPrincipal user)
{
PrincipalContext context = new PrincipalContext(ContextType.Domain, "Harper");
GroupPrincipal group = GroupPrincipal.FindByIdentity(context, "MyGroup");
if (user.IsMemberOf(group))
{
return true;
}
return false;
}
PrincipalContext principalCtx = new PrincipalContext(ContextType.Domain);
UserPrincipal uPrincipal = UserPrincipal.Current;
if (validate.IsUserInGroup("MyGroup", uPrincipal))
{
var MemberShipForm = new Membership();
MemberShipForm.Show();
}
I want to check, if a a user is in a specific parent OU.
How can I do that?
Check below code for a clear desciption of what I am looking for.
using System.DirectoryServices.AccountManagement;
public bool IsUserInOU(string samAccountName, string OUName){
using (var context = new PrincipalContext(ContextType.Domain))
{
using (var user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, samAccountName))
{
//Check if the user is in the OU specified in OUName
//Something like:
//return user.IsInOU(OUName);
}
}
}
public void TestIt_1(){
//The parent OU of this user is "AwesomeOU"
string samAccountName = "Joe";
string OUName = "AwesomeOU";
bool expected = true;
bool actual = IsUserInOU(samAccountName, OUName);
Assert.AreEqual(expected, actual);
}
public void TestIt_2(){
//The parent OU of this user is "WhateverOU"
string samAccountName = "Mike";
string OUName = "AwesomeOU";
bool expected = false;
bool actual = IsUserInOU(samAccountName, OUName);
Assert.AreEqual(expected, actual);
}
The Domain:
National OU
Awesome OU
Joe
Whatever OU
Mike
Solution 1 after empi's answer
With the information given by empi, I wrote the below method to extract the first OU in the DistinguishedName. Having done that, the rest is a breeze.
public static string GetOUForUser(string samAccountName)
{
using (var context = new PrincipalContext(ContextType.Domain))
{
using (var user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, samAccountName))
{
//System.Console.WriteLine(user.DistinguishedName);
int startIndex = user.DistinguishedName.IndexOf("OU=", 1) + 3; //+3 for length of "OU="
int endIndex = user.DistinguishedName.IndexOf(",", startIndex);
var group = user.DistinguishedName.Substring((startIndex), (endIndex - startIndex));
return group;
}
}
}
Solution 2 after JPBlanc's answer
public static string GetOUForUser(string samAccountName)
{
using (var context = new PrincipalContext(ContextType.Domain))
{
using (var user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, samAccountName))
{
using (DirectoryEntry deUser = user.GetUnderlyingObject() as DirectoryEntry)
{
using (DirectoryEntry deUserContainer = deUser.Parent)
{
return deUserContainer.Properties["Name"].Value.ToString();
}
}
}
}
}
Ok #Empi solution is working, but UserPrincipal is built on DirectoryEntry objects that provides a parent or container properties that just give you the object you are looking for, without using string way.
/* Retreiving a principal context
*/
PrincipalContext domainContext = new PrincipalContext(ContextType.Domain, "WM2008R2ENT:389", "dc=dom,dc=fr", "dom\\jpb", "MyPwd");
/* Retreive a user
*/
UserPrincipal user = UserPrincipal.FindByIdentity(domainContext, "user1");
/* Retreive the container
*/
DirectoryEntry deUser = user.GetUnderlyingObject() as DirectoryEntry;
DirectoryEntry deUserContainer = deUser.Parent;
Console.WriteLine (deUserContainer.Properties["distinguishedName"].Value);
This information is in UserPrincipal.DistinguishedName. You should check if DistinguishedName ends with "," + ou distinguished name (case insensitive). However, you must know the distingushed name of ou you're checking.
For example, if dn is: CN=Jeff Smith,OU=Sales,DC=Fabrikam,DC=COM, then it says that user is in OU=Sales,DC=Fabrikam,DC=COM ou.
This is how I would get the Distinguished Name for a specific AD user, hope it helps :-)
private static string GetDNOfUser(string user)
{
var ctx = new PrincipalContext(ContextType.Domain, Environmentals.Domain, Environmentals.OUPath);
//Creating object for search filter
UserPrincipal userPrin = new UserPrincipal(ctx)
{
//Only getting users with the same name as the input
Name = user
};
var searcher = new PrincipalSearcher
{
//Applying filter to query
QueryFilter = userPrin
};
//Finding the user
var results = searcher.FindOne();
searcher.Dispose();
//Return the distinguishedname
return results.DistinguishedName;
}