308 lines
No EOL
16 KiB
C#
308 lines
No EOL
16 KiB
C#
using Insight.Agent.Interfaces;
|
|
using Insight.Agent.Messages;
|
|
using System.Management;
|
|
using System.Runtime.Versioning;
|
|
using static Insight.Agent.Messages.PhysicalDisk;
|
|
using static Insight.Agent.Messages.StoragePool;
|
|
using static Insight.Agent.Messages.VirtualDisk;
|
|
|
|
namespace Insight.Agent.Network.Handlers
|
|
{
|
|
[SupportedOSPlatform("windows")]
|
|
public class StoragePoolHandler : IAgentMessageHandler<AgentSession>
|
|
{
|
|
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage
|
|
{
|
|
if (message is GetInventory)
|
|
{
|
|
var result = new StoragePoolList();
|
|
result.AddRange(GetStoragePool());
|
|
|
|
await sender.SendAsync(result, cancellationToken);
|
|
}
|
|
}
|
|
|
|
private static List<StoragePool> GetStoragePool()
|
|
{
|
|
if (Environment.OSVersion.Version.Major < 6 || Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor < 2)
|
|
{
|
|
throw new PlatformNotSupportedException();
|
|
}
|
|
|
|
using var searcher = new ManagementObjectSearcher
|
|
{
|
|
Scope = new ManagementScope(@"root\microsoft\windows\storage"),
|
|
Query = new ObjectQuery("select objectid, uniqueid, name, friendlyname, resiliencysettingnamedefault, isprimordial, isreadonly, isclustered, size, allocatedsize, logicalsectorsize, operationalstatus, healthstatus from msft_storagepool")
|
|
};
|
|
|
|
if (searcher.TryGet(out var collection) is false)
|
|
{
|
|
searcher.Query = new ObjectQuery("select * from msft_storagepool");
|
|
|
|
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
|
}
|
|
|
|
var pools = new List<StoragePool>();
|
|
|
|
using (collection)
|
|
{
|
|
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
|
{
|
|
var pool = new StoragePool();
|
|
|
|
var properties = @object.GetPropertyHashes();
|
|
|
|
pool.UniqueId = @object.GetValue<string>(properties, "uniqueid")?.Trim();
|
|
pool.Name = @object.GetValue<string>(properties, "name")?.Trim();
|
|
pool.FriendlyName = @object.GetValue<string>(properties, "friendlyname")?.Trim();
|
|
|
|
if (@object.TryGetValue<ushort[]>(properties, "operationalstatus", out var operationals) && operationals is not null)
|
|
{
|
|
pool.States = operationals.Select(p => (StoragePool.OperationalState)p).ToList();
|
|
}
|
|
|
|
pool.Health = (StoragePool.HealthState)@object.GetValue<ushort>(properties, "healthstatus");
|
|
pool.RetireMissingPhysicalDisks = (RetireMissingPhysicalDisksEnum)@object.GetValue<ushort>(properties, "retiremissingphysicaldisks");
|
|
pool.Resiliency = @object.GetValue<string>(properties, "resiliencysettingnamedefault")?.Trim();
|
|
pool.IsPrimordial = @object.GetValue<bool>(properties, "isprimordial");
|
|
pool.IsReadOnly = @object.GetValue<bool>(properties, "isreadonly");
|
|
pool.IsClustered = @object.GetValue<bool>(properties, "isclustered");
|
|
pool.Size = @object.GetValue<ulong>(properties, "size");
|
|
pool.AllocatedSize = @object.GetValue<ulong>(properties, "allocatedsize");
|
|
pool.SectorSize = @object.GetValue<ulong>(properties, "logicalsectorsize");
|
|
|
|
if (@object.GetValue<string>(properties, "objectid") is string objectId)
|
|
{
|
|
pool.PhysicalDisks = QueryPhysicalDisksByStoragePool(objectId);
|
|
pool.VirtualDisks = QueryVirtualDisksByStoragePool(objectId);
|
|
}
|
|
|
|
pools.Add(pool);
|
|
}
|
|
}
|
|
|
|
return pools;
|
|
}
|
|
|
|
private static List<PhysicalDisk> GetPhysicalDisks()
|
|
{
|
|
using var searcher = new ManagementObjectSearcher
|
|
{
|
|
Scope = new ManagementScope(@"root\microsoft\windows\storage"),
|
|
Query = new ObjectQuery("select objectid, uniqueid, name, friendlyname from msft_physicaldisk")
|
|
};
|
|
|
|
if (searcher.TryGet(out var collection) is false)
|
|
{
|
|
searcher.Query = new ObjectQuery("select * from msft_physicaldisk");
|
|
|
|
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
|
}
|
|
|
|
var disks = new List<PhysicalDisk>();
|
|
|
|
using (collection)
|
|
{
|
|
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
|
{
|
|
var disk = new PhysicalDisk();
|
|
|
|
var properties = @object.GetPropertyHashes();
|
|
|
|
disk.UniqueId = @object.GetValue<string>(properties, "uniqueid")?.Trim();
|
|
disk.FriendlyName = @object.GetValue<string>(properties, "friendlyname")?.Trim();
|
|
disk.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
|
|
disk.Model = @object.GetValue<string>(properties, "model")?.Trim();
|
|
disk.MediaType = @object.GetValue<ushort>(properties, "mediatype");
|
|
disk.BusType = @object.GetValue<ushort>(properties, "bustype");
|
|
|
|
if (@object.TryGetValue<ushort[]>(properties, "operationalstatus", out var operationals) && operationals is not null)
|
|
{
|
|
disk.States = operationals.Select(p => (PhysicalDisk.OperationalState)p).ToList();
|
|
}
|
|
|
|
disk.Health = (PhysicalDisk.HealthState)@object.GetValue<ushort>(properties, "healthstatus");
|
|
|
|
if (@object.TryGetValue<ushort[]>(properties, "supportedusages", out var supportedusages) && supportedusages is not null)
|
|
{
|
|
disk.SupportedUsages = supportedusages.Select(p => (SupportedUsagesEnum)p).ToList();
|
|
}
|
|
|
|
disk.Usage = @object.GetValue<ushort>(properties, "usage");
|
|
disk.PhysicalLocation = @object.GetValue<string>(properties, "physicallocation")?.Trim();
|
|
disk.SerialNumber = @object.GetValue<string>(properties, "serialnumber")?.Trim();
|
|
disk.FirmwareVersion = @object.GetValue<string>(properties, "firmwareversion")?.Trim();
|
|
disk.Size = @object.GetValue<ulong>(properties, "size");
|
|
disk.AllocatedSize = @object.GetValue<ulong>(properties, "allocatedsize");
|
|
disk.LogicalSectorSize = @object.GetValue<ulong>(properties, "logicalsectorsize");
|
|
disk.PhysicalSectorSize = @object.GetValue<ulong>(properties, "physicalsectorsize");
|
|
disk.VirtualDiskFootprint = @object.GetValue<ulong>(properties, "virtualdiskfootprint");
|
|
|
|
disks.Add(disk);
|
|
}
|
|
}
|
|
|
|
return disks;
|
|
}
|
|
|
|
private static List<VirtualDisk> GetVirtualDisks()
|
|
{
|
|
using var searcher = new ManagementObjectSearcher
|
|
{
|
|
Scope = new ManagementScope(@"root\microsoft\windows\storage"),
|
|
Query = new ObjectQuery("select objectid, uniqueid, name, friendlyname, access, provisioningtype, physicaldiskredundancy, resiliencysettingname, isdeduplicationenabled, issnapshot, operationalstatus, healthstatus, size, allocatedsize, footprintonpool, readcachesize, writecachesize from msft_virtualdisk")
|
|
};
|
|
|
|
if (searcher.TryGet(out var collection) is false)
|
|
{
|
|
searcher.Query = new ObjectQuery("select * from msft_virtualdisk");
|
|
|
|
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
|
}
|
|
|
|
var disks = new List<VirtualDisk>();
|
|
|
|
using (collection)
|
|
{
|
|
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
|
{
|
|
var disk = new VirtualDisk();
|
|
|
|
var properties = @object.GetPropertyHashes();
|
|
|
|
disk.UniqueId = @object.GetValue<string>(properties, "uniqueid")?.Trim();
|
|
disk.Name = @object.GetValue<string>(properties, "name")?.Trim();
|
|
disk.FriendlyName = @object.GetValue<string>(properties, "friendlyname")?.Trim();
|
|
disk.AccessType = (AccessTypeEnum)@object.GetValue<ushort>(properties, "access");
|
|
disk.ProvisioningType = (ProvisioningTypeEnum)@object.GetValue<ushort>(properties, "provisioningtype");
|
|
disk.PhysicalDiskRedundancy = @object.GetValue<ushort>(properties, "physicaldiskredundancy");
|
|
disk.ResiliencySettingName = @object.GetValue<string>(properties, "resiliencysettingname")?.Trim();
|
|
disk.Deduplication = @object.GetValue<bool>(properties, "isdeduplicationenabled");
|
|
disk.IsSnapshot = @object.GetValue<bool>(properties, "issnapshot");
|
|
|
|
if (@object.TryGetValue<ushort[]>(properties, "operationalstatus", out var operationals) && operationals is not null)
|
|
{
|
|
disk.States = operationals.Select(p => (VirtualDisk.OperationalState)p).ToList();
|
|
}
|
|
|
|
disk.Health = (VirtualDisk.HealthState)@object.GetValue<ushort>(properties, "healthstatus");
|
|
disk.Size = @object.GetValue<ulong>(properties, "size");
|
|
disk.AllocatedSize = @object.GetValue<ulong>(properties, "allocatedsize");
|
|
disk.FootprintOnPool = @object.GetValue<ulong>(properties, "footprintonpool");
|
|
disk.ReadCacheSize = @object.GetValue<ulong>(properties, "readcachesize");
|
|
disk.WriteCacheSize = @object.GetValue<ulong>(properties, "writecachesize");
|
|
|
|
disks.Add(disk);
|
|
}
|
|
}
|
|
|
|
return disks;
|
|
}
|
|
|
|
private static List<PhysicalDisk> QueryPhysicalDisksByStoragePool(string storagePoolObjectId)
|
|
{
|
|
using var searcher = new ManagementObjectSearcher
|
|
{
|
|
Scope = new ManagementScope(@"root\microsoft\windows\storage"),
|
|
Query = new ObjectQuery("ASSOCIATORS OF {MSFT_StoragePool.ObjectId=\"" + Helpers.EscapeWql(storagePoolObjectId) + "\"} WHERE AssocClass = MSFT_StoragePoolToPhysicalDisk")
|
|
};
|
|
|
|
if (searcher.TryGet(out var collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
|
|
|
var disks = new List<PhysicalDisk>();
|
|
|
|
using (collection)
|
|
{
|
|
foreach (ManagementObject @object in collection)
|
|
{
|
|
var disk = new PhysicalDisk();
|
|
|
|
var properties = @object.GetPropertyHashes();
|
|
|
|
disk.UniqueId = @object.GetValue<string>(properties, "uniqueid")?.Trim();
|
|
disk.DeviceId = @object.GetValue<string>(properties, "deviceid")?.Trim();
|
|
disk.FriendlyName = @object.GetValue<string>(properties, "friendlyname")?.Trim();
|
|
disk.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
|
|
disk.Model = @object.GetValue<string>(properties, "model")?.Trim();
|
|
disk.MediaType = @object.GetValue<ushort>(properties, "mediatype");
|
|
disk.BusType = @object.GetValue<ushort>(properties, "bustype");
|
|
|
|
if (@object.TryGetValue<ushort[]>(properties, "operationalstatus", out var operationals) && operationals is not null)
|
|
{
|
|
disk.States = operationals.Select(p => (PhysicalDisk.OperationalState)p).ToList();
|
|
}
|
|
|
|
disk.Health = (PhysicalDisk.HealthState)@object.GetValue<ushort>(properties, "healthstatus");
|
|
|
|
if (@object.TryGetValue<ushort[]>(properties, "supportedusages", out var supportedusages) && supportedusages is not null)
|
|
{
|
|
disk.SupportedUsages = supportedusages.Select(p => (SupportedUsagesEnum)p).ToList();
|
|
}
|
|
|
|
disk.Usage = @object.GetValue<ushort>(properties, "usage");
|
|
disk.PhysicalLocation = @object.GetValue<string>(properties, "physicallocation")?.Trim();
|
|
disk.SerialNumber = @object.GetValue<string>(properties, "serialnumber")?.Trim();
|
|
disk.FirmwareVersion = @object.GetValue<string>(properties, "firmwareversion")?.Trim();
|
|
disk.Size = @object.GetValue<ulong>(properties, "size");
|
|
disk.AllocatedSize = @object.GetValue<ulong>(properties, "allocatedsize");
|
|
disk.LogicalSectorSize = @object.GetValue<ulong>(properties, "logicalsectorsize");
|
|
disk.PhysicalSectorSize = @object.GetValue<ulong>(properties, "physicalsectorsize");
|
|
disk.VirtualDiskFootprint = @object.GetValue<ulong>(properties, "virtualdiskfootprint");
|
|
|
|
disks.Add(disk);
|
|
}
|
|
}
|
|
|
|
return disks;
|
|
}
|
|
|
|
private static List<VirtualDisk> QueryVirtualDisksByStoragePool(string storagePoolObjectId)
|
|
{
|
|
using var searcher = new ManagementObjectSearcher
|
|
{
|
|
Scope = new ManagementScope(@"root\microsoft\windows\storage"),
|
|
Query = new ObjectQuery("ASSOCIATORS OF {MSFT_StoragePool.ObjectId=\"" + Helpers.EscapeWql(storagePoolObjectId) + "\"} WHERE AssocClass = MSFT_StoragePoolToVirtualDisk")
|
|
};
|
|
|
|
if (searcher.TryGet(out var collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
|
|
|
var disks = new List<VirtualDisk>();
|
|
|
|
using (collection)
|
|
{
|
|
foreach (ManagementObject @object in collection)
|
|
{
|
|
var disk = new VirtualDisk();
|
|
|
|
var properties = @object.GetPropertyHashes();
|
|
|
|
disk.UniqueId = @object.GetValue<string>(properties, "uniqueid")?.Trim();
|
|
disk.Name = @object.GetValue<string>(properties, "name")?.Trim();
|
|
disk.FriendlyName = @object.GetValue<string>(properties, "friendlyname")?.Trim();
|
|
disk.AccessType = (AccessTypeEnum)@object.GetValue<ushort>(properties, "access");
|
|
disk.ProvisioningType = (ProvisioningTypeEnum)@object.GetValue<ushort>(properties, "provisioningtype");
|
|
disk.PhysicalDiskRedundancy = @object.GetValue<ushort>(properties, "physicaldiskredundancy");
|
|
disk.ResiliencySettingName = @object.GetValue<string>(properties, "resiliencysettingname")?.Trim();
|
|
disk.Deduplication = @object.GetValue<bool>(properties, "isdeduplicationenabled");
|
|
disk.IsSnapshot = @object.GetValue<bool>(properties, "issnapshot");
|
|
|
|
if (@object.TryGetValue<ushort[]>(properties, "operationalstatus", out var operationals) && operationals is not null)
|
|
{
|
|
disk.States = operationals.Select(p => (VirtualDisk.OperationalState)p).ToList();
|
|
}
|
|
|
|
disk.Health = (VirtualDisk.HealthState)@object.GetValue<ushort>(properties, "healthstatus");
|
|
disk.Size = @object.GetValue<ulong>(properties, "size");
|
|
disk.AllocatedSize = @object.GetValue<ulong>(properties, "allocatedsize");
|
|
disk.FootprintOnPool = @object.GetValue<ulong>(properties, "footprintonpool");
|
|
disk.ReadCacheSize = @object.GetValue<ulong>(properties, "readcachesize");
|
|
disk.WriteCacheSize = @object.GetValue<ulong>(properties, "writecachesize");
|
|
|
|
disks.Add(disk);
|
|
}
|
|
}
|
|
|
|
return disks;
|
|
}
|
|
}
|
|
} |