There is a domain network with are connected computers.
Need a code that will display a list of Active Directory users connected to it now (using them / connected remotely).
Something similar to the "Users" tab in Task Manager, only for a domain network.
I tried to do this with WMI.
Classes Win32_LogonSession
, Win32_LoggedOnUser
, Win32_Account
The principle is this:
From active Win32_LogonSession
weeded out LogonType
= 2, 10 и 11.
By LogonId
from Win32_LoggedOnUser
get name and domain, search it in Win32_Account
(to weed out system sessions) (Below there will be a code, maybe someone will come in handy)
But I ran into a problem : the event Session_onEnd
is triggered far from 100% of cases, and LogOff
seems not to be recorded at all, or is recorded incorrectly.
As a result, I get a lot of "hanging" sessions that users connect to, or create new ones when they log in. Analysis of the Windows event log in this regard does not give anything useful either. (LogOff
is still incorrect)
So, if I can connect to a computer and get all the information out of it, how to extract - is it in use now and who is using it?
using System;
using System.Collections.Generic;
using System.Data;
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
using System.Linq;
using System.Management;
using System.Net;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace UserManager
{
public partial class LogOnSession : Form
{
List<LogOnSessionR> SessionsList = new List<LogOnSessionR>();
List<LoggedOnUser> LoggedList = new List<LoggedOnUser>();
List<PC> CompList = new List<PC>();
public LogOnSession()
{
InitializeComponent();
}
private void LogOnSession_Load(object sender, EventArgs e)
{
if (Form1.SelfRef != null)
{
CBDomain.Items.Add("All Forest");
foreach (object a in Form1.SelfRef.CBDomain.Items)
{
CBDomain.Items.Add(a);
}
CBDomain.SelectedIndex = Form1.SelfRef.CBDomain.SelectedIndex;
}
GetComputersInDomain(CBDomain.SelectedIndex);
CBComputers.SelectedIndex = 0;
}
private void CBDomain_SelectedIndexChanged(object sender, EventArgs e)
{
LogOnListView.Items.Clear();
GetComputersInDomain(CBDomain.SelectedIndex);
}
public void GetComputersInDomain(int I)
{
CompList.Clear();
CBComputers.Items.Clear();
if (I == 0)
{
DirectoryEntry de = new DirectoryEntry();
DirectorySearcher myADSearcher = new DirectorySearcher(de);
myADSearcher.Filter = "(&(objectClass=computer))";
foreach (SearchResult sr in myADSearcher.FindAll())
{
PC pc = new PC();
pc.Name = removeCN(sr.GetDirectoryEntry().Name);
pc.IP = getPCIP(pc.Name);
CompList.Add(pc);
}
}
else
{
DirectoryEntry de = new DirectoryEntry("LDAP://" + Form1.ListDomain[I-1].Name);
DirectorySearcher myADSearcher = new DirectorySearcher(de);
myADSearcher.Filter = "(&(objectClass=computer))";
foreach (SearchResult sr in myADSearcher.FindAll())
{
PC pc = new PC();
pc.Name = removeCN(sr.GetDirectoryEntry().Name);
pc.IP = getPCIP(pc.Name);
CompList.Add(pc);
}
}
CBComputers.Items.Add("All");
foreach (PC pc in CompList)
{
CBComputers.Items.Add(pc.Name);
}
}
public string removeCN(string str)
{
if (str.Contains("CN="))
{
return str.Replace("CN=", "");
}
else
{
return str;
}
}
public string getPCIP(string hostName)
{
IPHostEntry hostEntry;
hostEntry = Dns.GetHostEntry(hostName);
if (hostEntry.AddressList.Length > 0)
{
return hostEntry.AddressList[0].ToString();
//you might get more than one ip for a hostname since
//DNS supports more than one record
}
return null;
}
private void RefreshL_Click(object sender, EventArgs e)
{
ViewResult(getInfo());
}
public void ViewResult(List<LogonUser> results)
{
LogOnListView.Items.Clear();
if (results.Count == 0) { return; }
int i = 0;
foreach (LogonUser result in results)
{
LogOnListView.Items.Add(i.ToString());
LogOnListView.Items[i].SubItems.Add(result.SamAccountName);
LogOnListView.Items[i].SubItems.Add(result.FullName);
LogOnListView.Items[i].SubItems.Add(result.Computer);
LogOnListView.Items[i].SubItems.Add(result.Domain);
LogOnListView.Items[i].SubItems.Add(result.StartTime.ToLocalTime().ToString());
LogOnListView.Items[i].SubItems.Add(cAD.LastLastLogon(getDN(result.SamAccountName)).ToLocalTime().ToString());
LogOnListView.Items[i].SubItems.Add(cAD.LastLastLogoff(getDN(result.SamAccountName)).ToLocalTime().ToString());
i++;
}
}
private string getDN(string samAccountName)
{
DirectoryEntry myADEntry = new DirectoryEntry();
DirectorySearcher myADSearcher = new DirectorySearcher(myADEntry);
myADSearcher.Filter = "(&(objectClass=user)(sAMAccountName=" + samAccountName + ")(!(objectClass=computer)))";
return myADSearcher.FindOne().GetDirectoryEntry().Properties["distinguishedName"].Value.ToString();
}
private List<LogonUser> getInfo()
{
List<LogonUser> LogonUserList = new List<LogonUser>();
ConnectionOptions options;
options = new ConnectionOptions();
//options.Username = "administrator";
//options.Password = "Parol-Admin";
options.EnablePrivileges = true;
options.Impersonation = ImpersonationLevel.Impersonate;
if (CBComputers.SelectedIndex == 0)
{
foreach (PC pc in CompList)
{
if (pc.Name == Environment.MachineName)
{
LogonUserList.AddRange(getLogonUserList(pc, options, LocalWMIRequestLogOnSession(), LocalWMIRequestLoggedOnUser()));
}
else
{
LogonUserList.AddRange(getLogonUserList(pc, options, WMIRequestLogOnSession(pc.IP, options), WMIRequestLoggedOnUser(pc.IP, options)));
}
}
}
else
{
PC pc = CompList[CBComputers.SelectedIndex - 1];
if (pc.Name == Environment.MachineName)
{
LogonUserList.AddRange(getLogonUserList(pc, options, LocalWMIRequestLogOnSession(), LocalWMIRequestLoggedOnUser()));
}
else
{
LogonUserList.AddRange(getLogonUserList(pc, options, WMIRequestLogOnSession(pc.IP, options), WMIRequestLoggedOnUser(pc.IP, options)));
}
}
return LogonUserList;
}
private LogonUser FindInDomainController(PC pc, ConnectionOptions options, LoggedOnUser lou, LogOnSessionR losr)
{
try
{
List<PC> Controllers = new List<PC>();
if (CBDomain.SelectedIndex == 0)
{
foreach (GlobalCatalog contr in Form1.DsDomain.Forest.GlobalCatalogs)
{
PC Con = new PC();
Con.Name = contr.Name;
Con.IP = contr.IPAddress;
Controllers.Add(Con);
}
}
else
{
foreach (DomainController contr in Form1.ListDomain[CBDomain.SelectedIndex - 1].DomainControllers)
{
PC Con = new PC();
Con.Name = contr.Name;
Con.IP = contr.IPAddress;
Controllers.Add(Con);
}
}
LogonUser getlg;
foreach (PC Controller in Controllers)
{
ManagementScope scope;
if (Controller.Name == Environment.MachineName)
{
scope = new ManagementScope("\\root\\cimv2");
}
else
{
scope = new ManagementScope("\\\\" + Controller.IP + "\\root\\cimv2", options);
scope.Connect(); //
}
String queryString = "SELECT * FROM Win32_UserAccount WHERE Domain=\"" + getDomain(lou.Antecedent) + "\" AND Name=\"" + getsAmAccountName(lou.Antecedent) + "\"";
ObjectQuery query;
query = new ObjectQuery(queryString);
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
var Temp = searcher.Get()
.Cast<ManagementObject>()
.Select(mo => new
{
Name = Convert.ToString(mo["Name"]),
FullName = Convert.ToString(mo["FullName"]),
AccountType = Convert.ToUInt32(mo["AccountType"]),
Caption = Convert.ToString(mo["Caption"]),
Description = Convert.ToString(mo["Description"]),
Disabled = Convert.ToBoolean(mo["Disabled"]),
Domain = Convert.ToString(mo["Domain"]),
InstallDate = Convert.ToDateTime(mo["InstallDate"]),
LocalAccount = Convert.ToBoolean(mo["LocalAccount"]),
Lockout = Convert.ToBoolean(mo["Lockout"]),
PasswordChangeable = Convert.ToBoolean(mo["PasswordChangeable"]),
PasswordExpires = Convert.ToBoolean(mo["PasswordExpires"]),
PasswordRequired = Convert.ToBoolean(mo["PasswordRequired"]),
SID = Convert.ToString(mo["SID"]),
SIDType = Convert.ToByte(mo["SIDType"]),
Status = Convert.ToString(mo["Status"])
}
).ToList();
if (Temp.Count == 0) { continue; }
// if (Temp.Count > 1) { throw new Exception("Найденно " + Temp.Count + " одинаковых пользователя"); }
getlg = new LogonUser()
{
AuthenticationPackage = losr.AuthenticationPackage,
Name = Temp[0].Name,
Domain = Temp[0].Domain,
Caption = Temp[0].Caption,
Description = Temp[0].Description,
InstallDate = Temp[0].InstallDate,
LogonId = losr.LogonId,
LogonType = losr.LogonType,
StartTime = losr.StartTime,
Status = Temp[0].Status,
Computer = pc.Name,
SamAccountName = getsAmAccountName(lou.Antecedent),
FullName = Temp[0].FullName,
AccountType = Temp[0].AccountType,
Enabled = !Temp[0].Disabled,
LocalAccount = Temp[0].LocalAccount,
Lockout = Temp[0].Lockout,
PasswordChangeable = Temp[0].PasswordChangeable,
PasswordExpires = Temp[0].PasswordExpires,
PasswordRequired = Temp[0].PasswordRequired,
SID = Temp[0].SID,
SIDType = Temp[0].SIDType
};
return getlg;
}
return null;
}
catch
{
}
return null;
}
public List<LogOnSessionR> LocalWMIRequestLogOnSession()
{
List<LogOnSessionR> ReqList = new List<LogOnSessionR>();
ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2",
"SELECT * FROM Win32_LogonSession WHERE LogonType = '2' OR LogonType = '10' OR LogonType = '11'");
var Temp = searcher.Get()
.Cast<ManagementObject>()
.Select(mo => new
{
AuthenticationPackage = Convert.ToString(mo["AuthenticationPackage"]),
Name = Convert.ToString(mo["Name"]),
Caption = Convert.ToString(mo["Caption"]),
Description = Convert.ToString(mo["Description"]),
InstallDate = (mo["InstallDate"] == null ? Convert.ToDateTime(mo["InstallDate"]) : ManagementDateTimeConverter.ToDateTime(mo["InstallDate"].ToString())),
LogonId = Convert.ToString(mo["LogonId"]),
LogonType = Convert.ToUInt32(mo["LogonType"]),
StartTime = (mo["StartTime"] == null ? Convert.ToDateTime(mo["StartTime"]) : ManagementDateTimeConverter.ToDateTime(mo["StartTime"].ToString())),
Status = Convert.ToString(mo["Status"])
}
).ToList();
foreach (var obj in Temp)
{
LogOnSessionR req = new LogOnSessionR();
req.AuthenticationPackage = obj.AuthenticationPackage;
req.Name = obj.Name;
req.Caption = obj.Caption;
req.Description = obj.Description;
req.InstallDate = obj.InstallDate;
req.LogonId = obj.LogonId;
req.LogonType = obj.LogonType;
req.StartTime = obj.StartTime;
req.Status = obj.Status;
ReqList.Add(req);
}
return ReqList;
}
public List<LoggedOnUser> LocalWMIRequestLoggedOnUser()
{
List<LoggedOnUser> ReqList = new List<LoggedOnUser>();
ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2",
"SELECT * FROM Win32_LoggedOnUser");
var Temp = searcher.Get()
.Cast<ManagementObject>()
.Select(mo => new
{
Antecedent = Convert.ToString(mo["Antecedent"]),
Dependent = Convert.ToString(mo["Dependent"])
}
).ToList();
foreach (var obj in Temp)
{
LoggedOnUser req = new LoggedOnUser();
req.Antecedent = obj.Antecedent;
req.Dependent = obj.Dependent;
ReqList.Add(req);
}
return ReqList;
}
private string getLogonId(string dependent)
{
var start = "LogonId=\"";
var end = "\"";
var regEx = new Regex(String.Format("{0}(.*){1}", Regex.Escape(start), Regex.Escape(end)));
var match = regEx.Match(dependent);
return match.Groups[1].Value;
// "\\\\.\\root\\cimv2:Win32_LogonSession.LogonId=\"997\""
}
private string getDomain(string antecedent)
{
var start = "Domain=\"";
var end = "\",";
var regEx = new Regex(String.Format("{0}(.*){1}", Regex.Escape(start), Regex.Escape(end)));
var match = regEx.Match(antecedent);
return match.Groups[1].Value;
// "\\\\.\\root\\cimv2:Win32_Account.Domain=\"LAB\" AND Name=\"Administrator\""
}
private string getsAmAccountName(string antecedent)
{
var start = "Name=\"";
var end = "\"";
var regEx = new Regex(String.Format("{0}(.*){1}", Regex.Escape(start), Regex.Escape(end)));
var match = regEx.Match(antecedent);
return match.Groups[1].Value;
//
}
private List<LogonUser> getLogonUserList(PC pc, ConnectionOptions options, List<LogOnSessionR> sessionsList, List<LoggedOnUser> loggedList)
{
List<LogonUser> getList = new List<LogonUser>();
foreach (LoggedOnUser lou in loggedList)
{
foreach(LogOnSessionR losr in sessionsList)
{
if (losr.LogonId == getLogonId(lou.Dependent))
{
LogonUser temp = FindInDomainController(pc, options, lou, losr);
if (temp != null)
{
getList.Add(temp);
}
}
}
}
return getList;
}
public List<LogOnSessionR> WMIRequestLogOnSession(string ip, ConnectionOptions options)
{
List<LogOnSessionR> ReqList = new List<LogOnSessionR>();
try
{
ManagementScope scope;
scope = new ManagementScope("\\\\" + ip + "\\root\\cimv2", options);
scope.Connect();
String queryString = "SELECT * FROM Win32_LogonSession WHERE LogonType = '2' OR LogonType = '10' OR LogonType = '11'";
ObjectQuery query;
query = new ObjectQuery(queryString);
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
var Temp = searcher.Get()
.Cast<ManagementObject>()
.Select(mo => new
{
AuthenticationPackage = Convert.ToString(mo["AuthenticationPackage"]),
Name = Convert.ToString(mo["Name"]),
Caption = Convert.ToString(mo["Caption"]),
Description = Convert.ToString(mo["Description"]),
InstallDate = (mo["InstallDate"] == null ? Convert.ToDateTime(mo["InstallDate"]) : ManagementDateTimeConverter.ToDateTime(mo["InstallDate"].ToString())),
LogonId = Convert.ToString(mo["LogonId"]),
LogonType = Convert.ToUInt32(mo["LogonType"]),
StartTime = (mo["StartTime"] == null ? Convert.ToDateTime(mo["StartTime"]) : ManagementDateTimeConverter.ToDateTime(mo["StartTime"].ToString())),
Status = Convert.ToString(mo["Status"])
}
).ToList();
foreach (var obj in Temp)
{
LogOnSessionR req = new LogOnSessionR();
req.AuthenticationPackage = obj.AuthenticationPackage;
req.Name = obj.Name;
req.Caption = obj.Caption;
req.Description = obj.Description;
req.InstallDate = obj.InstallDate;
req.LogonId = obj.LogonId;
req.LogonType = obj.LogonType;
req.StartTime = obj.StartTime;
req.Status = obj.Status;
ReqList.Add(req);
}
return ReqList;
}
catch
{
}
return new List<LogOnSessionR>();
}
public List<LoggedOnUser> WMIRequestLoggedOnUser(string ip, ConnectionOptions options)
{
List<LoggedOnUser> ReqList = new List<LoggedOnUser>();
try
{
ManagementScope scope;
scope = new ManagementScope("\\\\" + ip + "\\root\\cimv2", options);
scope.Connect();
String queryString = "SELECT * FROM Win32_LoggedOnUser";
ObjectQuery query;
query = new ObjectQuery(queryString);
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
var Temp = searcher.Get()
.Cast<ManagementObject>()
.Select(mo => new
{
Antecedent = Convert.ToString(mo["Antecedent"]),
Dependent = Convert.ToString(mo["Dependent"])
}
).ToList();
foreach (var obj in Temp)
{
LoggedOnUser req = new LoggedOnUser();
req.Antecedent = obj.Antecedent;
req.Dependent = obj.Dependent;
ReqList.Add(req);
}
return ReqList;
}
catch
{
}
return new List<LoggedOnUser>();
}
private void label2_Click(object sender, EventArgs e)
{
}
}
public class PC
{
public string Name { get; set; }
public string IP { get; set; }
}
public class LoggedOnUser
{
public string Antecedent { get; set; }
public string Dependent { get; set; }
}
public class LogOnSessionR
{
public string AuthenticationPackage { get; set; }
public string Name { get; set; }
public string Caption { get; set; }
public string Description { get; set; }
public System.DateTime InstallDate { get; set; }
public string LogonId { get; set; }
public UInt32 LogonType { get; set; }
public System.DateTime StartTime { get; set; }
public string Status { get; set; }
}
public class LogonUser
{
public string AuthenticationPackage { get; set; }
public string Name { get; set; }
public string Domain { get; set; }
public string Caption { get; set; }
public string Description { get; set; }
public System.DateTime InstallDate { get; set; }
public string LogonId { get; set; }
public UInt32 LogonType { get; set; }
public System.DateTime StartTime { get; set; }
public string Status { get; set; }
public string Computer { get; set; }
public string SamAccountName { get; set; }
public string FullName { get; set; }
public uint AccountType { get; set; }
public bool? Enabled { get; set; }
public bool LocalAccount { get; set; }
public bool Lockout { get; set; }
public bool PasswordChangeable { get; set; }
public bool PasswordExpires { get; set; }
public bool PasswordRequired { get; set; }
public string SID { get; set; }
public byte SIDType { get; set; }
}
}