0

Anyone else had to determine who the currently logged on user is remotely in a Windows 7 environment? I am using .NET 4.0 and C#. The environment is mixed XP and 7.

  • WMI queries involving sessions result in all active sessions, but not the session that is interactive.
  • UserName from ComputerSystem (WMI) returns null exception if user is connected via Remote Desktop, which is common enough that this method cannot be used.
  • PsLoggedOn takes too long for my purposes (yes, 300 ms is too long) and is surprisingly not accurate 100% of the time
  • Using p/invoke for WTSGetActiveConsoleSessionID or LsaEnumerateLogonSessions is too complicated and prone to memory leaks (from what I've read)
  • tasklist /S <computername> will return information for XP systems, but Windows 7 won't be agreeable thanks to that lovely UAC.
  • HKCU (win registry) is inaccessible remotely due to permissions restrictions, HKU is accessible, but Volatile Environment doesn't appear to have a tag for "active"

So far, the most reliable way is using PsExec to remotely execute qwinsta from the command line and traverse the output to text remotely. This is annoying and takes time (more than PsLoggedOn), but I'm running out of ideas here for reliability. Reliability before speed, but speed is very important in terms of cost benefit.

Third party tools are not an option, has to be a script, preferably WMI and C#. I delved into hitting the DC using Principal objects, but I'm afraid I might have confused myself more. Also, all user accounts are administrators.

I've done a lot of research over Google, but I am thinking that maybe I am looking in the wrong place.

Any takers?

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
Quadwar
  • 1
  • 1
  • 1

1 Answers1

0

you can achieve this by browsing Win32_ComputerSystem class's UserName Propperty :

   ConnectionOptions con = new ConnectionOptions();
   con.Username = "Administrator";
   con.Password = "********";
   ManagementScope scope = new ManagementScope(@"\\" + strIPAddress + @"\root\cimv2", con);
   scope.Connect();

//check for scope.IsConnected, then process

   ManagementObjectSearcher searcher =new ManagementObjectSearcher(@"\\" + strIPAddress + @"\root\cimv2", "SELECT * FROM Win32_ComputerSystem"); 

   foreach (ManagementObject queryObj in searcher.Get())
    {
      Console.WriteLine("-----------------------------------");
      Console.WriteLine("Win32_ComputerSystem instance");
      Console.WriteLine("-----------------------------------");
      Console.WriteLine("UserName: {0}", queryObj["UserName"]);
    }
Mohammad Arshad Alam
  • 9,694
  • 6
  • 38
  • 61
  • Main problem is that if the user is logged into that computer with Remote Desktop, the WMI call will return a null exception. We've tested it. Why it will only work if someone is logged in via console and not RDP doesn't make sense to me, but I don't know the inner workings so there may be a good reason. – Quadwar Feb 20 '13 at 14:18
  • have you tested the connection with remote computer – Mohammad Arshad Alam Feb 20 '13 at 14:23
  • Yes. It's the main reason I posted this. I can't seem to find a solution that will find the current user that is "interactively" logged in for all scenarios. Remote Desktop is common enough in this organization that I can't overlook it. – Quadwar Feb 20 '13 at 16:37
  • Sorry for the late response, Arshad, I appreciate your tenacity. This actually did not work, either. What I ended up doing is using WMI to iterate through HKU, using the SID's, I pull ProfileImagePath, parse for username, from the HKLM\Software\Microsoft\Windows NT\CurrentVersion\ProfList\ and basically just say that these users are all logged in. I could technically get this information from HKU, but depending on the config of the machine, volatile environment did not always report the correct values, whereas proflist always has the username. – Quadwar Aug 10 '13 at 00:24