I have an application that checks to see if a user exists (if not create it) every time it starts. This is done as follows:
bool bUserExists = false;
DirectoryEntry dirEntryLocalMachine =
new DirectoryEntry("WinNT://" + Environment.MachineName + ",computer");
DirectoryEntries dirEntries = dirEntryLocalMachine.Children;
foreach (DirectoryEntry dirEntryUser in dirEntries)
{
bUserExists = dirEntryUser.Name.Equals("UserName",
StringComparison.CurrentCultureIgnoreCase);
if (bUserExists)
break;
}
The problem is on the majority of the systems where it is deployed. This can take 6 - 10 seconds, which is too long ... I need to find a way to reduce this (as much as possible). Is there a better or faster way I can use to verify if a user exists on the system or not?
I know there are other ways to solve this, like have the other applications sleep for 10 seconds, or have this tool send a message when it is ready, etc... But if I can greatly reduce the time it takes to find the user, it would make my life much easier.
.NET 3.5 supports new AD querying classes under the System.DirectoryServices.AccountManagement
namespace.
To make use of it, you'll need to add "System.DirectoryServices.AccountManagement" as a reference AND add the using
statement.
using System.DirectoryServices.AccountManagement;
using (PrincipalContext pc = new PrincipalContext(ContextType.Machine))
{
UserPrincipal up = UserPrincipal.FindByIdentity(
pc,
IdentityType.SamAccountName,
"UserName");
bool UserExists = (up != null);
}
< .NET 3.5
For versions of .NET prior to 3.5, here is a clean example I found on dotnet-snippets
DirectoryEntry dirEntryLocalMachine =
new DirectoryEntry("WinNT://" + Environment.MachineName + ",computer");
bool UserExists =
dirEntryLocalMachine.Children.Find(userIdentity, "user") != null;
You want to use the DirectorySearcher.
Something like this:
static bool userexists( string strUserName ) {
string adsPath = string.Format( @"WinNT://{0}", System.Environment.MachineName );
using( DirectoryEntry de = new DirectoryEntry( adsPath ) ) {
try {
return de.Children.Find( strUserName ) != null;
} catch( Exception e ) {
return false;
}
}
}
That should be quicker. Also, you can reduce the properties if all you are doing is checking for existence.
Another way is the following (supports either local or domain user):
bool UserExists(string userName)
{
var user = new NTAccount(userName);
try
{
var sid = (SecurityIdentifier)user.Translate(typeof(SecurityIdentifier));
return true;
}
catch (IdentityNotMappedException)
{
return false;
}
}
User may be either unqualified, or qualified by machine/domain name (DOMAIN\UserName
). If you need to specifically detect if the account exists on local machine, qualify it by Environment.MachineName
($"{Environment.MachineName}\\{userName}"
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With