I need to test which Windows users have administrator privileges.
OK, now read carefully: NOT CURRENT USER. I query all local user accounts, then I test which one of them has administrator privileges. Let's say I'm logged as Joe, my application runs in Joe user's context, but there is a user Timmy on this very PC, who is not currently logged on. I need to test if Timmy has admin on this PC. So, this question is definitely not about current user privileges ;) So, this is definitely not a duplicate of similar questions about determining the privileges of the current user. This one is different ;)
Here's my code:
public static dynamic[] Users => WMI.Query("SELECT * FROM Win32_UserAccount WHERE Disabled = 0").Select<dynamic, dynamic>(d => {
var machineContext = new PrincipalContext(ContextType.Machine);
Principal principal = Principal.FindByIdentity(machineContext, d.SID);
d.IsAdmin = principal.IsMemberOf(machineContext, IdentityType.Name, "Administrators");
principal.Dispose();
machineContext.Dispose();
return d;
}).ToArray();
This works, but it takes more than 2 seconds to execute IsMemberOf()
.
Is there a faster way to do this?
Why is it so slow?
If you wonder what WMI.Query
does here, it just queries the WMI and returns result as an array of managed dynamic
objects instead of IDisposable
types. IDisposable
types are disposed before the result is returned. Irrelevant to the question, though.
To clarify, I use System.DirectoryServices.AccountManagement
to get an actual user account from SID. I don't know if WindowsIdentity
can be created from SID. AFAIK it can't. The user for WindowsIdentity
needs to be logged on (throws a SecurityException if not), and I query all local users, not just the current one.