116 lines
5.2 KiB
C#
116 lines
5.2 KiB
C#
|
using System;
|
|||
|
using System.Diagnostics;
|
|||
|
using System.Linq;
|
|||
|
using System.Management;
|
|||
|
|
|||
|
namespace NetworkResurrector.Application.Services
|
|||
|
{
|
|||
|
public class ShutdownService : IShutdownService
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-xp/bb491003(v=technet.10)?redirectedfrom=MSDN
|
|||
|
/// </summary>
|
|||
|
/// <param name="ipAddress"></param>
|
|||
|
/// <returns></returns>
|
|||
|
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);
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// https://msdn.microsoft.com/en-us/library/system.management.managementscope(v=vs.110).aspx
|
|||
|
/// </summary>
|
|||
|
/// <param name="ipAddress"></param>
|
|||
|
/// <param name="user"></param>
|
|||
|
/// <param name="password"></param>
|
|||
|
/// <returns></returns>
|
|||
|
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));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|