feature: collect MDM Hardware Data (Autopilot hash) during device enrolment

resolves #160
This commit is contained in:
Gary Sharp
2025-02-05 17:38:57 +11:00
parent 0853bcee50
commit f946f3250c
17 changed files with 599 additions and 422 deletions
+13
View File
@@ -46,6 +46,7 @@ namespace Disco.Client.Interop
audit.ApplyPhysicalMemoryInformation(); audit.ApplyPhysicalMemoryInformation();
audit.ApplyDiskDriveInformation(); audit.ApplyDiskDriveInformation();
audit.ApplyBatteryInformation(); audit.ApplyBatteryInformation();
audit.ApplyMobileDeviceManagementInformation();
audit.NetworkAdapters = Network.GetNetworkAdapters(); audit.NetworkAdapters = Network.GetNetworkAdapters();
@@ -560,6 +561,18 @@ namespace Disco.Client.Interop
} }
} }
private static void ApplyMobileDeviceManagementInformation(this DeviceHardware deviceHardware)
{
try
{
using (var wmiObject = new ManagementObject(@"\\.\ROOT\CIMV2\mdm\dmmap:MDM_DevDetail_Ext01.InstanceID=""Ext"",ParentID=""./DevDetail"""))
{
deviceHardware.MdmHardwareData = (string)wmiObject.GetPropertyValue("DeviceHardwareData");
}
}
catch (Exception) { }
}
private static string Description(this PCSystemTypes type) private static string Description(this PCSystemTypes type)
{ {
switch (type) switch (type)
@@ -11,6 +11,8 @@ namespace Disco.Models.ClientServices.EnrolmentInformation
public string Model { get; set; } public string Model { get; set; }
public string ModelType { get; set; } public string ModelType { get; set; }
public string MdmHardwareData { get; set; }
public List<Bios> Bios { get; set; } public List<Bios> Bios { get; set; }
public List<BaseBoard> BasebBoard { get; set; } public List<BaseBoard> BasebBoard { get; set; }
public List<ComputerSystem> ComputerSystem { get; set; } public List<ComputerSystem> ComputerSystem { get; set; }
@@ -20,6 +20,7 @@ namespace Disco.Models.Repository
public const string HardwareKeyBaseBoard = "BaseBoard"; public const string HardwareKeyBaseBoard = "BaseBoard";
public const string HardwareKeyComputerSystem = "ComputerSystem"; public const string HardwareKeyComputerSystem = "ComputerSystem";
public const string HardwareKeyBatteries = "Batteries"; public const string HardwareKeyBatteries = "Batteries";
public const string HardwareKeyMdmHardwareData = "MdmHardwareData";
[Column(Order = 0), Key] [Column(Order = 0), Key]
public string DeviceSerialNumber { get; set; } public string DeviceSerialNumber { get; set; }
@@ -127,6 +127,8 @@ namespace Disco.Models.Services.Devices.Exporting
public bool DetailLanAdapters { get; set; } public bool DetailLanAdapters { get; set; }
[Display(ShortName = "Details", Name = "Wireless LAN Adapters", Description = "The Wireless LAN Adapters associated with the device")] [Display(ShortName = "Details", Name = "Wireless LAN Adapters", Description = "The Wireless LAN Adapters associated with the device")]
public bool DetailWLanAdapters { get; set; } public bool DetailWLanAdapters { get; set; }
[Display(ShortName = "Details", Name = "MDM Hardware Data", Description = "The Mobile Device Management Hardware Data associated with the device")]
public bool DetailMdmHardwareData { get; set; }
[Display(ShortName = "Details", Name = "AC Adapter", Description = "The AC Adapter associated with the device")] [Display(ShortName = "Details", Name = "AC Adapter", Description = "The AC Adapter associated with the device")]
public bool DetailACAdapter { get; set; } public bool DetailACAdapter { get; set; }
[Display(ShortName = "Details", Name = "Battery", Description = "The manually entered battery associated with the device")] [Display(ShortName = "Details", Name = "Battery", Description = "The manually entered battery associated with the device")]
@@ -358,5 +358,18 @@ namespace Disco.Services
device.SetDetail(DeviceDetail.ScopeHardware, DeviceDetail.HardwareKeyBatteries, json); device.SetDetail(DeviceDetail.ScopeHardware, DeviceDetail.HardwareKeyBatteries, json);
} }
public static string MdmHardwareData(this IEnumerable<DeviceDetail> details)
{
return details.GetDetail(DeviceDetail.ScopeHardware, DeviceDetail.HardwareKeyMdmHardwareData);
}
/// <summary>
/// Sets the Mobile Device Management Hardware Data
/// </summary>
public static void MdmHardwareData(this IEnumerable<DeviceDetail> details, Device device, string mdmHardwareData)
{
device.SetDetail(DeviceDetail.ScopeHardware, DeviceDetail.HardwareKeyMdmHardwareData, mdmHardwareData);
}
} }
} }
@@ -317,6 +317,8 @@ namespace Disco.Services.Devices.Enrolment
device.DeviceDetails.NetworkAdapters(device, Request.Hardware.NetworkAdapters); device.DeviceDetails.NetworkAdapters(device, Request.Hardware.NetworkAdapters);
if (Request.Hardware.Batteries?.Count > 0) if (Request.Hardware.Batteries?.Count > 0)
device.DeviceDetails.Batteries(device, Request.Hardware.Batteries); device.DeviceDetails.Batteries(device, Request.Hardware.Batteries);
if (!string.IsNullOrWhiteSpace(Request.Hardware.MdmHardwareData))
device.DeviceDetails.MdmHardwareData(device, Request.Hardware.MdmHardwareData);
if (adMachineAccount == null) if (adMachineAccount == null)
{ {
@@ -456,6 +456,7 @@ namespace Disco.Services.Devices.Exporting
} }
metadata.Add(nameof(DeviceExportOptions.DetailBatteries), batteriesFields); metadata.Add(nameof(DeviceExportOptions.DetailBatteries), batteriesFields);
metadata.Add(nameof(DeviceExportOptions.DetailKeyboard), new List<Metadata>() { new Metadata(nameof(DeviceExportOptions.DetailKeyboard), typeof(string), r => r.DeviceDetails.Where(dd => dd.Key == DeviceDetail.HardwareKeyKeyboard).Select(dd => dd.Value).FirstOrDefault(), csvStringEncoded) }); metadata.Add(nameof(DeviceExportOptions.DetailKeyboard), new List<Metadata>() { new Metadata(nameof(DeviceExportOptions.DetailKeyboard), typeof(string), r => r.DeviceDetails.Where(dd => dd.Key == DeviceDetail.HardwareKeyKeyboard).Select(dd => dd.Value).FirstOrDefault(), csvStringEncoded) });
metadata.Add(nameof(DeviceExportOptions.DetailMdmHardwareData), new List<Metadata>() { new Metadata(nameof(DeviceExportOptions.DetailMdmHardwareData), typeof(string), r => r.DeviceDetails.MdmHardwareData(), csvStringEncoded) });
return metadata; return metadata;
} }
+2 -2
View File
@@ -5883,7 +5883,7 @@ div.columnHost .column50 {
width: 50%; width: 50%;
} }
.hidden { .hidden {
display: none; display: none !important;
} }
.success { .success {
color: #60A917; color: #60A917;
@@ -6021,7 +6021,7 @@ i.clipboard-link {
right: calc(-1.28571429em - 4px); right: calc(-1.28571429em - 4px);
top: calc(100% - 14px); top: calc(100% - 14px);
z-index: 100; z-index: 100;
color: #D1D1D1; color: #d8d8d8;
background-color: #fff; background-color: #fff;
} }
i.clipboard-link:hover { i.clipboard-link:hover {
File diff suppressed because one or more lines are too long
+4
View File
@@ -311,6 +311,10 @@
background-color: #fff; background-color: #fff;
background: repeating-linear-gradient(45deg, #f4f4f4, #f4f4f4 10px, #fff 10px, #fff 20px); background: repeating-linear-gradient(45deg, #f4f4f4, #f4f4f4 10px, #fff 10px, #fff 20px);
} }
#DeviceDetailTab-DetailsContainer .device_detail_mdm_hardware_data code {
display: block;
word-break: break-all;
}
#deviceShowResources #AttachmentsContainer { #deviceShowResources #AttachmentsContainer {
padding: 0; padding: 0;
} }
+5
View File
@@ -282,6 +282,11 @@
} }
} }
} }
.device_detail_mdm_hardware_data code {
display: block;
word-break: break-all;
}
} }
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -1451,7 +1451,7 @@ div.columnHost .column50 {
width: 50%; width: 50%;
} }
.hidden { .hidden {
display: none; display: none !important;
} }
.success { .success {
color: #60A917; color: #60A917;
@@ -1589,7 +1589,7 @@ i.clipboard-link {
right: calc(-1.28571429em - 4px); right: calc(-1.28571429em - 4px);
top: calc(100% - 14px); top: calc(100% - 14px);
z-index: 100; z-index: 100;
color: #D1D1D1; color: #d8d8d8;
background-color: #fff; background-color: #fff;
} }
i.clipboard-link:hover { i.clipboard-link:hover {
+2 -2
View File
@@ -1519,7 +1519,7 @@ div.columnHost {
// Misc // Misc
.hidden { .hidden {
display: none; display: none !important;
} }
.success { .success {
@@ -1689,7 +1689,7 @@ i.clipboard-link {
right: calc(-1.28571429em - 4px); right: calc(-1.28571429em - 4px);
top: calc(100% - 14px); top: calc(100% - 14px);
z-index: 100; z-index: 100;
color: @BackgroundColour; color: @TableDataDarkBorderColour;
background-color: #fff; background-color: #fff;
&:hover { &:hover {
File diff suppressed because one or more lines are too long
@@ -19,6 +19,7 @@
var baseBoard = Model.Device.DeviceDetails.BaseBoard(); var baseBoard = Model.Device.DeviceDetails.BaseBoard();
var computerSystem = Model.Device.DeviceDetails.ComputerSystem(); var computerSystem = Model.Device.DeviceDetails.ComputerSystem();
var batteries = Model.Device.DeviceDetails.Batteries(); var batteries = Model.Device.DeviceDetails.Batteries();
var mdmHardwareData = Model.Device.DeviceDetails.MdmHardwareData();
} }
<div id="DeviceDetailTab-Details" class="DevicePart"> <div id="DeviceDetailTab-Details" class="DevicePart">
<div id="DeviceDetailTab-DetailsContainer"> <div id="DeviceDetailTab-DetailsContainer">
@@ -43,14 +44,14 @@
@foreach (var b in bios) @foreach (var b in bios)
{ {
<tr> <tr>
<td>@b.Manufacturer</td> <td><span data-clipboard>@b.Manufacturer</span></td>
<td>@b.SerialNumber</td> <td><span data-clipboard>@b.SerialNumber</span></td>
<td>@b.SMBIOSBIOSVersion @(b.SMBIOSMajorVersion.GetValueOrDefault(0)).@b.SMBIOSMinorVersion</td> <td><span data-clipboard>@b.SMBIOSBIOSVersion @(b.SMBIOSMajorVersion.GetValueOrDefault(0)).@b.SMBIOSMinorVersion</span></td>
<td>@(b.SystemBiosMajorVersion).@b.SystemBiosMinorVersion</td> <td><span data-clipboard>@(b.SystemBiosMajorVersion).@b.SystemBiosMinorVersion</span></td>
<td> <td>
@if (b.ReleaseDate.HasValue) @if (b.ReleaseDate.HasValue)
{ {
@b.ReleaseDate.Value.ToString("yyyy-MM-dd") <span data-clipboard>@b.ReleaseDate.Value.ToString("yyyy-MM-dd")</span>
} }
</td> </td>
</tr> </tr>
@@ -82,19 +83,19 @@
@foreach (var b in baseBoard) @foreach (var b in baseBoard)
{ {
<tr> <tr>
<td>@b.Manufacturer</td> <td><span data-clipboard>@b.Manufacturer</span></td>
<td>@b.Model</td> <td><span data-clipboard>@b.Model</span></td>
<td>@b.Product</td> <td><span data-clipboard>@b.Product</span></td>
<td>@b.PartNumber</td> <td><span data-clipboard>@b.PartNumber</span></td>
<td>@b.SKU</td> <td><span data-clipboard>@b.SKU</span></td>
<td>@b.SerialNumber</td> <td><span data-clipboard>@b.SerialNumber</span></td>
<td> <td>
@if (b.ConfigOptions != null) @if (b.ConfigOptions != null)
{ {
<text>@string.Join("; ", b.ConfigOptions)</text> <span data-clipboard>@string.Join("; ", b.ConfigOptions)</span>
} }
</td> </td>
<td>@b.Version</td> <td><span data-clipboard>@b.Version</span></td>
</tr> </tr>
} }
</tbody> </tbody>
@@ -125,28 +126,28 @@
@foreach (var c in computerSystem) @foreach (var c in computerSystem)
{ {
<tr> <tr>
<td>@c.Description</td> <td><span data-clipboard>@c.Description</span></td>
<td>@c.PCSystemType</td> <td><span data-clipboard>@c.PCSystemType</span></td>
<td>@c.SystemType</td> <td><span data-clipboard>@c.SystemType</span></td>
<td>@c.PrimaryOwnerName @c.PrimaryOwnerContact</td> <td><span data-clipboard>@c.PrimaryOwnerName @c.PrimaryOwnerContact</span></td>
<td>@c.ChassisSKUNumber</td> <td><span data-clipboard>@c.ChassisSKUNumber</span></td>
<td>@c.SystemSKUNumber</td> <td><span data-clipboard>@c.SystemSKUNumber</span></td>
<td> <td>
@if (c.OEMStringArray != null) @if (c.OEMStringArray != null)
{ {
<text>@string.Join("; ", c.OEMStringArray)</text> <span data-clipboard>@string.Join("; ", c.OEMStringArray)</span>
} }
</td> </td>
<td> <td>
@if (c.CurrentTimeZone.HasValue) @if (c.CurrentTimeZone.HasValue)
{ {
@((c.CurrentTimeZone.Value / 60).ToString(@"00\:"))@(Math.Abs(c.CurrentTimeZone.Value % 60).ToString("00")) <span data-clipboard>@((c.CurrentTimeZone.Value / 60).ToString(@"00\:"))@(Math.Abs(c.CurrentTimeZone.Value % 60).ToString("00"))</span>
} }
</td> </td>
<td> <td>
@if (c.Roles != null) @if (c.Roles != null)
{ {
<text>@string.Join("; ", c.Roles)</text> <span data-clipboard>@string.Join("; ", c.Roles)</span>
} }
</td> </td>
</tr> </tr>
@@ -176,12 +177,12 @@
@foreach (var processor in processors) @foreach (var processor in processors)
{ {
<tr> <tr>
<td>@processor.Name</td> <td><span data-clipboard>@processor.Name</span></td>
<td>@processor.Description</td> <td><span data-clipboard>@processor.Description</span></td>
<td>@processor.Architecture</td> <td><span data-clipboard>@processor.Architecture</span></td>
<td>@processor.MaxClockSpeedFriendly()</td> <td><span data-clipboard>@processor.MaxClockSpeedFriendly()</span></td>
<td>@processor.NumberOfCores.GetValueOrDefault(0).ToString("N0")</td> <td><span data-clipboard>@processor.NumberOfCores.GetValueOrDefault(0).ToString("N0")</span></td>
<td>@processor.NumberOfLogicalProcessors.GetValueOrDefault(0).ToString("N0")</td> <td><span data-clipboard>@processor.NumberOfLogicalProcessors.GetValueOrDefault(0).ToString("N0")</span></td>
</tr> </tr>
} }
</tbody> </tbody>
@@ -209,12 +210,12 @@
@foreach (var memory in physicalMemory) @foreach (var memory in physicalMemory)
{ {
<tr> <tr>
<td>@memory.DeviceLocator</td> <td><span data-clipboard>@memory.DeviceLocator</span></td>
<td>@memory.Manufacturer</td> <td><span data-clipboard>@memory.Manufacturer</span></td>
<td>@memory.PartNumber</td> <td><span data-clipboard>@memory.PartNumber</span></td>
<td>@memory.SerialNumber</td> <td><span data-clipboard>@memory.SerialNumber</span></td>
<td>@memory.CapacityFriendly()</td> <td><span data-clipboard>@memory.CapacityFriendly()</span></td>
<td>@memory.ConfiguredClockSpeed</td> <td><span data-clipboard>@memory.ConfiguredClockSpeed</span></td>
</tr> </tr>
} }
</tbody> </tbody>
@@ -242,13 +243,13 @@
{ {
<tr> <tr>
<td> <td>
@(adapter.NetConnectionID ?? "N/A") @if (adapter.IsWlanAdapter) <span data-clipboard>@(adapter.NetConnectionID ?? "N/A")</span> @if (adapter.IsWlanAdapter)
{<i class="fa fa-wifi"></i>} {<i class="fa fa-wifi"></i>}
</td> </td>
<td>@adapter.Manufacturer</td> <td><span data-clipboard>@adapter.Manufacturer</span></td>
<td>@adapter.ProductName</td> <td><span data-clipboard>@adapter.ProductName</span></td>
<td>@adapter.SpeedFriendly()</td> <td><span data-clipboard>@adapter.SpeedFriendly()</span></td>
<td>@adapter.MACAddress</td> <td><span data-clipboard>@adapter.MACAddress</span></td>
</tr> </tr>
} }
</tbody> </tbody>
@@ -262,14 +263,14 @@
{ {
<tr class="device_detail_lan_mac_address"> <tr class="device_detail_lan_mac_address">
<th>LAN MAC Address</th> <th>LAN MAC Address</th>
<td class="pad code">@(lanMacAddress)</td> <td class="pad code"><span data-clipboard>@lanMacAddress</span></td>
</tr> </tr>
} }
if (wlanMacAddress != null) if (wlanMacAddress != null)
{ {
<tr class="device_detail_wlan_mac_address"> <tr class="device_detail_wlan_mac_address">
<th>WLAN MAC Address</th> <th>WLAN MAC Address</th>
<td class="pad code">@(wlanMacAddress)</td> <td class="pad code"><span data-clipboard>@wlanMacAddress</span></td>
</tr> </tr>
} }
} }
@@ -294,13 +295,13 @@
@foreach (var disk in diskDrives) @foreach (var disk in diskDrives)
{ {
<tr> <tr>
<td>@disk.Manufacturer</td> <td><span data-clipboard>@disk.Manufacturer</span></td>
<td>@disk.Model</td> <td><span data-clipboard>@disk.Model</span></td>
<td>@disk.SerialNumber</td> <td><span data-clipboard>@disk.SerialNumber</span></td>
<td>@disk.FirmwareRevision</td> <td><span data-clipboard>@disk.FirmwareRevision</span></td>
<td>@disk.MediaType</td> <td><span data-clipboard>@disk.MediaType</span></td>
<td>@disk.InterfaceType</td> <td><span data-clipboard>@disk.InterfaceType</span></td>
<td>@disk.SizeFriendly()</td> <td><span data-clipboard>@disk.SizeFriendly()</span></td>
</tr> </tr>
if (disk.Partitions != null) if (disk.Partitions != null)
{ {
@@ -369,7 +370,35 @@
</td> </td>
</tr> </tr>
} }
@if (!string.IsNullOrEmpty(mdmHardwareData))
{
<tr class="device_detail_mdm_hardware_data">
<th>MDM Hardware Data</th>
<td class="pad">
<div>
<button class="button small" data-action="copy">Copy</button>
<button class="button small" data-action="show">Show</button>
</div>
<code class="hidden" data-clipboard>@mdmHardwareData</code>
<script>
$(function () {
const $container = $('tr.device_detail_mdm_hardware_data');
if (!navigator.clipboard) {
$container.find('button[data-action="copy"]').remove();
} else {
$container.find('button[data-action="copy"]').on('click', function () {
navigator.clipboard.writeText($container.find('code').text());
});
}
$container.find('button[data-action="show"]').on('click', function () {
$container.find('code').removeClass('hidden');
$(this).remove();
});
});
</script>
</td>
</tr>
}
<tr class="device_detail_ac_adapter"> <tr class="device_detail_ac_adapter">
<th>AC Adapter</th> <th>AC Adapter</th>
<td class="pad"> <td class="pad">
File diff suppressed because it is too large Load Diff