Is it possible to read deleted users from Active directory?
Simple and short question.
I want read this info with C# UserPrincipal, but I am not sure if this is possible.
Here's how you can search for deleted users using DirectoryEntry and DirectorySearcher. If it's really trivial for you to get the underlying object as UserPrincipal you can cast user object as UserPrincipal.
public static void searchDeletedUsers()
{
using (DirectoryEntry entry = new DirectoryEntry("LDAP://yourldappath.com"))
{
using (DirectorySearcher searcher = new DirectorySearcher(entry))
{
searcher.Filter = "(&(isDeleted=TRUE)(objectclass=user))";
searcher.Tombstone = true;
var users = searcher.FindAll();
foreach(var user in users)
{
//user will contain the deleted user object
}
}
}
}
Related
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();
}
I'm using DirectoryEntry class
Trying to read all users from specific OU and sub OU's.
Following code is part of task
using(DirectoryEntry dEntry = new DirectoryEntry(dn))
using(DirectorySearcher dSearcher = new DirectorySearcher(dEntry))
{
dSearcher.SearchScope = SearchScope.Subtree;
dSearcher.Filter = "(&(objectClass=user) (objectCategory=person))";
foreach(SearchResult in dSearcher.FindAll())
{
//Do something...
}
}
some of sub OU's are protected from reading for current user.
And i got task exception "one or more error accured"
I'm looking for way to check if OU is not accessible and skip it. And to write that OU to log.
I tried following :
public void GetOu(List<MyUser> list, string path)
{
using (DirectoryEntry dEntry = new DirectoryEntry(path))
using(DirectorySearcher dSearcher = new DirectorySearcher(dEntry))
{
dSearcher.SearcherScope = SearchScope.Subtree;
dSearcher.Filter = "(objectClass=organizationalUnit)";
foreach(SearchResult result in dSearcher.FindAll())
{
GetUsersFromOU(list,result.GetDirectoryEntry());
}
}
}
public void GetUsersFromOU(List<MyUser> list,DirectoryEntry ou)
{
using (DirectorySearcher dSearcher = new DirectorySearcher(ou);
dSearcher.SearchScope = SearchScope.OneLevel;
dSearcher.Filter = "(&(objectClass=user)(objectCategory=person))";
foreach (Search result in dSearcher.FindAll())
{
//Do something.... update list...
}
}
Now get no exceptions and skips not accessible OUs.
1.But still can't find what are the "bad ou"s
2.run time is catastrophic...
You will have to make sure that the user running the process has the appropriate permissions to perform the lookup. This will be your Windows account in a desktop application and the account running the application pool in an ASP.NET application.
I have a ASP.NET Website project and I need to list all the users and their groups on my Windows system. I have set the identity impersonation to true and provided the username and password of the admin in the web.config. Where do I start?
Thanks in advance.
Update:
I have the following code at the moment -
var machine = new DirectoryEntry("WinNT://<IP ADDRESS>");
foreach (DirectoryEntry child in machine.Children)
{
// get the child's group(s).
}
When I debug, I can see the list of users in machine.Children. How do I find the group(s) that this user belongs to?
This article covers how to talk to Active Directory and should get you where you want to go:
http://www.codeproject.com/KB/system/everythingInAD.aspx
To get users, you would do something like this:
public List<string> GetUserList()
{
string DomainName="";
string ADUsername="";
string ADPassword="";
List<string> list=new List<string>();
DirectoryEntry entry=new DirectoryEntry(LDAPConnectionString, ADUsername, ADPassword);
DirectorySearcher dSearch=new DirectorySearcher(entry);
dSearch.Filter="(&(objectClass=user))";
foreach(SearchResult sResultSet in dSearch.FindAll())
{
string str=GetProperty(sResultSet, "userPrincipalName");
if(str!="")
list.Add(str);
}
return list;
}
You probably want to start with the DirectoryEntry and Active Directory support in .net.
Here's a good resource: http://www.codeproject.com/KB/system/everythingInAD.aspx
Local access is similar, even if you're not in a domain:
DirectoryEntry localMachine = new DirectoryEntry("WinNT://" +
Environment.MachineName);
DirectoryEntry admGroup = localMachine.Children.Find("administrators",
"group");
object members = admGroup.Invoke("members", null);
foreach (object groupMember in (IEnumerable)members) {
DirectoryEntry member = new DirectoryEntry(groupMember);
//...
}
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");
I am trying to get the list of local users of a computer using the following code.
internal void GetUsers()
{
try
{
List<string> adUsers = new List<string>();
DirectoryEntry directoryEntry = new DirectoryEntry("WinNT://" + Environment.MachineName);
foreach (DirectoryEntry child in directoryEntry.Children)
{
if (child.SchemaClassName.Equals("User", StringComparison.OrdinalIgnoreCase))
{
adUsers.Add(child.Name);
}
}
}
catch (Exception ex)
{
//Exception
}
}
This code works fine in my computer. However, when I tested it on a few other computers, the following system users were included in the list:
ASPNET,
HelpAssistant
Could some one throw some light on how I can get rid of these system users and get only users who actually log in, ie, normal users.
Thanks,
Ram
Not an answer as such, but some suggestions that might help.
I think the problem is that those accounts aren't real system accounts, so might not be so easy to distinguish.
You could look at the WMI classes Win32_UserAccount and Win32_UserProfile and see if there are any properties in there that might indicate which user accounts are normal ones and which ones are the ones you mention. Specifically, maybe the 'SIDType' or 'AccountType' properties of Win32_UserAccount or maybe the Special property of the Win32_UserProfile class.
Might be other WMI classes that might be worth looking at as well.
Or there might be some way that you can query if a user account has the interactive logon right (which I assume those two accounts might not have normally).
Have you tried enumerating the Properties collection on DirectoryEntry?
using (DirectoryEntry dirEntry = new DirectoryEntry(strchild))
{
foreach (string strPropertyName in dirEntry.Properties.PropertyNames)
{
Console.WriteLine(strPropertyName + " " + dirEntry.Properties[strPropertyName].Value.ToString());
}
}
Other than that, you may have to do an LDAP search on Active Directory to match the UserName you have found to an ActiveDirectory user.
Have a look at this article.
http://www.codeproject.com/KB/system/everythingInAD.aspx
Have fun.
The following code will get you the local users that actually have local accessible folders.
var localDrives = Environment.GetLogicalDrives();
var localUsers = new List<string>();
var query = new SelectQuery("Win32_UserAccount") { Condition = "SIDType = 1 AND AccountType = 512" };
var searcher = new ManagementObjectSearcher(query);
foreach (ManagementObject envVar in searcher.Get())
{
foreach (string drive in localDrives)
{
var dir = Path.Combine(String.Format("{0}Users", drive), envVar["name"].ToString());
if (Directory.Exists(dir))
{
localUsers.Add(envVar["name"].ToString());
}
}
}