testing(不是当前)用户是否是pipe理员的更快方法

我需要testing哪些Windows用户具有pipe理员权限。

好,现在仔细阅读: 不是当前用户 。 我查询所有本地用户帐户,然后testing其中哪一个具有pipe理员权限。 比方说,我被logging为乔,我的应用程序运行在乔用户的上下文,但有一个用户蒂米在这台电脑,谁目前没有login。 我需要testingTimmy是否在这台PC上有pipe理员。 所以,这个问题绝对不是关于当前的用户权限)所以,这绝对不是有关确定当前用户权限的类似问题的重复。 这一个是不同的;)

这是我的代码:

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(); 

这可以工作,但是执行IsMemberOf()需要2秒多的时间 。 有没有更快的方法来做到这一点? 为什么这么慢?

如果您想知道WMI.Query在这里做了什么,它只是查询WMI并将结果作为受pipedynamic对象的数组而不是IDisposabletypes返回。 在返回结果之前丢弃IDisposabletypes。 不过,与这个问题无关。

为了澄清,我使用System.DirectoryServices.AccountManagement从SID获取实际的用户帐户。 我不知道是否可以从SID创buildWindowsIdentity 。 AFAIK它不能。 WindowsIdentity的用户需要login(如果没有,则抛出SecurityException),我查询所有本地用户,而不仅仅是当前用户。

那么,我发现了,但它仍然很奇怪…

更新后的代码:(我将匹配的组名更改为匹配的组SID)。

 public static dynamic[] Users => WMI.Query("SELECT * FROM Win32_UserAccount WHERE Disabled = 0").Select<dynamic, dynamic>(d => { using (var machineContext = new PrincipalContext(ContextType.Machine)) using (Principal principal = Principal.FindByIdentity(machineContext, d.SID)) d.IsAdmin = principal.GetGroups().Any(i => i.Sid.IsWellKnown(System.Security.Principal.WellKnownSidType.BuiltinAdministratorsSid)); return d; }).ToArray(); 

事实证明IsMemberOf()IsMemberOf()快得多。

更新:实际上大约快了135倍。 带有Any()IsMemberOf()花了17ms而不是2300ms的IsMemberOf()

作为奖励,我将与我的WMI.Qurey分享;)

 /// <summary> /// Safe, managed WMI queries support. /// </summary> static class WMI { /// <summary> /// Queries WMI and returns results as an array of dynamic objects. /// </summary> /// <param name="q"></param> /// <returns></returns> public static dynamic[] Query(string q) { using (var s = new ManagementObjectSearcher(q)) return s .Get() .OfType<ManagementObject>() .Select(i => { var x = new ExpandoObject(); using (i) foreach (var p in i.Properties) (x as IDictionary<string, object>).Add(p.Name, p.Value); return x; }) .ToArray(); } 

}