This is based on my finding in http://www.seirer.net/blog/2013/9/12/how-to-deal-with-localized-or-renamed-administrators-in-net , written by Michael Seirer. He tried to get the SID of the local administrator account, and all we need are the names in this group. The cause of the error is "Member SID cannot be resolved." because there are accounts that are no longer recognized in Active Directory - probable relics pointing to remote user accounts. You can either do what Microsoft says and just delete them, and hope that your application never crashes (although it will be the next time the account is deleted, which is in this group of "Administrators") , or solve it forever with this code, which I slightly modified from Mike.
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);
It will return a List<string> members of the local Administrators group on the local machine. You can even change Environment.MachineName as any computer name in your domain if you do not want a local machine.
Then you can iterate over the list to see if they are in it:
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 }
source share