From 80ff66773179ff565a04dab31be2812732ebd678 Mon Sep 17 00:00:00 2001 From: Lev Rusanov <30170278+JDM170@users.noreply.github.com> Date: Tue, 28 Jan 2025 21:08:43 +0700 Subject: [PATCH] Update * Added CHANGELOG.md * Added new package Signed-off-by: Lev Rusanov <30170278+JDM170@users.noreply.github.com> --- CHANGELOG.md | 13 ++ Program.cs | 519 +++++++++++++++++++++++++++--------------- domain_utility.csproj | 6 + packages.config | 1 + settings.json | 11 + 5 files changed, 362 insertions(+), 188 deletions(-) create mode 100644 settings.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 3fd0122..d03aad6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +## 26-01-2025 +* Feat: Добавлена функция отключения кошелька KDE (нужны тесты) +* Feat: Добавлен файл settings.json с настройками для перезагрузки компьютеров по расписанию + +## 25-01-2025 +* Fix: Исправлено имя функции CheckComputerName +* Refactor: Сортировка кода +* Feat: Добавлены информационные сообщения в некоторые функции +* Feat: Добавлен просмотр времени работы компьютера на Linux +* Feat: Добавлено обновление пароля 802.1x удаленным методом (массовое изменение в разработке) +* Feat: Добавлено запоминание пароля для команд по SSH +* Feat: Добавлен пакет NuGet: Newtonsoft.Json + ## 08-10-2024 * Fix: Убраны проверки при вводе в ShowDomainUserInfo * Fix: Убрана очистка окна при ввода команды для выполнения в ExecuteCommandViaSSH diff --git a/Program.cs b/Program.cs index ae5d886..429d5e9 100644 --- a/Program.cs +++ b/Program.cs @@ -1,8 +1,10 @@ -using Renci.SshNet; +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; @@ -32,15 +34,18 @@ namespace domain_utility { "^[rR]\\d*[-]\\d+[a-zA-Z]+\\d+$", "" } // R54-630300THE01 }; - //private static volatile bool _ping_stop = false; - private static bool _ping_stop = false; + private static string domain_user = string.Empty; + private static string domain_password = string.Empty; + + //private static volatile bool _click_cancel = false; + private static bool _click_cancel = false; private static bool IsStringContainIp(string ip) { return Regex.Match(ip, @"^(\d+[.]\d+[.]\d+[.]\d+)$").Success; } - private static string СheckComputerName(string pcName) + private static string CheckComputerName(string pcName) { for (int i = 0; i < computerNameRegex.GetLength(0); i++) if (Regex.Match(pcName, computerNameRegex[i, 0]).Success) @@ -48,27 +53,42 @@ namespace domain_utility return string.Empty; } + //private static void InputCancelClick(object sender, ConsoleCancelEventArgs e) + //{ + // //e.Cancel = true; + // _click_cancel = true; + // //Menu(); + //} + private static string InputData(string message, Action callback, bool withClear = true, bool withChecks = true) { + //Console.CancelKeyPress += InputCancelClick; + //if (_click_cancel) + //{ + // Console.CancelKeyPress -= InputCancelClick; + // _click_cancel = false; + // Menu(); + //} if (withClear) Console.Clear(); Console.WriteLine(message); Console.Write("> "); - string remote = Console.ReadLine().Trim(); - if (string.IsNullOrWhiteSpace(remote)) + string data = Console.ReadLine(); + if (string.IsNullOrWhiteSpace(data)) InputData(message, callback, withClear, withChecks); + data = data.Trim(); Console.WriteLine(); if (withChecks) - if (!IsStringContainIp(remote)) + if (!IsStringContainIp(data)) { - remote = СheckComputerName(remote); - if (remote == string.Empty) + data = CheckComputerName(data); + if (data == string.Empty) { Console.WriteLine("Имя компьютера или IP-адрес не распознаны! Попробуйте еще раз."); BackToMenu(callback); } } - return remote; + return data; } private static void BackToMenu(Action callback, bool withMessage = true) @@ -87,6 +107,77 @@ namespace domain_utility } } + 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); + } + } + + 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 string PingHost(string host) { string returnMessage = string.Empty; @@ -135,21 +226,62 @@ namespace domain_utility return returnMessage; } - public static void ResetAdminPassword() + private static void PingClickCancel(object sender, ConsoleCancelEventArgs e) { - string machineNameAndUser = WindowsIdentity.GetCurrent().Name.ToString(); - string machineName = machineNameAndUser.Substring(0, machineNameAndUser.IndexOf('\\')); + e.Cancel = true; + _click_cancel = true; + } - using (DirectoryEntry directoryEntry = new DirectoryEntry(string.Format("WinNT://{0}/{1}", machineName, "Администратор"))) + private static void StartPing() + { + string remote = InputData("\nВведите IP адрес или имя компьютера (пр. 10.234.16.129, 'IT04', '630300IT04', 'R54-630300IT04'):", + StartPing); + + string correctName = CheckComputerName(remote); + if (correctName != string.Empty) { - //directoryEntry.Properties["LockOutTime"].Value = 0; - directoryEntry.Invoke("SetPassword", "Qwe12345"); - directoryEntry.CommitChanges(); - //directoryEntry.Close(); + 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.WriteLine("Пароль сброшен."); - BackToMenu(Menu); + 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() @@ -222,164 +354,11 @@ namespace domain_utility 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'):", @@ -390,32 +369,167 @@ namespace domain_utility proc.StartInfo = new ProcessStartInfo("shutdown", remote); proc.Start(); - Console.WriteLine("Команда перезагрузки успешно отправлена!"); + 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.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 - "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 + "\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(); - for (int i = 0; i < menuList.Length; i++) - Console.WriteLine(menuList[i]); + foreach (string item in menuList) // for (int i = 0; i < menuList.Length; i++) + Console.WriteLine(item); // Console.WriteLine(menuList[i]); int choice; - Console.Write("> "); + Console.Write("\n> "); while (!int.TryParse(Console.ReadLine(), out choice)) { Console.WriteLine("Введите цифру!"); @@ -429,18 +543,47 @@ namespace domain_utility 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 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: { - Console.WriteLine("Неправильный выбор!"); Menu(); break; } } } + + private static void StartRestartComputers() + { + string path = Path.Combine(Environment.CurrentDirectory, "settings.json"); + if (!File.Exists(path)) + { + Console.WriteLine("Файл с настройками не найден!"); + Console.ReadKey(); + return; + } + var data = JsonConvert.DeserializeObject(File.ReadAllText(path)); + string remote; + int sleep_time = Convert.ToInt32(data.sleep_time); + foreach (string item in data.pc_list) + { + remote = CheckComputerName(item.ToString()); + if (remote == string.Empty) + { + Console.WriteLine($"{item}: имя ПК не распознано."); + 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() { diff --git a/domain_utility.csproj b/domain_utility.csproj index bf02963..e06876c 100644 --- a/domain_utility.csproj +++ b/domain_utility.csproj @@ -39,6 +39,9 @@ packages\Microsoft.Bcl.AsyncInterfaces.1.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll + packages\SSH.NET.2024.1.0\lib\net462\Renci.SshNet.dll @@ -66,6 +69,9 @@ + + Always + diff --git a/packages.config b/packages.config index 42ea68e..86ca986 100644 --- a/packages.config +++ b/packages.config @@ -2,6 +2,7 @@ + diff --git a/settings.json b/settings.json new file mode 100644 index 0000000..3cf5091 --- /dev/null +++ b/settings.json @@ -0,0 +1,11 @@ +{ + "sleep_time" : 500, + "restart_time": 1, + "message": "Плановая перезагрузка компьютера через 1 минуту!", + "pc_list" : [ + "IT01", + "IT02", + "630870MMP01", + "R54-630870MMP02" + ] +} \ No newline at end of file