using Newtonsoft.Json; using Renci.SshNet; using System; using System.Collections.Generic; using System.Diagnostics; using System.DirectoryServices; using System.IO; 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 { private static readonly string regularDateTime = @"(\d+[.]\d+[.]\d+[ ]\d+[:]\d+[:]\d+)"; private static readonly string[,] stringsToFind = new string[,] { { "Учетная запись активна", @"(Yes|No)", "Учетная запись работает: " }, { "Последний пароль задан", regularDateTime, "Когда был сменен пароль: " }, { "Действие пароля завершается", regularDateTime, "Когда нужно менять пароль (крайний срок): "}, { "Членство в глобальных группах", @"([*].+)", "Член групп:\t" } }; private static readonly string[,] computerNameRegex = new string[,] { { "^[a-zA-Z]+\\d+$", "R54-630300" }, // THE01 { "^\\d{6,}[a-zA-Z]+\\d+$", "R54-" }, // 630300THE01 { "^[rR]\\d{2,}[-]\\d{6,}[a-zA-Z]+\\d+$", "" } // R54-630300THE01 }; private static string domain_user = string.Empty; private static string domain_password = string.Empty; private static bool _click_cancel = false; private static bool IsStringContainIp(string ip) { return Regex.Match(ip, @"^(\d+[.]\d+[.]\d+[.]\d+)$").Success; } private static string CheckComputerName(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 data = Console.ReadLine(); if (string.IsNullOrWhiteSpace(data)) return InputData(message, callback, withClear, withChecks); data = data.Trim(); Console.WriteLine(); if (withChecks) if (!IsStringContainIp(data)) { data = CheckComputerName(data); if (data == string.Empty) { Console.WriteLine("Имя компьютера или IP-адрес не распознаны! Попробуйте еще раз."); BackToMenu(callback); } } return data; } 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 void InputDomainCredentials() { if (domain_user == string.Empty) { string machineNameAndUser = WindowsIdentity.GetCurrent().Name.ToString(); int indexOfUserName = machineNameAndUser.IndexOf('\\') + 1; domain_user = machineNameAndUser.Substring(indexOfUserName, machineNameAndUser.Length - indexOfUserName).ToLower(); } if (domain_password != string.Empty) return; 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"); domain_password = password; } private static void ExecuteCommandViaSSH(string remote, string commandToExecute) { InputDomainCredentials(); try { using (SshClient client = new SshClient(remote, domain_user, domain_password)) { client.Connect(); SshCommand command = client.RunCommand(commandToExecute); Console.WriteLine(command.Result); client.Disconnect(); } } catch (Exception ex) { Console.WriteLine("Произошла ошибка: " + ex.Message); } } private 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 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} время<1мс TTL={2}", pingReply.Address, pingReply.Buffer.Length, pingReply.Options.Ttl); else returnMessage = string.Format("Ответ от {0}: число байт={1} время={2}мс 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; } private static void PingClickCancel(object sender, ConsoleCancelEventArgs e) { e.Cancel = true; _click_cancel = true; } private static void StartPing() { string remote = InputData("\nВведите IP адрес или имя компьютера (пр. 10.234.16.129, 'IT04', '630300IT04', 'R54-630300IT04'):", StartPing); Console.WriteLine("Нажмите Ctrl + C чтобы остановить\n"); string correctName = CheckComputerName(remote); if (correctName != string.Empty) { try { IPAddress ip = Dns.GetHostEntry(correctName).AddressList.First(addr => addr.AddressFamily == AddressFamily.InterNetwork); remote = ip.ToString(); Console.WriteLine("Обмен пакетами с {0}.main.russianpost.ru [{1}] с 32 байтами данных:", correctName, remote); } catch (Exception) { Console.WriteLine("Компьютер не найден."); BackToMenu(StartPing); return; } } else Console.WriteLine("Обмен пакетами с {0} по с 32 байтами данных:", remote); Console.CancelKeyPress += PingClickCancel; for (int i = 0; i < 4; i++) { if (_click_cancel) break; Console.WriteLine(PingHost(remote)); Thread.Sleep(1000); } Console.CancelKeyPress -= PingClickCancel; _click_cancel = false; BackToMenu(StartPing); } 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(); Console.WriteLine("Подключение открыто."); BackToMenu(StartRDPConnection); } 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); } 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); } private static void OpenComputerCups() { string remote = InputData("\nВведите IP адрес или имя компьютера (пр. 10.234.16.129, 'IT04', '630300IT04', 'R54-630300IT04'):", OpenComputerCups); Process.Start($"https://{remote}:631/printers"); Console.WriteLine($"CUPS {remote} открыт."); BackToMenu(OpenComputerCups); } 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); ExecuteCommandViaSSH(remote, commandToExecute); Console.WriteLine("Команда выполнена."); BackToMenu(ExecuteCustomCommandViaSSH); } private static void FixConky() { string remote = InputData("\nВведите IP адрес или имя компьютера (пр. 10.234.16.129, 'IT04', '630300IT04', 'R54-630300IT04'):", FixConky); ExecuteCommandViaSSH(remote, "sudo sed -i 's/update_interval = 0.5,/update_interval = 300,/' /etc/conky/conky.conf"); Console.WriteLine("Команда исправления Conky отправлена."); BackToMenu(FixConky); } private static void RemoteRebootLinux() { string remote = InputData("\nВведите IP адрес или имя компьютера (пр. 10.234.16.129, 'IT04', '630300IT04', 'R54-630300IT04'):", RemoteRebootLinux); ExecuteCommandViaSSH(remote, "sudo shutdown -r +3 \"Через 3 минуты будет произведена перезагрузка ПК!\""); Console.WriteLine("Команда перезагрузки отправлена."); BackToMenu(RemoteRebootLinux); } private static void ShowLinuxComputerBootupTime() { string remote = InputData("\nВведите IP адрес или имя компьютера (пр. 10.234.16.129, 'IT04', '630300IT04', 'R54-630300IT04'):", ShowLinuxComputerBootupTime); ExecuteCommandViaSSH(remote, "uptime"); BackToMenu(ShowLinuxComputerBootupTime); } private static void ChangeRemote802Password() { string remote = InputData("\nВведите IP адрес или имя компьютера (пр. 10.234.16.129, 'IT04', '630300IT04', 'R54-630300IT04')\nall - для массового изменения", ChangeRemote802Password, withChecks: false); remote = remote.Trim().ToLower(); if (remote != "all") { if (!IsStringContainIp(remote)) { remote = CheckComputerName(remote); if (remote == string.Empty) ChangeRemote802Password(); } } string new802password = InputData("\nВведите новый пароль от УЗ:", ChangeRemote802Password, withClear: false, withChecks: false); if (remote == "all") { //InputDomainCredentials(); // load json file with pc names //string[] pc_names = { "it01", "it02" }; //string pc_name; //foreach (var item in pc_names) //{ // pc_name = CheckComputerName(item); // if (pc_name == string.Empty) // continue; // try // { // using (SshClient client = new SshClient(pc_name, domain_user, domain_password)) // { // client.Connect(); // SshCommand command = client.RunCommand($"sudo sed -i 's/password=.\\+/password={new802password}/' /etc/NetworkManager/system-connections/Проводное\\ подключение\\ 1.nmconnection"); // Console.WriteLine(command.Result); // command = client.RunCommand("sudo nmcli connection reload"); // Console.WriteLine(command.Result); // command.Dispose(); // client.Disconnect(); // } // Console.WriteLine(pc_name + ": "); // } // catch (Exception ex) // { // Console.WriteLine(pc_name + ": " + ex.Message); // } //} Console.WriteLine("Пока не реализовано :("); } else { ExecuteCommandViaSSH(remote, $"sudo sed -i 's/^password=.\\+/password={new802password}/' /etc/NetworkManager/system-connections/Проводное\\ подключение\\ 1.nmconnection && sudo nmcli connection reload"); Console.WriteLine("Команда отправлена."); } BackToMenu(ChangeRemote802Password); } private static void DisableKdeWallet() { string remote = InputData("\nВведите IP адрес или имя компьютера (пр. 10.234.16.129, 'IT04', '630300IT04', 'R54-630300IT04'):", DisableKdeWallet); ExecuteCommandViaSSH(remote, "sudo sed -i 's/^Exec=/#Exec=/' /usr/share/dbus-1/services/org.kde.kwalletd5.service"); Console.WriteLine("Команда отключения кошелька отправлена."); BackToMenu(DisableKdeWallet); } static readonly string[] menuList = { //"630300 - сброс пароля локального администратора (только Windows)", // ResetAdminPassword "Выберите действие:", "1 - ping компьютера", // StartPing "2 - удаленно подключиться к компьютеру", // StartRDPConnection "\nWindows:", "3 - посмотреть информацию о пользователе", // ShowDomainUserInfo "4 - посмотреть дату последней загрузки компьютера", // ShowComputerBootupTime "5 - удаленная перезагрузка компьютера", // RemoteRebootWindows "\nLinux:", "6 - открыть CUPS выбранного компьютера", // OpenComputerCups "7 - выполнить команду через SSH", // ExecuteCustomCommandViaSSH "8 - изменить время обновления conky с 0.5 на 300", // FixConky "9 - удаленная перезагрузка компьютера", // RemoteRebootLinux "10 - посмотреть время работы компьютера", // ShowLinuxComputerBootupTime "11 - сменить пароль для 802.1x", // ChangeRemote802Password "12 - отключить KDE кошелек", // DisableKdeWallet }; private static void Menu() { Console.Clear(); foreach (string item in menuList) // for (int i = 0; i < menuList.Length; i++) Console.WriteLine(item); // Console.WriteLine(menuList[i]); int choice; Console.Write("\n> "); 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: ExecuteCustomCommandViaSSH(); break; case 8: FixConky(); break; case 9: RemoteRebootLinux(); break; case 10: ShowLinuxComputerBootupTime(); break; case 11: ChangeRemote802Password(); break; case 12: DisableKdeWallet(); break; case 630300: ResetAdminPassword(); break; default: { Menu(); break; } } } private class JsonFile { public int sleep_time = 0; public int restart_time = 0; public string message = ""; public Dictionary> everyday_reboot = null; } private static void StartRestartComputers() { string path = Path.Combine(Environment.CurrentDirectory, "settings.json"); if (!File.Exists(path)) { Console.WriteLine("Файл с настройками не найден!"); Console.ReadKey(); return; } JsonFile data = JsonConvert.DeserializeObject(File.ReadAllText(path)); string remote, unitKey; int sleep_time = data.sleep_time; foreach (var unit in data.everyday_reboot) { unitKey = unit.Key; foreach (int position in unit.Value) { remote = CheckComputerName($"{unitKey}{(position < 10 ? $"0{position}" : position.ToString())}"); if (remote == string.Empty) { Console.WriteLine($"{unitKey}{(position < 10 ? $"0{position}" : position.ToString())}: имя ПК не распознано."); continue; } //Console.WriteLine($"{remote}: shutdown -r +{data.restart_time} \"{data.message}\""); ExecuteCommandViaSSH(remote, $"sudo shutdown -r +{data.restart_time} \"{data.message}\""); Thread.Sleep(sleep_time); } } Console.ReadKey(); } static void Main(string[] args) { Console.Title = Assembly.GetExecutingAssembly().GetCustomAttribute().Title; if (args.Length > 0 && args[0] == "reboot") { StartRestartComputers(); return; } Menu(); } } }