Я создаю приложение C# для мониторинга рабочих нагрузок сервера и рабочей станции с помощью запросов WMI и WQL. Я использую WMI, потому что он кажется быстрее по сравнению с запросами powershell. Мои трудности начинаются, когда я пытаюсь восстановить зарегистрированных пользователей на удаленной машине. Я решил, что мне нужно использовать класс Win32_LoggedOnUser. Я пробовал следующие запросы:
@"SELECT * FROM Win32_LoggedOnUser"
@"SELECT Antecedent FROM Win32_LoggedOnUser"
Я привык получать желаемое значение следующим образом:
var cims = connection.getCimInstances(this, queryUser);
if (cims != null)
{
foreach (CimInstance cim in cims)
{
Komponenten.User user = new Komponenten.User();
user.Name = Convert.ToString(cim.CimInstanceProperties["Name"].Value);
users.Add(user);
}
}
где queryUser — одна из приведенных выше строк.
В обоих случаях я получаю взамен объект Win32_Account, который, кажется, предполагает — и отладчик, кажется, подтверждает — что я должен снова использовать CimInstanceProperties["Name"].Value
в возвращенном Win32_Account
классе. Но это совсем не работает. Любые идеи о том, как получить доступ к CimInstanceProperties Win32_Account, хранящемуся в CimInstanceProperity? Я ничего не могу найти ни на соответствующей справочной странице Windows (https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-loggedonuser), ни во время обширного поиска в Google.
Спасибо!
Слишком размыто, согласен. Соединение в порядке, я также получаю CimInstance-Object обратно, но CimInstanceProperty содержит два новых CimInstance-Objects (Antecedent и Descendent), которые снова имеют CimInstanceProperty в качестве члена. Я хотел бы получить доступ к свойствам Antecendent-Object, но я не могу понять, как это сделать.
В итоге я использовал ManagementObject-Class и Regex для поиска имен пользователей после преобразования Antecedent - Object в строку:
var users = new List<Komponenten.User>();
var searcher = this.connection.makeQuery(this, "SELECT * FROM Win32_LoggedOnUser");
if (searcher != null)
{
foreach (ManagementObject queryObj in searcher.Get())
{
Komponenten.User user = new Komponenten.User();
var win32_account = queryObj["Antecedent"].ToString();
string stripped = Regex.Replace(win32_account, "[^a-zA-Z=]+", "", RegexOptions.Compiled);
int end = stripped.LastIndexOf(" = ");
user.Name = stripped.Substring(end+1);
users.Add(user);
}
this.users = users;
Альтернативой, которая учитывает LogonSession, является:
var users = new List<Komponenten.User>();
var searcher = this.connection.makeQuery(this, "SELECT LogonId FROM Win32_LogonSession Where LogonType=2");
var Scope = this.connection.getScope(this, this.connection.getConnection());
if (searcher != null)
{
foreach (ManagementObject queryObj in searcher.Get())
{
ObjectQuery LQuery = new ObjectQuery("Associators of {Win32_LogonSession.LogonId = " + queryObj["LogonId"] + "} Where AssocClass=Win32_LoggedOnUser Role=Dependent");
ManagementObjectSearcher LSearcher = new ManagementObjectSearcher(Scope, LQuery);
foreach (ManagementObject LWmiObject in LSearcher.Get())
{
Komponenten.User user = new Komponenten.User();
user.Name = Convert.ToString(LWmiObject["Name"]);
users.Add(user);
}
}
this.users = users;
}
где this.connection.getConnection — это объект ConnectionsOption в зависимости от вашего соответствующего домена и данных учетной записи.
"Но это вообще не работает" что ты имеешь в виду? когда вы создали соединение (с именем пользователя и паролем, я думаю), вы проверили, что соединение в порядке?