I'm looking for a way to get the users that are logged in on a remote machine. I would love to know if they are logged on localy or remotely, but most of all I MUST know their status. I saw some answers on the net that are written in VB, but I need it in c#. the solution given in markdmak answer here is looking like a good start, but it's in VB and it looks for remote sessions only. I have this piece of code, which can be a start, but I would like to couple the LogonId to a username and to see its status:
string fqdn = ""; // set!!!
ConnectionOptions options = new ConnectionOptions();
options.EnablePrivileges = true;
// To connect to the remote computer using a different account, specify these values:
// these are needed in dev environment
options.Username = ConfigurationManager.AppSettings["KerberosImpersonationUser"];
options.Password = ConfigurationManager.AppSettings["KerberosImpersonationPassword"];
options.Authority = "ntlmdomain:" + ConfigurationManager.AppSettings["KerberosImpersonationDomain"];
ManagementScope scope = new ManagementScope("\\\\" + fqdn + "\\root\\CIMV2", options);
try
{
scope.Connect();
}
catch (Exception ex)
{
if (ex.Message.StartsWith("The RPC server is unavailable"))
{
// The Remote Procedure Call server is unavailable
// cannot check for logged on users
return false;
}
else
{
throw ex;
}
}
SelectQuery query = new SelectQuery("Select * from Win32_LogonSession");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
ManagementObjectCollection results = searcher.Get();
bool returnVal = false;
foreach (ManagementObject os in results)
{
try
{
if (os.GetPropertyValue("LogonId").ToString() != null && os.GetPropertyValue("LogonId").ToString() != "")
{
returnVal = true;
}
}
catch (NullReferenceException)
{
continue;
}
}
return returnVal;
}
What I really need and can't find, is a way of getting ALL users on a remote machine AND their status, meaning: Active, Disconnected, Logged-off, etc.
w command – Shows information about the users currently on the machine, and their processes.
Step 1- Open the Command Line Interface by running "cmd" in the run dialog box (Win + R). Step 2- Type query user and press Enter. It will list all users that are currently logged on your computer.
You can use the Win32_LogonSession
WMI class filtering for the LogonType
property with the value 2 (Interactive)
Try this sample
using System;
using System.Collections.Generic;
using System.Management;
using System.Text;
namespace GetWMI_Info
{
class Program
{
static void Main(string[] args)
{
try
{
string ComputerName = "remote-machine";
ManagementScope Scope;
if (!ComputerName.Equals("localhost", StringComparison.OrdinalIgnoreCase))
{
ConnectionOptions Conn = new ConnectionOptions();
Conn.Username = "username";
Conn.Password = "password";
Conn.Authority = "ntlmdomain:DOMAIN";
Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", ComputerName), Conn);
}
else
Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", ComputerName), null);
Scope.Connect();
ObjectQuery Query = new ObjectQuery("SELECT LogonId FROM Win32_LogonSession Where LogonType=2");
ManagementObjectSearcher Searcher = new ManagementObjectSearcher(Scope, Query);
foreach (ManagementObject WmiObject in Searcher.Get())
{
Console.WriteLine("{0,-35} {1,-40}", "LogonId", WmiObject["LogonId"]);// String
ObjectQuery LQuery = new ObjectQuery("Associators of {Win32_LogonSession.LogonId=" + WmiObject["LogonId"] + "} Where AssocClass=Win32_LoggedOnUser Role=Dependent");
ManagementObjectSearcher LSearcher = new ManagementObjectSearcher(Scope, LQuery);
foreach (ManagementObject LWmiObject in LSearcher.Get())
{
Console.WriteLine("{0,-35} {1,-40}", "Name", LWmiObject["Name"]);
}
}
}
catch (Exception e)
{
Console.WriteLine(String.Format("Exception {0} Trace {1}", e.Message, e.StackTrace));
}
Console.WriteLine("Press Enter to exit");
Console.Read();
}
}
}
@RRUZ got me started but the Associators
query did not work on remote machine with a lot of Win32_LoggedOnUser
objects (don't know why). No results were returned.
I also needed remote Desktop sessions so I used LogonType "10" sessions and my ConnectionOptions
were differents
I replaced the Associators query with WmiObject.GetRelationships("Win32_LoggedOnUser")
and the speed increases by a lot and results were there.
private void btnUnleash_Click(object sender, EventArgs e)
{
string serverName = "serverName";
foreach (var user in GetLoggedUser(serverName))
{
dataGridView1.Rows.Add(serverName, user);
}
}
private List<string> GetLoggedUser(string machineName)
{
List<string> users = new List<string>();
try
{
var scope = GetManagementScope(machineName);
scope.Connect();
var Query = new SelectQuery("SELECT LogonId FROM Win32_LogonSession Where LogonType=10");
var Searcher = new ManagementObjectSearcher(scope, Query);
var regName = new Regex(@"(?<=Name="").*(?="")");
foreach (ManagementObject WmiObject in Searcher.Get())
{
foreach (ManagementObject LWmiObject in WmiObject.GetRelationships("Win32_LoggedOnUser"))
{
users.Add(regName.Match(LWmiObject["Antecedent"].ToString()).Value);
}
}
}
catch (Exception ex)
{
users.Add(ex.Message);
}
return users;
}
private static ManagementScope GetManagementScope(string machineName)
{
ManagementScope Scope;
if (machineName.Equals("localhost", StringComparison.OrdinalIgnoreCase))
Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", "."), GetConnectionOptions());
else
{
Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", machineName), GetConnectionOptions());
}
return Scope;
}
private static ConnectionOptions GetConnectionOptions()
{
var connection = new ConnectionOptions
{
EnablePrivileges = true,
Authentication = AuthenticationLevel.PacketPrivacy,
Impersonation = ImpersonationLevel.Impersonate,
};
return connection;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With