How to enumerate Windows user accounts?

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

I'm trying to get a list of user accounts on the local computer - the same
list you see when you are about to log in to Windows XP or Vista. This needs
to work on a home computer (not connected to a domain). It's for a parental
control app where I want the parent to be able to assign rules for each
child's account. I've tried using the Win32 API
LsaEnumerateAccountsWithUserRight with the SE_INTERACTIVE_LOGON_NAME
privilege, but it doesn't work. I tried passing in NULL as the UserRights
parameter, which is supposed to return ALL accounts, but I get back a list
which has the built-in accounts and a few others (see below), but not one
single normal user account. I just want the accounts for people who can log
on interactively. I'd prefer if there was a fully .NET C# solution but I'll
do Win32 if I have to. Should I be using LsaLookupNames2 instead?

NT AUTHORITY\SERVICE
BUILTIN\Remote Desktop Users
BUILTIN\Backup Operators
BUILTIN\Users
BUILTIN\Administrators
Justin-Laptop\Guest
Justin-Laptop\SQLServer2005MSSQLUser$Justin-Laptop$SQLEXPRESS
Justin-Laptop\SQLServer2005SQLBrowserUser$Justin-Laptop
NT AUTHORITY\NETWORK SERVICE
NT AUTHORITY\LOCAL SERVICE
Everyone
 
This code seems to be heading in the right direction. But I really need the
SID for each account. And I'm not sure what groups to enumerate to match what
you see when you log in to Windows XP or Vista. This ActiveDirectory stuff is
new to me.

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);
Console.WriteLine(member.Name);
}
 
Try this inside the for loop:

string sid = new
SecurityIdentifier((byte[])member.Properties["objectSid"][0], 0).Value;
Console.WriteLine (sid);

This works with .NET 2.0 onwards.
 
Back
Top