How to get all user account names in XP, Vist & 7, for 32 or 64 bit and any OS language

I have a winform C # application that will be installed on Windows 7, Vista and XP, 32 or 64 bit machines, with operating systems in English, German and Spanish (and other languages ​​in the future).

I need to get a list of all the administrator account and user names on the local computer. I just need a list of account names, nothing more.

The problem is that my code only works for English operating systems.

Is there a way to get user names on the local computer, regardless of the language of the OS, and regardless of whether it is XP, Vista or 7 and regardless of 32 or 64 bits?

I read a post somewhere about using the SID to get the local administrator name if it was renamed. Can using SID be helpful in solving my problem?

Below is my code. On a computer with a German OS, the code does not work in the line "DirectoryEntry admGroup = localMachine.Children.Find (" administrators "," group ");". This, most likely, fails, because in the German OS the words "administrators", "group" are most likely written differently. The same is probably true for the OS in Spanish.

My code for 32-bit OS:

DirectoryEntry localMachine = new DirectoryEntry( "WinNT://" + Environment.MachineName); DirectoryEntry admGroup = localMachine.Children. Find("administrators", "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); if (!(member.Name == "admin" || member.Name == "Domain Admins")) { drow = dtWindowsUser.NewRow(); drow["WindowsUser"] = member.Name; //Add row to datatable dtWindowsUser.Rows.Add(drow); } } foreach (object groupMember in (IEnumerable)usermembers) { DirectoryEntry member = new DirectoryEntry(groupMember); if (!(member.Name == "ACTUser" || member.Name == "ASPNET" || member.Name == "Domain Users" || member.Name == "Authenticated Users" || member.Name == "INTERACTIVE" || member.Name == "SQLDebugger")) { drow = dtWindowsUser.NewRow(); drow["WindowsUser"] = member.Name; //Add row to datatable dtWindowsUser.Rows.Add(drow); } } 

My code for 64bit OS:

 SelectQuery query = new SelectQuery("Win32_UserAccount"); ManagementObjectSearcher searcher = new ManagementObjectSearcher(query); foreach (ManagementObject envVar in searcher.Get()) { str_name = envVar["Name"].ToString(); if (!(str_name == "admin" || str_name == "Domain Admins")) { if (!(str_name == "ACTUser" || str_name == "ASPNET" || str_name == "Domain Users" || str_name == "Authenticated Users" || str_name == "INTERACTIVE" || str_name == "SQLDebugger")) { if (!(str_name == "HomeGroupUser$")) { drow = dtWindowsUser.NewRow(); drow["WindowsUser"] = str_name; //Add row to datatable dtWindowsUser.Rows.Add(drow); } } } } 
+7
source share
4 answers

Even in a system that uses English, you do not want to receive groups by name - you can rename them from the expected. For built-in groups, such as Administrators, you want to use a well-known SID that will work regardless of which language is used to designate the group.

This is one way to get the data you need ...

 SecurityIdentifier builtinAdminSid = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null); PrincipalContext ctx = new PrincipalContext(ContextType.Machine); GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, builtinAdminsSid.Value); foreach (Principal p in group.Members) { Console.WriteLine(p.Name); } 


Edit: @joung's suggestion to use WellKnownSidType is a much better idea than using an encoded magic value like String builtinAdminsSidString = "S-1-5-32-544"; so I changed the above code example.

+5
source

This example of how to get the administrator name may be useful.

 var builtinAdministratorsName = new SecurityIdentifier( WellKnownSidType.BuiltinAdministratorsSid, null). Translate(typeof(NTAccount)).Value; 
+4
source

Please try the following:

 using System.Management; using (var accountSearcher = new System.Management.ManagementObjectSearcher("SELECT * FROM Win32_UserAccount WHERE LocalAccount=True")) using (var accountCollection = accountSearcher.Get()) foreach (var account in accountCollection) this.listBox1.Items.Add(account["Name"].ToString()); 
0
source

get the language using GetSystemUILanguage , and then use the switch case (u urself should search for folder names).

-one
source

All Articles