NetWkstaUserEnum (netapi32)
Last changed: -69.60.207.16

.
Summary
The NetWkstaUserEnum function lists information about all users currently logged on to the workstation. This list includes interactive, service and batch logons.

C# Signature:

    [DllImport("netapi32.dll", CharSet = CharSet.Unicode, SetLastError=true)]
    static extern int NetWkstaUserEnum(
       string servername,
       int level,
       out IntPtr bufptr,
       int prefmaxlen,
       out int entriesread,
       out int totalentries,
       ref int resume_handle);

VB Signature:

<DllImport("netapi32.dll", CharSet := CharSet.Unicode, SetLastError:=True)> _

Shared Function NetWkstaUserEnum(ByVal servername As String, ByVal level As Integer, <System.Runtime.InteropServices.Out()> ByRef bufptr As IntPtr, ByVal prefmaxlen As Integer, <System.Runtime.InteropServices.Out()> ByRef entriesread As Integer, <System.Runtime.InteropServices.Out()> ByRef totalentries As Integer, ByRef resume_handle As Integer) As Integer

End Function

User-Defined Types:

See sample code for types and constants.

Alternative Managed API:

WMI can do this sort of thing (the System.Management namespace in .Net 2.0)

Notes:

If you want to find the user logged in to the workstation, consider instead a WMI query ("select UserName from Win32_ComputerSystem"), which has certain advantages (runs faster, less ambigious results, doesn't require Interop if using .Net 2.0 System.Management namespace, etc.)

Tips & Tricks:

Please add some!

* On Windows 8+ when users log in with a MicrosoftAccount the username is returned like "MicrosoftAccount\user.email@thedomain.com" rather than the ID. This means for example that it won't match their directory name in C:\Users.

Sample Code:

  class NetWorkstationUserEnum
  {
    [DllImport("netapi32.dll", CharSet = CharSet.Unicode, SetLastError=true)]
    static extern int NetWkstaUserEnum(
       string servername,
       int level,
       out IntPtr bufptr,
       int prefmaxlen,
       out int entriesread,
       out int totalentries,
       ref int resume_handle);

    [DllImport("netapi32.dll")]
    static extern int NetApiBufferFree(
       IntPtr Buffer);

    const int NERR_SUCCESS = 0;
    const int ERROR_MORE_DATA = 234;

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct WKSTA_USER_INFO_0
    {
        public string wkui0_username;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct WKSTA_USER_INFO_1
    {
        public string wkui1_username;
        public string wkui1_logon_domain;
        public string wkui1_oth_domains;
        public string wkui1_logon_server;
    }
    void ScanHost(string hostName)
    {

        IntPtr bufptr = IntPtr.Zero;
        int dwEntriesread;
        int dwTotalentries = 0;
        int dwResumehandle = 0;
        int nStatus;
        Type tWui1 = typeof(WKSTA_USER_INFO_1);
        int nStructSize = Marshal.SizeOf(tWui1);
        WKSTA_USER_INFO_1 wui1;

        //this.listView1.Items.Clear();

        do
        {
        nStatus = NetWkstaUserEnum(
          hostName,
1,           out bufptr,
          32768,
          out dwEntriesread,
          out dwTotalentries,
          ref dwResumehandle);

        //
        // If the call succeeds,
        //
        if ((nStatus == NERR_SUCCESS) | (nStatus == ERROR_MORE_DATA))
        {
            if (dwEntriesread > 0)
            {
            IntPtr pstruct = bufptr;

            //
            // Loop through the entries.
            //
            for (int i = 0; i < dwEntriesread; i++)
            {
                wui1 = (WKSTA_USER_INFO_1)Marshal.PtrToStructure(pstruct, tWui1);
                Console.WriteLine(wui1.wkui1_logon_domain + "\\" + wui1.wkui1_username);
                pstruct = (IntPtr)((int)pstruct + nStructSize);
            }
            }
            else
            {
            Console.WriteLine("A system error has occurred : " + nStatus);
            }
        }

        if (bufptr != IntPtr.Zero)
            NetApiBufferFree(bufptr);

        } while (nStatus == ERROR_MORE_DATA);
    }
    static public void Main(string[] args)
    {
        string host = Environment.MachineName;
        if (args.Length > 0)
        {
        host = args[0];
        }
        NetWorkstationUserEnum nws = new NetWorkstationUserEnum();
        nws.ScanHost(host);
    }
  }

Documentation

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netmgmt/netmgmt/netwkstauserenum.asp