C# Console Application - Get Current User AD Groups - c#

I'm writing a script to get a list of the current user's AD Groups and creates a .txt file to a Path.
I've had a look around and it seems like I should be using these references:
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;
I'm also using this:
UserPrincipal user = UserPrincipal.FindByIdentity(new PrincipalContext(ContextType.Domain, "<Domain>"), IdentityType.SamAccountName, "<UserName>");
foreach (GroupPrincipal group in user.GetGroups())
{
Console.Out.WriteLine(group);
}
But this doesn't quite list all the groups that the user should be in.
Is there something I'm missing?

I use this block of code to get the user groups:
String domainName = #"<your domain>";
String username = domainName + #"\<your username>";
PrincipalContext thisDomain = new PrincipalContext(ContextType.Domain);
UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(thisDomain, username);
PrincipalSearchResult<Principal> userGroups = userPrincipal.GetAuthorizationGroups();
foreach (Principal principal in userGroups.OfType<GroupPrincipal>())
{
Debug.WriteLine(principal.Name);
}
As far as I can tell, it lists all the groups the user is a member of by comparison to what is held in Active Directory and looking at the user object in the MMC snap in

Related

How to add a user from another domain to a local domain group?

Using C# I would like to add a user from one domain to a local domain. The domains have a two way trust. Currently I get the error
'No principal matching the specified parameters was found.' on the .Save() line.
I have the DN of the user (e.g 'CN=Adams, Sam,OU=Beer, DC=Drinkers,DC=local').
The groups is something like CN=Drunks, OU=Groups,DC=Bars,DC=local.
This works when it is the same domain, but when it is cross domains is when I get the error. The user account that I am using has admin rights locally and read rights in the other domain.
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, m_AD_connection.Domain, m_AD_connection.Path, ContextOptions.Negotiate, m_AD_connection.UserName, m_AD_connection.Password))
{
GroupPrincipal group = GroupPrincipal.FindByIdentity(pc, GroupName);
if (group != null)
{
group.Members.Add(pc, IdentityType.DistinguishedName, DN);
group.Save();
return true;
}
else
return false;
}
Any suggestions on what I need to do?
Your issue is in this line:
group.Members.Add(pc, IdentityType.DistinguishedName, DN);
The context parameter should be the context required to look up the user, not the group. So you need to create a new PrincipalContext for the second domain and pass that to Add(). For example:
var drinkersPc = new PrincipalContext(ContextType.Domain, "drinkers.local");
group.Members.Add(drinkersPc, IdentityType.DistinguishedName, DN);

Active Directory - Get Manager account (from Distinguished Name)

I am trying to get the manager's account for a user account in active directory.
Here's the code I have..
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
DirectoryContext directoryContext = new DirectoryContext(DirectoryContextType.Domain, "MyDomain");
Domain domain = Domain.GetDomain(directoryContext);
// Find MY directory Entry
DirectorySearcher search = new DirectorySearcher(domain.GetDirectoryEntry())
{
Filter = String.Format("(SAMAccountName={0})", "<my user id>")
};
search.PropertiesToLoad.Add("displayName");
search.PropertiesToLoad.Add("mail");
search.PropertiesToLoad.Add("manager");
DirectoryEntry userAccount = search.FindOne()?.GetDirectoryEntry();
As you can see, there's a property called manager that is requested and comes back as
CN=Manager Name,OU=Employee,OU=United Kingdom, OU=CompantUsers, DC=MyDomain, DC=xxx,DC=zzzzz
The CN=Manager Name is the full name, not the LoginID/SAMAccountName (as used when I searched for MY AD entry ... so how can I now find the AD entry for my manager
Ahhh ... When you know the right question to ask then Google knows the answer ... I did not know that the CN..... string was known as a distinguishedName
if (userAccount.Properties["manager"].Value != null)
{
DirectorySearcher search2 = new DirectorySearcher(domain.GetDirectoryEntry())
{
Filter = string.Format("(distinguishedName={0})", userAccount.Properties["manager"].Value)
};
search2.PropertiesToLoad.Add("displayName");
search2.PropertiesToLoad.Add("mail");
search2.PropertiesToLoad.Add("manager");
DirectoryEntry mgrAcc = search2.FindOne()?.GetDirectoryEntry();
}

Get Name of User from Active Directory

I need to show only the name of a user from Active Directory, I am using
lbl_Login.Text = User.Identity.Name; //the result is domain\username
This shows the users name but not the real name of the user, I've checked other questions and answers related here but I've not gotten the solution.
Is there any property just as "User.Identity.Name" to get only the name of the user?
You want name of a user from active directory. Try code like this:
string name ="";
using (var context = new PrincipalContext(ContextType.Domain))
{
var usr = UserPrincipal.FindByIdentity(context, User.Identity.Name);
if (usr != null)
name = usr.DisplayName;
}
or this from social.msdn.microsoft.com:
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
UserPrincipal user = UserPrincipal.Current;
string displayName = user.DisplayName;
or may be it:
System.DirectoryServices.AccountManagement.UserPrincipal.Current.DisplayName;
The System.DirectoryServices.AccountManagement namespace provides uniform access and manipulation of user, computer, and group security principals across the multiple principal stores: Active Directory Domain Services (AD DS), Active Directory Lightweight Directory Services (AD LDS), and Machine SAM (MSAM).
using System.DirectoryServices.AccountManagement;
string fullName = null;
using (PrincipalContext context = new PrincipalContext(ContextType.Domain))
{
using (UserPrincipal user = UserPrincipal.FindByIdentity(context, User.Identity.Name))
{
if (user != null)
{
fullName = user.DisplayName;
lbl_Login.Text = fullName;
}
}
}

Find local groups that a domain user belongs to?

I'm using the System.DirectoryServices.AccountManagement namespace to find domain users and their corresponding AD security groups. This works well.
I'm also using that namespace to query the local security groups on a remote server. I am able to find a security group and then list the users of that group no problem.
What I'm having issues with is displaying which LOCAL groups a DOMAIN user belongs to:
PrincipalContext localmachine = new PrincipalContext(ContextType.Machine, "ServerName");
PrincipalContext domain = new PrincipalContext(ContextType.Domain);
// find the user using the domain context (Works fine)
UserPrincipal user = UserPrincipal.FindByIdentity(domain, userName);
// if found - grab its groups
if (user != null)
{
// The get groups method is the only method that would accept a new context
PrincipalSearchResult<Principal> groups = user.GetGroups(localMachine);
// no groups are returned .... removed rest of code
}
I'm attempting to use the GetGroups method passing in the localMachine PrincipalContext but no groups are returned.
The users exists only in the Domain AD. There is not an entry for this user in the local users on the localMachine. The domain users are added to local security groups.
Any ideas? I'd like to be able to pull a list of all local groups this domain user belongs to and then see if a certain groups exists in that list. The only option that is working now is for me to search certain groups on the system and see if the domain user belongs to that group.
The following code will return the local groups that a domain user is member of:
PrincipalContext domain = new PrincipalContext(ContextType.Domain);
UserPrincipal user = UserPrincipal.FindByIdentity(domain, userName);
foreach (GroupPrincipal group in user.GetAuthorizationGroups())
{
if (group.Context.ConnectedServer == serverName)
Console.Out.WriteLine("{0}\\{1}", group.Context.Name, group.SamAccountName);
}
I know my answer is late, but this worked for me (after I tried all sorts of permutations):
private static IList<string> GetUserLocalGroups(string userAccountName, string computerName, string domainName)
{
List<string> groups = new List<string>();
// We have to deal with a local computer
DirectoryEntry root = new DirectoryEntry(String.Format("WinNT://{0},Computer", computerName), null, null, AuthenticationTypes.Secure);
foreach (DirectoryEntry groupDirectoryEntry in root.Children)
{
if (groupDirectoryEntry.SchemaClassName != "Group")
continue;
string groupName = groupDirectoryEntry.Name;
Console.WriteLine("Checking: {0}", groupName);
if (IsUserMemberOfGroup(groupDirectoryEntry, String.Format("WinNT://{0}/{1}", domainName, userAccountName)))
{
groups.Add(groupName);
}
}
return groups;
}
private static bool IsUserMemberOfGroup(DirectoryEntry group, string userPath)
{
return (bool)group.Invoke(
"IsMember",
new object[] { userPath }
);
}
The call is something like this:
GetUserLocalGroups("samaccountname", "computerName.yourdomain", "yourdomain");

Can not retrieve Active Directory user in C#

I built a test Active Directory server in Window 2008 and I also run the DNS server on it. On my client machine which runs the C# application, I can authenticate the user against the Active directory server using the function below:
public static UserPrincipal GetUserPrincipal(string usrName,string pswd,string domainName)
{
UserPrincipal usr;
PrincipalContext ad;
// Enter Active Directory settings
ad = new PrincipalContext(ContextType.Domain, domainName,usrName,pswd);
//search user
usr = new UserPrincipal(ad);
usr.SamAccountName = usrName;
PrincipalSearcher search = new PrincipalSearcher(usr);
usr = (UserPrincipal)search.FindOne();
search.Dispose();
return usr;
}
In a separate logic I tried to retrieve a user back from the server using a user name. I used the functions below:
public static DirectoryEntry CreateDirectoryEntry()
{
// create AD connection
DirectoryEntry de = new DirectoryEntry("LDAP://CN=Users,DC=rootforest,DC=com","LDAP","password");
de.AuthenticationType = AuthenticationTypes.Secure;
return de;
}
public static ResultPropertyCollection GetUserProperty(string domainName, string usrName)
{
DirectoryEntry de = CreateDirectoryEntry();
DirectorySearcher deSearch = new DirectorySearcher();
deSearch.SearchRoot = de;
deSearch.Filter = "(SamAccountName=" + usrName + ")";
SearchResult results = deSearch.FindOne();
return null;
}
However, I got no response back from the LDAP server at all, not even an exception. Am I missing certain settings on LDAP server, any of you able to see a flaw in my code (pls don't mind the hard code values, I was testing with this code).
As part of my troubleshooting, I confirmed that I can ping to the rootforest.com from the client machine. I confirmed the user with property samaccountname "LDAP" exists. My path seems to be right because when I go onto the LDAP server and type :
dsquery user -name LDAP*
I got the following:
CN=LDAP L. LDAP,CN=Users,DC=rootforest,DC=com
Any help would be greatly appreciated, I've spent most of my day troubleshooting and researching this little bugger and I think it could be something small which I overlooked.
I don't understand why you're using the new PrincipalContext / UserPrincipal stuff in your first example, but fall back to the hard to use DirectoryEntry stuff in your second example.... doesn't really make sense... also: your second function GetUserProperty seems to return null always - typo or not??
Since you're on already using the System.DirectoryServices.AccountManagement (S.DS.AM) namespace - use it for your second task, too! Read all about it here:
Managing Directory Security Principals in the .NET Framework 3.5
MSDN docs on System.DirectoryServices.AccountManagement
Basically, you can define a domain context and easily find users and/or groups in AD:
public static ????? GetUserProperty(string domainName, string usrName)
{
// set up domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, usrName);
if(user != null)
{
// return what you need to return from your user principal here
}
else
{
return null;
}
}
The new S.DS.AM makes it really easy to play around with users and groups in AD:
I think your code have a few problems:
Why do you return null in your GetUserProperty() function? You should return results instead.
The attribute you are using in your search filter is misspelled. Use sSAMAccountName instead. Furthermore extend your query to search only for user accounts. Here is an example: (&(objectCategory=person)(objectClass=user)(sAMAccountName=usrName))
You could also use the UserPrincipal class to search for an identity in Active Directory. The UserPrincipal class provides a static method called FindByIdentity() to search for a user identity.
Hope, this helps.

Categories