236 lines
7.7 KiB
C#

using Intel.Management.Wsman;
using System.Security;
namespace AmtScanner.Api.Services;
public interface IAmtPowerService
{
Task<PowerStateResult> GetPowerStateAsync(string ipAddress, string username, string password, List<int> openPorts);
Task<PowerActionResult> ChangePowerStateAsync(string ipAddress, string username, string password, List<int> openPorts, PowerAction action);
}
public enum PowerAction
{
PowerOn = 2,
PowerCycle = 5, // 重启(硬重启)
PowerOff = 8, // 关机(硬关机)
Reset = 10, // 重置
GracefulOff = 12, // 优雅关机
GracefulReset = 14 // 优雅重启
}
public class PowerStateResult
{
public bool Success { get; set; }
public int PowerState { get; set; }
public string PowerStateText { get; set; } = string.Empty;
public string? Error { get; set; }
}
public class PowerActionResult
{
public bool Success { get; set; }
public string Message { get; set; } = string.Empty;
public string? Error { get; set; }
}
public class AmtPowerService : IAmtPowerService
{
private readonly ILogger<AmtPowerService> _logger;
public AmtPowerService(ILogger<AmtPowerService> logger)
{
_logger = logger;
}
public async Task<PowerStateResult> GetPowerStateAsync(
string ipAddress,
string username,
string password,
List<int> openPorts)
{
var result = new PowerStateResult();
try
{
var connection = CreateConnection(ipAddress, username, password, openPorts);
await Task.Run(() =>
{
// 使用 SDK 中的方式查询电源状态
var computerSysRef = connection.NewReference("SELECT * FROM CIM_ComputerSystem WHERE Name='ManagedSystem'");
var associatedPowerMgmtRef = connection.NewReference("CIM_AssociatedPowerManagementService");
associatedPowerMgmtRef.AddSelector("UserOfService", computerSysRef);
foreach (IWsmanItem item in associatedPowerMgmtRef.Enumerate(
"http://schemas.dmtf.org/wbem/wsman/1/wsman/SelectorFilter", null))
{
if (item.Object.GetProperty("ServiceProvided").IsA("CIM_PowerManagementService"))
{
var powerState = Convert.ToInt32(item.Object.GetProperty("PowerState").ToString());
result.PowerState = powerState;
result.PowerStateText = GetPowerStateText(powerState);
result.Success = true;
break;
}
}
});
if (!result.Success)
{
result.Error = "无法获取电源状态";
}
}
catch (Exception ex)
{
_logger.LogError(ex, "获取电源状态失败: {Ip}", ipAddress);
result.Error = ex.Message;
}
return result;
}
public async Task<PowerActionResult> ChangePowerStateAsync(
string ipAddress,
string username,
string password,
List<int> openPorts,
PowerAction action)
{
var result = new PowerActionResult();
try
{
_logger.LogInformation("执行电源操作: {Action} on {Ip}", action, ipAddress);
var connection = CreateConnection(ipAddress, username, password, openPorts);
await Task.Run(() =>
{
// 获取电源管理服务
var powerManagementRef = connection.NewReference(
"SELECT * FROM CIM_PowerManagementService WHERE Name='Intel(r) AMT Power Management Service'");
// 创建输入参数
var inputObject = powerManagementRef.CreateMethodInput("RequestPowerStateChange");
inputObject.SetProperty("PowerState", ((int)action).ToString());
// 设置目标计算机系统
var computerSystemRef = connection.NewReference(
"SELECT * FROM CIM_ComputerSystem WHERE Name='ManagedSystem'");
inputObject.SetProperty("ManagedElement", computerSystemRef);
// 调用方法
var outputObject = powerManagementRef.InvokeMethod(inputObject);
var returnValue = outputObject.GetProperty("ReturnValue");
var returnCode = Convert.ToUInt32(returnValue.ToString());
if (returnCode == 0)
{
result.Success = true;
result.Message = GetActionSuccessMessage(action);
}
else if (returnCode == 2)
{
result.Success = false;
result.Error = "操作不允许:当前系统状态不支持此操作";
}
else
{
result.Success = false;
result.Error = $"操作失败,错误代码: {returnCode}";
}
});
_logger.LogInformation("电源操作完成: {Action} on {Ip}, Success: {Success}",
action, ipAddress, result.Success);
}
catch (Exception ex)
{
_logger.LogError(ex, "电源操作失败: {Action} on {Ip}", action, ipAddress);
result.Error = ex.Message;
}
return result;
}
private WsmanConnection CreateConnection(string ipAddress, string username, string password, List<int> openPorts)
{
string protocol;
int port;
if (openPorts.Contains(16992))
{
protocol = "http";
port = 16992;
}
else if (openPorts.Contains(16993))
{
protocol = "https";
port = 16993;
}
else
{
throw new Exception("没有找到可用的AMT端口");
}
var securePassword = new SecureString();
foreach (char c in password)
{
securePassword.AppendChar(c);
}
securePassword.MakeReadOnly();
var connection = new WsmanConnection();
connection.Address = $"{protocol}://{ipAddress}:{port}/wsman";
connection.SetCredentials(username, securePassword);
if (protocol == "https")
{
connection.Options.ServerCertificateValidationCallback = (certificate, sslPolicyErrors) =>
{
if (certificate.Subject.Equals(certificate.Issuer))
return true;
if (sslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
return true;
return false;
};
}
return connection;
}
private string GetPowerStateText(int powerState)
{
return powerState switch
{
2 => "开机",
3 => "轻度睡眠",
4 => "深度睡眠",
5 => "电源循环(软)",
6 => "硬关机",
7 => "休眠",
8 => "软关机",
9 => "电源循环(硬)",
10 => "主总线重置",
11 => "诊断中断",
_ => $"未知状态 ({powerState})"
};
}
private string GetActionSuccessMessage(PowerAction action)
{
return action switch
{
PowerAction.PowerOn => "开机命令已发送",
PowerAction.PowerCycle => "重启命令已发送",
PowerAction.PowerOff => "关机命令已发送",
PowerAction.Reset => "重置命令已发送",
PowerAction.GracefulOff => "优雅关机命令已发送",
PowerAction.GracefulReset => "优雅重启命令已发送",
_ => "电源操作命令已发送"
};
}
}