Files
domain_utility/Program.cs
2025-02-17 22:34:46 +07:00

597 lines
26 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
{
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{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 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 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 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 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);
}
}
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;
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<string> strArr = new List<string> { };
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<ManagementObject>().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.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 static void StartRestartComputers()
{
string path = Path.Combine(Environment.CurrentDirectory, "settings.json");
if (!File.Exists(path))
{
Console.WriteLine("Файл с настройками не найден!");
Console.ReadKey();
return;
}
var data = JsonConvert.DeserializeObject<dynamic>(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()
{
//Console.Title = typeof(Program).Assembly.GetName().Name;
Console.Title = Assembly.GetExecutingAssembly().GetCustomAttribute<AssemblyTitleAttribute>().Title;
Menu();
}
}
}