using Renci.SshNet; using System; using System.Collections.Generic; using System.Diagnostics; using System.DirectoryServices; using System.Linq; using System.Management; using System.Net; using System.Net.NetworkInformation; using System.Net.Sockets; using System.Reflection; using System.Security.Principal; using System.Text.RegularExpressions; using System.Threading; namespace domain_utility { internal class Program { static readonly string regularDateTime = @"(\d+[.]\d+[.]\d+[ ]\d+[:]\d+[:]\d+)"; static readonly string[,] stringsToFind = new string[,] { { "Учетная запись активна", @"(Yes|No)", "Учетная запись работает: " }, { "Последний пароль задан", regularDateTime, "Когда был сменен пароль: " }, { "Действие пароля завершается", regularDateTime, "Когда нужно менять пароль (крайний срок): "}, { "Членство в глобальных группах", @"([*].+)", "Член групп:\t" } }; static readonly string[,] computerNameRegex = new string[,] { { "^[a-zA-Z]+\\d+$", "R54-630300" }, // THE01 { "^\\d+[a-zA-Z]+\\d+$", "R54-" }, // 630300THE01 { "^[rR]\\d*[-]\\d+[a-zA-Z]+\\d+$", "" } // R54-630300THE01 }; //private static volatile bool _ping_stop = false; private static bool _ping_stop = false; private static bool IsStringContainIp(string ip) { return Regex.Match(ip, @"^(\d+[.]\d+[.]\d+[.]\d+)$").Success; } private static string СheckComputerName(string pcName) { for (int i = 0; i < computerNameRegex.GetLength(0); i++) if (Regex.Match(pcName, computerNameRegex[i, 0]).Success) return $"{computerNameRegex[i, 1]}{pcName}".ToUpper(); return string.Empty; } private static string InputData(string message, Action callback, bool withClear = true, bool withChecks = true) { if (withClear) Console.Clear(); Console.WriteLine(message); Console.Write("> "); string remote = Console.ReadLine().Trim(); if (string.IsNullOrWhiteSpace(remote)) InputData(message, callback, withClear, withChecks); Console.WriteLine(); if (withChecks) if (!IsStringContainIp(remote)) { remote = СheckComputerName(remote); if (remote == string.Empty) { Console.WriteLine("Имя компьютера или IP-адрес не распознаны! Попробуйте еще раз."); BackToMenu(callback); } } return remote; } private static void BackToMenu(Action callback, bool withMessage = true) { if (withMessage) Console.WriteLine("\nНажмите Enter чтобы продолжить, ESC чтобы вернуться на главную."); ConsoleKey key = Console.ReadKey(true).Key; if (key == ConsoleKey.Enter) callback.Invoke(); else if (key == ConsoleKey.Escape) Menu(); else { Console.WriteLine("Нажмите Enter или ESC!"); BackToMenu(callback, false); } } private static string PingHost(string host) { string returnMessage = string.Empty; PingOptions pingOptions = new PingOptions() { DontFragment = true }; // TTL = 128 using (Ping ping = new Ping()) { byte[] buffer = new byte[32]; for (int i = 0; i < 4; i++) { try { PingReply pingReply = ping.Send(host, 1000, buffer, pingOptions); if (pingReply == null) { returnMessage = "Ошибка подключения по неизвестной причине."; throw new Exception(message: string.Empty); } switch (pingReply.Status) { case IPStatus.Success: { if (pingReply.RoundtripTime < 1) returnMessage = string.Format("Ответ от {0}: число байт={1} время<1ms TTL={2}", pingReply.Address, pingReply.Buffer.Length, pingReply.Options.Ttl); else returnMessage = string.Format("Ответ от {0}: число байт={1} время={2}ms TTL={3}", pingReply.Address, pingReply.Buffer.Length, pingReply.RoundtripTime, pingReply.Options.Ttl); break; } case IPStatus.TimedOut: returnMessage = "Время подключения истекло."; break; case IPStatus.DestinationHostUnreachable: returnMessage = "Заданный узел недоступен."; break; default: returnMessage = string.Format("Ошибка пинга: {0}", pingReply.Status.ToString()); break; } } catch (Exception ex) { if (ex.Message != string.Empty) returnMessage = string.Format("Ошибка подключения: {0}", ex.Message); } } } return returnMessage; } public static void ResetAdminPassword() { string machineNameAndUser = WindowsIdentity.GetCurrent().Name.ToString(); string machineName = machineNameAndUser.Substring(0, machineNameAndUser.IndexOf('\\')); using (DirectoryEntry directoryEntry = new DirectoryEntry(string.Format("WinNT://{0}/{1}", machineName, "Администратор"))) { //directoryEntry.Properties["LockOutTime"].Value = 0; directoryEntry.Invoke("SetPassword", "Qwe12345"); directoryEntry.CommitChanges(); //directoryEntry.Close(); } Console.WriteLine("Пароль сброшен."); BackToMenu(Menu); } private static void ShowDomainUserInfo() { string username = InputData("\nВведите имя пользователя (пр. 'lev.rusanov'): ", ShowDomainUserInfo, withChecks: false); username = $"user {username} /domain"; ProcessStartInfo procStartInfo = new ProcessStartInfo("net", username) { CreateNoWindow = true, UseShellExecute = false, RedirectStandardOutput = true, }; List strArr = new List { }; Process proc = new Process(); proc.StartInfo = procStartInfo; proc.Start(); while (!proc.StandardOutput.EndOfStream) strArr.Add(proc.StandardOutput.ReadLine()); Match regex; bool groupsFlag = false; for (int i = 0; i < strArr.Count; i++) { for (int j = 0; j < stringsToFind.GetLength(0); j++) { if (strArr[i].Contains(stringsToFind[j, 0])) { regex = Regex.Match(strArr[i], stringsToFind[j, 1]); if (regex.Success) { Console.WriteLine(stringsToFind[j, 2] + regex.Value); if (j == 3) { groupsFlag = true; continue; } } } if (j == 3 && groupsFlag) { regex = Regex.Match(strArr[i], stringsToFind[j, 1]); if (regex.Success) Console.WriteLine("\t\t" + regex.Value); } } } strArr.Clear(); BackToMenu(ShowDomainUserInfo); } private static void ShowComputerBootupTime() { string remote = InputData("\nВведите IP адрес или имя компьютера (пр. 10.234.16.129, 'IT04', '630300IT04', 'R54-630300IT04'):", ShowComputerBootupTime); ManagementScope scope = new ManagementScope(string.Format(@"\\{0}\root\cimv2", remote)); try { scope.Connect(); ObjectQuery query = new ObjectQuery("SELECT LastBootUpTime FROM Win32_OperatingSystem"); ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query); var firstResult = searcher.Get().OfType().First()["LastBootUpTime"]; DateTime lastBootUp = ManagementDateTimeConverter.ToDateTime(firstResult.ToString()); Console.WriteLine("Дата последней загрузки: " + lastBootUp); Console.WriteLine("Время работы (д:ч:м:с): " + (DateTime.Now.ToUniversalTime() - lastBootUp.ToUniversalTime()).ToString(@"d\:hh\:mm\:ss")); } catch (Exception) { Console.WriteLine("Произошла ошибка. Попробуйте еще раз."); BackToMenu(ShowComputerBootupTime); } BackToMenu(ShowComputerBootupTime); } private static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e) { e.Cancel = true; _ping_stop = true; } private static void StartPing() { string remote = InputData("\nВведите IP адрес или имя компьютера (пр. 10.234.16.129, 'IT04', '630300IT04', 'R54-630300IT04'):", StartPing); string correctName = СheckComputerName(remote); if (correctName != string.Empty) { try { IPAddress ip = Dns.GetHostEntry(correctName).AddressList.First(addr => addr.AddressFamily == AddressFamily.InterNetwork); remote = ip.ToString(); Console.WriteLine("Обмен пакетами с {0} [{1}] с 32 байтами данных:", correctName, remote); } catch (Exception) { Console.WriteLine("Компьютер не найден."); BackToMenu(StartPing); return; } } else Console.WriteLine("Обмен пакетами с {0} по с 32 байтами данных:", remote); Console.CancelKeyPress += Console_CancelKeyPress; for (int i = 0; i < 4; i++) { if (_ping_stop) break; Console.WriteLine(PingHost(remote)); Thread.Sleep(1000); } Console.CancelKeyPress -= Console_CancelKeyPress; _ping_stop = false; BackToMenu(StartPing); } private static void OpenComputerCups() { string remote = InputData("\nВведите IP адрес или имя компьютера (пр. 10.234.16.129, 'IT04', '630300IT04', 'R54-630300IT04'):", OpenComputerCups); Process.Start($"https://{remote}:631/printers"); BackToMenu(OpenComputerCups); } private static void StartRDPConnection() { string remote = InputData("\nВведите IP адрес или имя компьютера (пр. 10.234.16.129, 'IT04', '630300IT04', 'R54-630300IT04'):", StartRDPConnection); remote = $"/v:{remote} /f"; Process proc = new Process(); proc.StartInfo = new ProcessStartInfo("mstsc", remote); proc.Start(); BackToMenu(StartRDPConnection); } private static string InputPassword() { Console.WriteLine("Введите пароль от СВОЕЙ учетной записи:"); Console.Write("> "); string password = string.Empty; ConsoleKeyInfo key; do { key = Console.ReadKey(true); if (key.Key == ConsoleKey.Backspace && password.Length > 0) { password = password.Substring(0, password.Length - 1); Console.Write("\b \b"); } else if (key.KeyChar < 32 || key.KeyChar > 126) continue; else if (key.Key != ConsoleKey.Backspace) { password += key.KeyChar; Console.Write("*"); } } while (key.Key != ConsoleKey.Enter); Console.Write("\n\n"); return password; } private static void ExecuteCommandViaSSH(string remote, string password, string commandToExecute) { string machineNameAndUser = WindowsIdentity.GetCurrent().Name.ToString(); int indexOfUserName = machineNameAndUser.IndexOf('\\') + 1; string machineUser = machineNameAndUser.Substring(indexOfUserName, machineNameAndUser.Length - indexOfUserName).ToLower(); try { using (SshClient client = new SshClient(remote, machineUser, password)) { client.Connect(); SshCommand command = client.RunCommand(commandToExecute); Console.WriteLine(command.Result); client.Disconnect(); } } catch (Exception ex) { Console.WriteLine("Произошла ошибка: " + ex.Message); } } private static void FixConky() { string remote = InputData("\nВведите IP адрес или имя компьютера (пр. 10.234.16.129, 'IT04', '630300IT04', 'R54-630300IT04'):", FixConky); string password = InputPassword(); ExecuteCommandViaSSH(remote, password, "sudo sed -i 's/update_interval = 0.5,/update_interval = 300,/' /etc/conky/conky.conf"); BackToMenu(FixConky); } private static void RemoteRebootLinux() { string remote = InputData("\nВведите IP адрес или имя компьютера (пр. 10.234.16.129, 'IT04', '630300IT04', 'R54-630300IT04'):", RemoteRebootLinux); string password = InputPassword(); ExecuteCommandViaSSH(remote, password, "sudo shutdown -r +3 \"Через 3 минуты будет произведена перезагрузка ПК!\""); BackToMenu(RemoteRebootLinux); } private static void ExecuteCustomCommandViaSSH() { string remote = InputData("\nВведите IP адрес или имя компьютера (пр. 10.234.16.129, 'IT04', '630300IT04', 'R54-630300IT04'):", ExecuteCustomCommandViaSSH); string commandToExecute = InputData("Введите команду для выполнения:", ExecuteCustomCommandViaSSH, withClear: false, withChecks: false); string password = InputPassword(); ExecuteCommandViaSSH(remote, password, commandToExecute); BackToMenu(ExecuteCustomCommandViaSSH); } private static void RemoteRebootWindows() { string remote = InputData("\nВведите IP адрес или имя компьютера (пр. 10.234.16.129, 'IT04', '630300IT04', 'R54-630300IT04'):", RemoteRebootWindows); remote = $"/m \\\\{remote} /r /f /t 180 /c \"Через 3 минуты будет произведена перезагрузка ПК!\""; Process proc = new Process(); proc.StartInfo = new ProcessStartInfo("shutdown", remote); proc.Start(); Console.WriteLine("Команда перезагрузки успешно отправлена!"); BackToMenu(RemoteRebootWindows); } static readonly string[] menuList = { //"630300 - сброс пароля локального администратора (только Windows)", // ResetAdminPassword "Выберите действие:", "1 - ping компьютера", // StartPing "2 - удаленно подключиться к компьютеру", // StartRDPConnection "3 - посмотреть информацию о пользователе (только Windows)", // ShowDomainUserInfo "4 - посмотреть дату последней загрузки компьютера (только Windows)", // ShowComputerBootupTime "5 - удаленная перезагрузка компьютера (только Windows)", // RemoteRebootWindows "6 - открыть CUPS выбранного компьютера (только Linux)", // OpenComputerCups "7 - изменить время обновления conky с 0.5 на 300 (только Linux)", // FixConky "8 - удаленная перезагрузка компьютера (только Linux)", // RemoteRebootLinux "9 - выполнить команду удаленно (только Windows -> Linux)", // ExecuteCustomCommandViaSSH }; private static void Menu() { Console.Clear(); for (int i = 0; i < menuList.Length; i++) Console.WriteLine(menuList[i]); int choice; Console.Write("> "); while (!int.TryParse(Console.ReadLine(), out choice)) { Console.WriteLine("Введите цифру!"); Console.Write("> "); } switch (choice) { case 1: StartPing(); break; case 2: StartRDPConnection(); break; case 3: ShowDomainUserInfo(); break; case 4: ShowComputerBootupTime(); break; case 5: RemoteRebootWindows(); break; case 6: OpenComputerCups(); break; case 7: FixConky(); break; case 8: RemoteRebootLinux(); break; case 9: ExecuteCustomCommandViaSSH(); break; case 630300: ResetAdminPassword(); break; default: { Console.WriteLine("Неправильный выбор!"); Menu(); break; } } } static void Main() { //Console.Title = typeof(Program).Assembly.GetName().Name; Console.Title = Assembly.GetExecutingAssembly().GetCustomAttribute().Title; Menu(); } } }