这很大程度上基于我在http://www.seirer.net/blog/2013/9/12/how-to-deal-with-localized-or-renamed-administrators-in-net上由 Michael Seirer 撰写的发现。他试图获取本地管理员帐户的 SID,而我们只需要该组中的名称。错误“无法解析成员的 SID”的原因。是因为 Active Directory 中不再识别某些帐户 - 可能是指向已删除用户帐户的遗物。您可以按照微软所说的去做,然后删除它们,并希望您的应用程序永远不会再次崩溃(尽管它会,下次删除该管理员组中的帐户时),或者使用我稍微修改的这段代码永久解决它麦克风。
using System.DirectoryServices;
using System.Collections;
using System.Runtime.InteropServices;
[DllImport("advapi32", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool ConvertSidToStringSid(IntPtr pSid, out string strSid);
private static string GetTextualSID(DirectoryEntry objGroup)
{
string sSID = string.Empty;
byte[] SID = objGroup.Properties["objectSID"].Value as byte[];
IntPtr sidPtr = Marshal.AllocHGlobal(SID.Length);
sSID = "";
System.Runtime.InteropServices.Marshal.Copy(SID, 0, sidPtr, SID.Length);
ConvertSidToStringSid((IntPtr)sidPtr, out sSID);
System.Runtime.InteropServices.Marshal.FreeHGlobal(sidPtr);
return sSID;
}
public static List<string> GetLocalAdministratorsNames()
{
List<string> admins = new List<string>();
DirectoryEntry localMachine = new DirectoryEntry("WinNT://" + Environment.MachineName);
string adminsSID = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null).ToString();
string localizedAdmin = new System.Security.Principal.SecurityIdentifier(adminsSID).Translate(typeof(System.Security.Principal.NTAccount)).ToString();
localizedAdmin = localizedAdmin.Replace(@"BUILTIN\", "");
DirectoryEntry admGroup = localMachine.Children.Find(localizedAdmin, "group");
object adminmembers = admGroup.Invoke("members", null);
DirectoryEntry userGroup = localMachine.Children.Find("users", "group");
object usermembers = userGroup.Invoke("members", null);
//Retrieve each user name.
foreach (object groupMember in (IEnumerable)adminmembers)
{
DirectoryEntry member = new DirectoryEntry(groupMember);
string sidAsText = GetTextualSID(member);
admins.Add(member.Name);
}
return admins;
}
它将返回List<string>
本地计算机上本地管理员组的成员。Environment.MachineName
如果您不想要本地计算机,您甚至可以更改为域中的任何计算机名称。
然后您可以迭代列表以查看它们是否在其中:
private static bool isAdmin(string user)
{
//string user = @"DOMAIN\doej";
user = user.Split(@'\')[1];
List<string> admins = GetLocalAdministratorsNames();
foreach (string s in admins)
{
if (s == user)
return true; // admin found
}
return false; // not an admin
}