Ping C#: параллельное выполнение

Ping C#: параллельное выполнение

Всем доброго времени суток. На связи Алексей Гулынин. В данной статье я бы хотел реализовать задачу, которая возможно будет полезна многим администраторам. Пусть у нас в текстовом файле имеется список имен рабочих станций. Задача: проверить доступность рабочей станции стандартной командной "ping". Далее, если рабочая станция доступна, то проверить существование папки "admin$". Бывает, что пользователи домена каким-либо образом (в данной статье не будем говорить как такое можно сделать) убирают из группы администраторов своей машины учетные записи пользователей, которые такими правами обладают (например, администраторы домена или специалисты технической поддержки, которые удаленно подключаются к пользователю в случае возникновения у него проблем). В этом случае подключиться к машине не получится.

Для того, чтобы выявить таких недобросовестных пользователей реализуем код на C#. Пояснения к коду будут в комментариях:

// Подключаем пространства имён
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net.NetworkInformation;

namespace PingSystemAndCheckAdminShare
{
    class Program
    {
        // данная коллекция будет содержать имена рабочих станций
        private static List<string> hosts = new List<string>();

        public static void Main()
        {
            // В переменную hosts записываем все рабочие станции из файла
            hosts = getComputersListFromTxtFile("D:\\computersList.txt");
            // Создаём Action типизированный string, данный Action будет запускать функцию Pinger
            Action<string> asyn = new Action<string>(Pinger);
            // Для каждой рабочей станции запускаем Pinger'а
            hosts.ForEach(e =>
            {
                asyn.Invoke(e);
            });
            Console.ReadKey();

        }
        
        // Функция получения списка рабочих станций из файла
        private static List<string> getComputersListFromTxtFile(string pathToFile)
        {
            List<string> computersList = new List<string>();
            using (StreamReader sr = new StreamReader(pathToFile, Encoding.Default))
            {
                string line = "";
                while ((line = sr.ReadLine()) != null)
                {
                    computersList.Add(line);
                }
            }
            return computersList;
        }
        
        // Функция записи проблемных рабочих станций в файл
        private static void writeProblemComputersToFile(string fullPathToFile, List<string> problemComputersList)
        {
            using (StreamWriter sw = new StreamWriter(fullPathToFile, true, Encoding.Default))
            {
                problemComputersList.ForEach(e => {sw.WriteLine(e);});    
            }
        }
        
        // Проверяем доступна ли папка admin$
        private static bool checkAdminShare(string computerName)
        {
            if (Directory.Exists("\\\\" + computerName + "\\admin$"))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        
        // Наш основной класс, который будет отправлять команду ping
        async private static void Pinger(string hostAdress)
        {
            // Создаём экземпляр класса Ping
            Ping png = new Ping();
            try
            {
                // Пингуем рабочую станцию hostAdress
                PingReply pr = await png.SendPingAsync(hostAdress);
                List<string> problemComputersList = new List<string>();
                Console.WriteLine(string.Format("Status for {0} = {1}, ip-адрес: {2}", hostAdress, pr.Status, pr.Address));
                // Если рабочая станция пингуется и папка admin$ недоступна,
                // то такую машину заносим в список
                if (pr.Status == IPStatus.Success && !checkAdminShare(hostAdress)) 
                {
                    problemComputersList.Add(hostAdress);
                }
                // Записываем в файл все проблемные машины
                writeProblemComputersToFile("D:\\problemsWithAdminShare.txt", problemComputersList);
            }
            catch
            {
                Console.WriteLine("Возникла ошибка! " + hostAdress);
            }
        }
    }
}

Особенностью метода Pinger является то, что он будет выполняться асинхронно. На это указывает ключевое слово "async". У класса "Ping" есть асинхронный метод "SendPingAsync", который и будет распараллелен (стоит ключевое слово "await").

Также отмечу, что в данном случае исключение срабатывает, когда в DNS отсутствует запись, соответствующая имени рабочей станции, т.е. по имени не удаётся определить ip-адрес, т.к. этой записи нет.

В данной статье вы узнали как параллельно выполнить команду ping в C#.

На связи был Алексей Гулынин, оставляйте свои комментарии, увидимся в следующих статьях.


Комментарии:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *