21

How can I get a list of local computer usernames in windows using C#?

Bobby
  • 11,419
  • 5
  • 44
  • 69
MBZ
  • 26,084
  • 47
  • 114
  • 191

5 Answers5

32
using System.Management;

SelectQuery query = new SelectQuery("Win32_UserAccount");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
foreach (ManagementObject envVar in searcher.Get())
{
     Console.WriteLine("Username : {0}", envVar["Name"]);
}

This code is the same as the link KeithS posted. I used it a couple years ago without issue but had forgotten where it came from, thanks Keith.

sclarson
  • 4,362
  • 3
  • 32
  • 44
  • "without issue" -> in my experience WMI has a failure rate > 0.5%, so be careful if integrating in a customer facing app – eglasius Aug 10 '12 at 08:43
  • 2
    Warning: This command will take a very long time if you are connected to a large network. You can test this command in airplane mode to find the expected results. – Mike Oct 10 '17 at 22:30
  • Is there any way to do this without wmi? – jjxtra Jan 09 '22 at 15:59
  • 1
    Note that, if your computer is connected to a AD domain, this could does *not* return the local users but the users in your domain. You need to add `$"domain='{Environment.MachineName}'"` as second parameter to the `SelectQuery` constructor to get only the local users. – Sebastian Krysmanski Jun 10 '22 at 06:24
10

I use this code to get my local Windows 7 users:

public static List<string> GetComputerUsers()
{
    List<string> users = new List<string>();
    var path =
        string.Format("WinNT://{0},computer", Environment.MachineName);

    using (var computerEntry = new DirectoryEntry(path))
        foreach (DirectoryEntry childEntry in computerEntry.Children)
            if (childEntry.SchemaClassName == "User")
                users.Add(childEntry.Name);

    return users;
}
VansFannel
  • 45,055
  • 107
  • 359
  • 626
0

Here is a method to list all users (including hidden ones) that works well without WMI or Netapi32.dll:

//Register a process execution context that will list all users on this machine without displaying a separate window
System.Diagnostics.ProcessStartInfo execution = new System.Diagnostics.ProcessStartInfo
{
    //Make sure the windows SendMessage pump knows to hide the window
    WindowStyle = ProcessWindowStyle.Hidden,
    //Make sure command prompt runs as a child process of your exe
    CreateNoWindow = true,
    //Redirect execution errors to the calling C# code
    RedirectStandardError = true,
    //Redirect execution output to the calling C# code
    RedirectStandardOutput = true,
    //Do not use windows shell to execute this process
    UseShellExecute = false,
    //Specify command prompt as the executed process
    FileName = "cmd.exe",
    //Tell command prompt to output this machine's entire username database
    Arguments = "/c net user"
};

//Execute the configured process
System.Diagnostics.Process process = System.Diagnostics.Process.Start(execution);

//Register the executed process output stream & grab only the user names from the output
MatchCollection output = new Regex(@"(((?! )(?<= {2,}).)((?![" + "\"" + @"&/\[\]:\|\<\>\+=;,\?\*%@]| {2,}).)+(?= {2,}))|((?<! {2,})((?![" + "\"" + @"&/\[\]:\|\<\>\+=;,\?\*%@]| {2,}).)+(?= {2,}))", RegexOptions.Compiled).Matches(process.StandardOutput.ReadToEnd());

//Wait for the executed process to quit
process.WaitForExit();

//Sample the registered usernames for this PC
for(int i = 0; i < output.Count; i++)
{
    //Do summin with the selected username string
    Console.WriteLine("\n" + output[i].Value + "\n");
}

As you can see, at the heart of this code is the net user command. Therefore, you have quite a few options to play with, like getting users from another PC on your network.

Also the RegEx I wrote is a bit long, it can be broken into two RegEx patterns. Usernames & trailing spaces can be matched first with trailing white space being removed per username in the loop.

Here's the two patterns' code for that approach, if you'd prefer:

//Execute the configured process
System.Diagnostics.Process process = System.Diagnostics.Process.Start(execution);

//Register the executed process output stream & grab only the user names from the output
MatchCollection output = new Regex(@"((?![" + "\"" + @"&/\[\]:\|\<\>\+=;,\?\*%@]| {2,}).)+(?= {2,})", RegexOptions.Compiled).Matches(process.StandardOutput.ReadToEnd());

//Wait for the executed process to quit
process.WaitForExit();

//Declare a trailing white space RegEx pattern
Regex trailingSpaces = new Regex(@"^ +| +$", RegexOptions.Compiled);

//Sample the registered usernames for this PC
for(int i = 0; i < output.Count; i++)
{
    //Do summin with the selected username string
    Console.WriteLine("\n" + trailingSpaces.Replace(output[i].Value, "") + "\n");
}

Note that the literal ' ' character is used rather than \s because \s will match newline & tab characters which will include these two extra lines:

"User accounts for \PCNAME-PC"

and

"-------------------------------------------------------------------------------"

(^^ Quotes are to stop stackoverflow's formatting)

Finally, keep in mind that net user is only available from Windows Vista onward. On XP or earlier, you're in the dark I think. Unless someone else has some neat cmd code for that?

Anyways, I hope this helps you or anyone else that needs this :).

Aldeatho
  • 11
  • 2
-1

One way would be to list the directories in C:\Documents and Settings (in Vista/7: C:\Users).

yellowblood
  • 1,604
  • 2
  • 17
  • 32
-3

The following are a few different ways to get your local computer name:

string name = Environment.MachineName;
string name = System.Net.Dns.GetHostName();
string name = System.Windows.Forms.SystemInformation.ComputerName;
string name = System.Environment.GetEnvironmentVariable(“COMPUTERNAME”);
James
  • 641
  • 3
  • 10