using System; using System.Diagnostics; using System.Linq; using System.Management; namespace NetworkResurrector.Application.Services { public class ShutdownService : IShutdownService { /// /// https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-xp/bb491003(v=technet.10)?redirectedfrom=MSDN /// /// /// public string ShutdownMachine(string ipAddressOrMachineName) { Process commandProcess = new Process(); commandProcess.StartInfo.FileName = "cmd.exe"; commandProcess.StartInfo.UseShellExecute = false; commandProcess.StartInfo.CreateNoWindow = true; commandProcess.StartInfo.RedirectStandardError = true; commandProcess.StartInfo.RedirectStandardInput = true; commandProcess.StartInfo.RedirectStandardOutput = true; commandProcess.Start(); commandProcess.StandardInput.WriteLine($"shutdown /r /m {ipAddressOrMachineName} /t 200 /f"); commandProcess.StandardInput.WriteLine("exit"); for (; !commandProcess.HasExited;) //wait executed { System.Threading.Thread.Sleep(1); } string errorOutput = commandProcess.StandardError.ReadToEnd(); string output = commandProcess.StandardOutput.ReadToEnd(); if (commandProcess != null) commandProcess.Dispose(); return $"Output:{Environment.NewLine}{output}{Environment.NewLine}{Environment.NewLine}Errors:{Environment.NewLine}{errorOutput}"; } public string ShutdownMachineWithManagementScope(string ipAddressOrMachineName) => ShutdownMachineWithManagementScope(ipAddressOrMachineName, false, null, null, null); /// /// https://msdn.microsoft.com/en-us/library/system.management.managementscope(v=vs.110).aspx /// /// /// /// /// public string ShutdownMachineWithManagementScope(string ipAddressOrMachineName, string user, string password, string domain) => ShutdownMachineWithManagementScope(ipAddressOrMachineName, true, user, password, domain); private string ShutdownMachineWithManagementScope(string ipAddressOrMachineName, bool useSpecificCredentials, string user, string password, string domain) { Validate(ipAddressOrMachineName, useSpecificCredentials, user, password, domain); /* Build an options object for the remote connection * if you plan to connect to the remote computer with a different user name and password than the one you are currently using ConnectionOptions options = new ConnectionOptions(); * and then set the options.Username and options.Password properties to the correct values * and also set options.Authority = "ntlmdomain:DOMAIN"; * and replace DOMAIN with the remote computer's domain. You can also use Kerberos instead of ntlmdomain. */ ConnectionOptions options = new ConnectionOptions { Username = user, Password = password, Authority = $"ntlmdomain:{domain}" }; // Make a connection to a remote computer. ManagementScope scope = new ManagementScope($"\\\\{ipAddressOrMachineName}\\root\\cimv2", options); scope.Connect(); //Query system for Operating System information ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_OperatingSystem"); ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query); ManagementObjectCollection queryCollection = searcher.Get(); foreach (ManagementObject obj in queryCollection) { // Display the remote computer information Console.WriteLine("Computer Name : {0}", obj["csname"]); Console.WriteLine("Windows Directory : {0}", obj["WindowsDirectory"]); Console.WriteLine("Operating System: {0}", obj["Caption"]); Console.WriteLine("Version: {0}", obj["Version"]); Console.WriteLine("Manufacturer : {0}", obj["Manufacturer"]); obj.InvokeMethod("ShutDown", null); //shutdown } return "x"; } private void Validate(string ipAddressOrMachineName, bool useSpecificCredentials, string user, string password, string domain) { if (string.IsNullOrEmpty(ipAddressOrMachineName)) throw new ArgumentException("The provided ipAddressOrMachineName input is null or empty.", nameof(ipAddressOrMachineName)); if (useSpecificCredentials && OneOfStringsIsNullOrEmpty(user, password, domain)) throw new ArgumentException($"One of user, password or domain inputs is null or empty."); } private bool OneOfStringsIsNullOrEmpty(params string[] inputs) { return inputs.Any(z => string.IsNullOrEmpty(z)); } } }