HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

User Logged onto Windows

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
userontologgedwindows

Problem

I created a Windows Service that Tracks which App Server a user is actually connected to through a load balancer.

It retrieves the user that is logged into windows on that machine, then cross references the Active Directory (AD) account to return the first name, last name and E-mail (for notification through the website created for this project)

There is one system on the Network where users only remote into the system, the Vista System, for some reason it is returning with Values that say "LOCAL SERVICE" is Logged into that machine, it's weird and the Security Guys say that it is impossible for the "LOCAL SERVICE" account to be logged into Windows.

Here is how I get the user that is logged into Windows

ManagementScope ms = new ManagementScope("\\\\.\\root\\cimv2");
ObjectQuery query = new ObjectQuery("select * from win32_computersystem");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(ms, query);

foreach (ManagementObject mo in searcher.Get())
{
    _username = mo["username"].ToString();
}
// remove the domain part from the username
string[] usernameParts = _username.Split('\\');
_username = usernameParts[usernameParts.Length - 1];


I only post this because, it isn't broken, it does exactly what it is supposed to.

is this an Edge Case that I can fix, or is the user actually "logged in" to this machine

Is there something that I can do to make this code more efficient?

I have cross posted this on SuperUser Migrated cross post to StackOverflow

Solution

As per my second comment, below is a possible solution. This solution involves a different querying method that will work for both console sessions and remote sessions. This method looks at all processes that are the explore.exe process, which is the user shell for each user that is logged into the server. Once armed with the list of those processes, getting the owner for it is another WMI query (GetProcessOwner method).

// what to do if multiple users logged in?
foreach (var p in Process.GetProcessesByName("explorer"))
{
    _username = GetProcessOwner(p.Id);
}

// remove the domain part from the username
var usernameParts = _username.Split('\\');

_username = usernameParts[usernameParts.Length - 1];


...

public static string GetProcessOwner(int processId)
    {
        var query = "Select * From Win32_Process Where ProcessID = " + processId;
        ManagementObjectCollection processList;

        using (var searcher = new ManagementObjectSearcher(query))
        {
            processList = searcher.Get();
        }

        foreach (var mo in processList.OfType())
        {
            object[] argList = { string.Empty, string.Empty };
            var returnVal = Convert.ToInt32(mo.InvokeMethod("GetOwner", argList));

            if (returnVal == 0)
            {
                // return DOMAIN\user
                return argList[1] + "\\" + argList[0];
            }
        }

        return "NO OWNER";
    }

Code Snippets

// what to do if multiple users logged in?
foreach (var p in Process.GetProcessesByName("explorer"))
{
    _username = GetProcessOwner(p.Id);
}

// remove the domain part from the username
var usernameParts = _username.Split('\\');

_username = usernameParts[usernameParts.Length - 1];
public static string GetProcessOwner(int processId)
    {
        var query = "Select * From Win32_Process Where ProcessID = " + processId;
        ManagementObjectCollection processList;

        using (var searcher = new ManagementObjectSearcher(query))
        {
            processList = searcher.Get();
        }

        foreach (var mo in processList.OfType<ManagementObject>())
        {
            object[] argList = { string.Empty, string.Empty };
            var returnVal = Convert.ToInt32(mo.InvokeMethod("GetOwner", argList));

            if (returnVal == 0)
            {
                // return DOMAIN\user
                return argList[1] + "\\" + argList[0];
            }
        }

        return "NO OWNER";
    }

Context

StackExchange Code Review Q#68076, answer score: 6

Revisions (0)

No revisions yet.