SuperMario
asked on
Using System.DirectoryServices to enumerate users on the current system.
Hi everyone,
I am trying to use System.DirectoryServices to show a list of Active Directory users on the current machine.
I'm doing something like this:
string sDomain = Environment.UserDomain;
string sMachine = Environment.MachineName;
string sLocalPath = "winnt://" + sDomain + "/" + sMachine; // I think this path is wrong
// the path is something like winnt://domain/machinename
// then I try this:
DirectoryEntry root = new DirectoryEntry(sLocalPath) ;
root.Children.SchemaFilter .Add("User s");
foreach(DirectoryEntry de in root.Children)
{
// enumerate the users.
}
However, it keeps throwing a darned exception on this line:
root.Children.SchemaFilter .Add("User s");
Anybody have any idea, or maybe another way using DirectoryServices to get a list of users on the local box? I already have it getting a list from the highest level, which is not what I want.
Thank you,
-Dan Waters
I am trying to use System.DirectoryServices to show a list of Active Directory users on the current machine.
I'm doing something like this:
string sDomain = Environment.UserDomain;
string sMachine = Environment.MachineName;
string sLocalPath = "winnt://" + sDomain + "/" + sMachine; // I think this path is wrong
// the path is something like winnt://domain/machinename
// then I try this:
DirectoryEntry root = new DirectoryEntry(sLocalPath)
root.Children.SchemaFilter
foreach(DirectoryEntry de in root.Children)
{
// enumerate the users.
}
However, it keeps throwing a darned exception on this line:
root.Children.SchemaFilter
Anybody have any idea, or maybe another way using DirectoryServices to get a list of users on the local box? I already have it getting a list from the highest level, which is not what I want.
Thank you,
-Dan Waters
ASKER
I hate to tell you this, but I've seen that link before and I really need some personal assistance... Thank you though.
For example, I want to find a list of local groups on the machine... Why won't my code I posted work? besides the fact that I put users as the filter.
I keep getting exceptions.
Any ideas?
Thanks,
Dan
For example, I want to find a list of local groups on the machine... Why won't my code I posted work? besides the fact that I put users as the filter.
I keep getting exceptions.
Any ideas?
Thanks,
Dan
Fair enough...
One problem.. Since you are trying to get local groups, then there is no point of specifying domain in the query path.
string sLocalPath = "winnt://" + sMachine
Try this.. and let mw know.
One problem.. Since you are trying to get local groups, then there is no point of specifying domain in the query path.
string sLocalPath = "winnt://" + sMachine
Try this.. and let mw know.
The other issue which is big trouble... WinNT provider does not have a concept of schema filters. It is used by LDAP/AD. So you will have to enumerate through the children list and filter out the objects of type "User"
See if the following code does the job for you..
using System;
using System.DirectoryServices;
namespace ADSISample
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
string sMachine = Environment.MachineName;
string sLocalPath = "WinNT://" + sMachine;
DirectoryEntry root = new DirectoryEntry(sLocalPath) ;
int idx = 0;
foreach(DirectoryEntry de in root.Children)
{
if (de.SchemaClassName.Compar eTo("User" ) == 0)
{
Console.WriteLine("This is my user {0}", idx);
Console.WriteLine("******* ********** ********") ;
foreach (string propName in de.Properties.PropertyName s)
{
foreach (object value in de.Properties[propName] )
{
Console.WriteLine("Prop Name=" + propName + " Value=" + value);
}
}
}
else
{
Console.WriteLine(de.Schem aClassName );
}
}
}
}
}
using System;
using System.DirectoryServices;
namespace ADSISample
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
string sMachine = Environment.MachineName;
string sLocalPath = "WinNT://" + sMachine;
DirectoryEntry root = new DirectoryEntry(sLocalPath)
int idx = 0;
foreach(DirectoryEntry de in root.Children)
{
if (de.SchemaClassName.Compar
{
Console.WriteLine("This is my user {0}", idx);
Console.WriteLine("*******
foreach (string propName in de.Properties.PropertyName
{
foreach (object value in de.Properties[propName] )
{
Console.WriteLine("Prop Name=" + propName + " Value=" + value);
}
}
}
else
{
Console.WriteLine(de.Schem
}
}
}
}
}
ASKER
I ended up solving it with DirectorySearcher. It turns out winnt is case sensitive and actually has to be WinNT...
But, for the points, here's another one:
Do you happen to know how I can add a user to a group? I know basically how to do it, setting the "Members" property of a group, but I am having a problem with the security. I think this has to do with Impersonation.
Mind you, I am not doing this with ASP.NET (where it's very easy to impersonate), but rather on a regular C# application.
If you could give me some guidance I'd be VERY thankful!
Thanks, and sorry I keep jumping around...
-Dan W.
But, for the points, here's another one:
Do you happen to know how I can add a user to a group? I know basically how to do it, setting the "Members" property of a group, but I am having a problem with the security. I think this has to do with Impersonation.
Mind you, I am not doing this with ASP.NET (where it's very easy to impersonate), but rather on a regular C# application.
If you could give me some guidance I'd be VERY thankful!
Thanks, and sorry I keep jumping around...
-Dan W.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Okay, I have one more question, and after that I'll reward the points (I've raised them to 120).
I am trying to add a DOMAIN user to a LOCAL group.
My group path is something like:
WinNT://MACHINENAME/GROUPN AME
The user path is like this:
WinNT://DOMAIN/USERNAME
Both the user and group DirectoryEntry objects exist... But when I try to invoke an Add method on the Group object, it throws a COMException saying the username is invalid.
This code was working fine before, I have just changed some paths.
Any suggestions?
thanks again for your help!
-Dan
I am trying to add a DOMAIN user to a LOCAL group.
My group path is something like:
WinNT://MACHINENAME/GROUPN
The user path is like this:
WinNT://DOMAIN/USERNAME
Both the user and group DirectoryEntry objects exist... But when I try to invoke an Add method on the Group object, it throws a COMException saying the username is invalid.
This code was working fine before, I have just changed some paths.
Any suggestions?
thanks again for your help!
-Dan
Post the code..
ASKER
/// <summary>
/// Adds a domain user to a local group.
/// </summary>
/// <param name="sDomain">The domain in which the user is found.</param>
/// <param name="sUser">The username.</param>
/// <param name="sGroup">Group name.</param>
/// <returns></returns>
public bool addDomainUserToLocalGroup( string sDomain, string sUser, string sGroup)
{
// Perform some basic error handling on parameters.
if(sGroup == "" || sGroup == null)
return error("Invalid group name.", true);
if(sUser == "" || sUser == null)
return error("Invalid user name.", true);
if(sMachine == "" || sMachine == null)
return error("Invalid machine name.", true);
string userPath, groupPath;
if(sDomain != "" && sDomain != null)
{
userPath = "WinNT://" + sDomain + "/" + sUser;
groupPath = "WinNT://" + this.sMachine + "/" + sGroup;
}
else
return error("The domain was not specified.", true);
try
{
DirectoryEntry group = new DirectoryEntry(groupPath, this.AuthUser, this.AuthPassword);
DirectoryEntry user = new DirectoryEntry(userPath, this.AuthUser, this.AuthPassword);
if(!dirExists(group.Path))
return error("Group " + sGroup + " does not exist. Path: " + group.Path, true);
if(!dirExists(user.Path))
return error("User " + sUser + " does not exist. Path: " + user.Path, true);
bool isMember = (bool)group.Invoke("isMemb er", new object[] { userPath });
//bool isMember = false;
// If the user is not a member of the specified group already...
if(!isMember)
{
// Go ahead and invoke the Add method and commit changes.
group.Invoke("add", new object[] { userPath } );
group.CommitChanges();
}
else
// Otherwise, flag an error (the user already exists in that group.)
return error("User " + sUser + " is already a member of " + sGroup + ". User Path=" + user.Path + ", Group Path=" + group.Path, false);
}
catch(System.Runtime.Inter opServices .COMExcept ion ce)
{
//return exceptionError(ce);
return error("Group path: " + groupPath + ", User path: " + userPath, true);
}
catch(Exception ex)
{
return exceptionError(ex);
}
return true;
}
/// Adds a domain user to a local group.
/// </summary>
/// <param name="sDomain">The domain in which the user is found.</param>
/// <param name="sUser">The username.</param>
/// <param name="sGroup">Group name.</param>
/// <returns></returns>
public bool addDomainUserToLocalGroup(
{
// Perform some basic error handling on parameters.
if(sGroup == "" || sGroup == null)
return error("Invalid group name.", true);
if(sUser == "" || sUser == null)
return error("Invalid user name.", true);
if(sMachine == "" || sMachine == null)
return error("Invalid machine name.", true);
string userPath, groupPath;
if(sDomain != "" && sDomain != null)
{
userPath = "WinNT://" + sDomain + "/" + sUser;
groupPath = "WinNT://" + this.sMachine + "/" + sGroup;
}
else
return error("The domain was not specified.", true);
try
{
DirectoryEntry group = new DirectoryEntry(groupPath, this.AuthUser, this.AuthPassword);
DirectoryEntry user = new DirectoryEntry(userPath, this.AuthUser, this.AuthPassword);
if(!dirExists(group.Path))
return error("Group " + sGroup + " does not exist. Path: " + group.Path, true);
if(!dirExists(user.Path))
return error("User " + sUser + " does not exist. Path: " + user.Path, true);
bool isMember = (bool)group.Invoke("isMemb
//bool isMember = false;
// If the user is not a member of the specified group already...
if(!isMember)
{
// Go ahead and invoke the Add method and commit changes.
group.Invoke("add", new object[] { userPath } );
group.CommitChanges();
}
else
// Otherwise, flag an error (the user already exists in that group.)
return error("User " + sUser + " is already a member of " + sGroup + ". User Path=" + user.Path + ", Group Path=" + group.Path, false);
}
catch(System.Runtime.Inter
{
//return exceptionError(ce);
return error("Group path: " + groupPath + ", User path: " + userPath, true);
}
catch(Exception ex)
{
return exceptionError(ex);
}
return true;
}
ASKER
By the way, it also throws on the Invoke isMember method.
-Dan
-Dan
ASKER
Hell, I got it to work, imagine that...
When you login, you have to login as DOMAIN\user with a backslash.
Any paths you reference must all have forward slashes.
Wow!
Here you go... :)
When you login, you have to login as DOMAIN\user with a backslash.
Any paths you reference must all have forward slashes.
Wow!
Here you go... :)
http://www.netomatix.com/DirectoryServices.aspx
It has whole bunch os samples on enumerating users, groups etc. Some are using LDAP provider, but can replace it with WinNT provider.