【发布时间】:2020-12-09 15:09:29
【问题描述】:
有一个域网络与连接的计算机。
需要一个代码来显示现在连接到它的 Active Directory 用户列表(使用它们/远程连接)。
类似于任务管理器中的“用户”选项卡,仅适用于域网络。
我尝试使用 WMI 来做到这一点。
类Win32_LogonSession、Win32_LoggedOnUser、Win32_Account
原理是这样的:
从活跃的Win32_LogonSession 淘汰LogonType = 2、10 和 11。
by LogonId from Win32_LoggedOnUser 获取名称和域名,在Win32_Account中搜索(清除系统会话)(下面会有代码,也许有人会派上用场)
但是我遇到了一个问题:事件Session_onEnd被触发的情况远非100%,而LogOff似乎根本没有记录,或者记录不正确。
因此,我得到了很多用户连接到的“挂起”会话,或者在他们登录时创建新会话。在这方面分析 Windows 事件日志也没有提供任何有用的信息。 (LogOff 还是不正确)
那么,如果我可以连接到一台计算机并从中获取所有信息,如何提取 - 它现在是否在使用以及谁在使用它?
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; }
}
}
【问题讨论】:
标签: c# active-directory