Запуск WMI-запроса на несколько компьютеров одновременно (C#)
Привет,
Я скопировал несколько сниплетов кода и построил небольшое программное обеспечение, чтобы:
1. запросите все существующие компьютеры в домене
2. запросите каждый компьютер в списке, если определенный пользователь вошел в систему на этом компьютере
3. Заполните Listbox1 всеми компьютерами, на которых этот пользователь вошел в систему
Но, как вы знаете, запрос удаленного WMI действительно невелик... А с сотнями компьютерных объектов в объявлении это может занять до нескольких часов до окончания.
Поэтому мне нужно знать лучший способ, как запустить запрос wmi на 10 или 20 компьютеров одновременно.
textBox1.Text = имя пользователя, которое следует искать
Listbox1 = компьютеры, найденные там, где пользователь вошел в систему
Listbox2 = все компьютеры в ActiveDirectory
Button2 = чтение всех компьютеров из active directory и запись в listbox2
Button1 = начать поиск компьютеров, перечисленных в списке listbox2
Что я уже пробовал:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Management; using System.Text.RegularExpressions; using System.DirectoryServices; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } public static string serverName; public static string searchUser; public static int computerlist = 0; public static int mycounter = 0; private void button1_Click(object sender, EventArgs e) { searchUser = textBox1.Text; do { serverName = listBox2.Items[mycounter].ToString(); foreach (var user in GetLoggedUser(serverName)) { listBox1.Items.Add(serverName + " - " + user); } label2.Text = "Quering: " + serverName; mycounter++; } while (mycounter < computerlist); } private List<string> GetLoggedUser(string serverName) { int mycounter = 0; string founduser; List<string> users = new List<string>(); try { var scope = GetManagementScope(serverName); scope.Connect(); var Query = new SelectQuery("SELECT LogonId FROM Win32_LogonSession Where LogonType=2"); var Searcher = new ManagementObjectSearcher(scope, Query); var regName = new Regex(@"(?<=Name="").*(?="")"); foreach (ManagementObject WmiObject in Searcher.Get()) { if (mycounter == 0) { foreach (ManagementObject LWmiObject in WmiObject.GetRelationships("Win32_LoggedOnUser")) { founduser = regName.Match(LWmiObject["Antecedent"].ToString()).Value; if (founduser.ToLower() == searchUser.ToLower()) { users.Add(founduser); mycounter = 1; break; } else { // Nothing } } } else { break; } } } catch (Exception ex) { users.Add(ex.Message); } return users; } private static ManagementScope GetManagementScope(string serverName) { ManagementScope Scope; if (serverName.Equals("localhost", StringComparison.OrdinalIgnoreCase)) Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", "."), GetConnectionOptions()); else { Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", serverName), GetConnectionOptions()); } return Scope; } private static ConnectionOptions GetConnectionOptions() { var connection = new ConnectionOptions { EnablePrivileges = true, Authentication = AuthenticationLevel.PacketPrivacy, Impersonation = ImpersonationLevel.Impersonate, }; return connection; } private void button2_Click(object sender, EventArgs e) { List<string> computerNames = new List<string>(); using (DirectoryEntry entry = new DirectoryEntry("LDAP://My LDAP Domain")) { using (DirectorySearcher mySearcher = new DirectorySearcher(entry)) { mySearcher.Filter = ("(objectClass=computer)"); mySearcher.SizeLimit = 0; mySearcher.PageSize = 250; mySearcher.PropertiesToLoad.Add("name"); foreach (SearchResult resEnt in mySearcher.FindAll()) { if (resEnt.Properties["name"].Count > 0) { string computerName = (string)resEnt.Properties["name"][0]; listBox2.Items.Add(computerName); } } } } label3.Text = "Found " + listBox2.Items.Count.ToString() + " Computer Objects"; button1.Enabled = true; computerlist = listBox2.Items.Count; } } }