From fce40d935118dd0928d6fe20d602fe01a651569f Mon Sep 17 00:00:00 2001 From: Alphaeus Mote Date: Wed, 7 May 2025 11:04:10 -0400 Subject: [PATCH] Enhanced SMBIOS functionality with manufacturer profiles and realistic hardware information --- Documentation/cmdlets/Set-ProxmoxVMSMBIOS.md | 54 +++ Documentation/examples/SMBIOS-Examples.ps1 | 12 +- .../Cmdlets/NewProxmoxVMBuilderCmdlet.cs | 4 +- PSProxmox/Cmdlets/NewProxmoxVMCmdlet.cs | 4 +- PSProxmox/Cmdlets/SetProxmoxVMSMBIOSCmdlet.cs | 58 ++- PSProxmox/Models/ProxmoxVMSMBIOS.cs | 14 +- PSProxmox/Models/ProxmoxVMSMBIOSProfile.cs | 443 +++++++++++++++--- 7 files changed, 510 insertions(+), 79 deletions(-) diff --git a/Documentation/cmdlets/Set-ProxmoxVMSMBIOS.md b/Documentation/cmdlets/Set-ProxmoxVMSMBIOS.md index 81fda54..c3eecee 100644 --- a/Documentation/cmdlets/Set-ProxmoxVMSMBIOS.md +++ b/Documentation/cmdlets/Set-ProxmoxVMSMBIOS.md @@ -33,6 +33,19 @@ Set-ProxmoxVMSMBIOS [] ``` +```powershell +Set-ProxmoxVMSMBIOS + -Connection + -Node + -VMID + -UseProfile + -Profile + [-PassThru] + [-WhatIf] + [-Confirm] + [] +``` + ## Description The `Set-ProxmoxVMSMBIOS` cmdlet sets the SMBIOS (System Management BIOS) settings for a virtual machine in Proxmox VE. SMBIOS settings allow you to customize hardware identification information that's presented to the guest operating system. @@ -199,6 +212,38 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -UseProfile + +Whether to use a manufacturer profile for SMBIOS values. + +```yaml +Type: SwitchParameter +Parameter Sets: Profile +Aliases: + +Required: True +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Profile + +The manufacturer profile to use for SMBIOS values. Valid values are: Proxmox, Dell, HP, Lenovo, Microsoft, VMware, HyperV, VirtualBox, Random. + +```yaml +Type: String +Parameter Sets: Profile +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -PassThru Return the updated SMBIOS settings. @@ -303,6 +348,15 @@ Set-ProxmoxVMSMBIOS -Connection $connection -Node "pve1" -VMID 100 -SMBIOS $smbi This example retrieves the current SMBIOS settings for VM 100, modifies them, and then updates the VM with the new settings. +### Example 4: Set SMBIOS settings using a manufacturer profile + +```powershell +$connection = Connect-ProxmoxServer -Server "proxmox.example.com" -Credential (Get-Credential) +Set-ProxmoxVMSMBIOS -Connection $connection -Node "pve1" -VMID 100 -UseProfile -Profile "Dell" -PassThru +``` + +This example sets the SMBIOS settings for VM 100 using the Dell manufacturer profile. The existing UUID will be preserved. + ## Related Links - [Get-ProxmoxVMSMBIOS](Get-ProxmoxVMSMBIOS.md) diff --git a/Documentation/examples/SMBIOS-Examples.ps1 b/Documentation/examples/SMBIOS-Examples.ps1 index 36ea1cb..ed2341c 100644 --- a/Documentation/examples/SMBIOS-Examples.ps1 +++ b/Documentation/examples/SMBIOS-Examples.ps1 @@ -50,8 +50,7 @@ Write-Host "UUID: $($smbios.UUID)" Set-ProxmoxVMSMBIOS -Connection $connection -Node "pve1" -VMID 100 -Manufacturer "Lenovo" -Product "ThinkSystem SR650" -Serial "LENOVO123" # Example 7: Update SMBIOS settings for an existing VM using a manufacturer profile -$smbios = ProxmoxVMSMBIOSProfile.GetProfile("VMware") -Set-ProxmoxVMSMBIOS -Connection $connection -Node "pve1" -VMID 101 -SMBIOS $smbios +Set-ProxmoxVMSMBIOS -Connection $connection -Node "pve1" -VMID 101 -UseProfile -Profile "VMware" -PassThru # Example 8: Create a VM with SMBIOS settings that mimic a physical server for licensing purposes $builder = New-ProxmoxVMBuilder -Name "license-server" -AutomaticSMBIOS -SMBIOSProfile "Dell" @@ -62,5 +61,14 @@ $builder.WithMemory(8192) .WithStart($true) $vm5 = New-ProxmoxVM -Connection $connection -Node "pve1" -Builder $builder +# Example 9: Create a VM with Microsoft Surface SMBIOS settings +$builder = New-ProxmoxVMBuilder -Name "surface-pro" -AutomaticSMBIOS -SMBIOSProfile "Microsoft" +$builder.WithMemory(4096) + .WithCores(2) + .WithDisk(50, "local-lvm") + .WithNetwork("virtio", "vmbr0") + .WithStart($true) +$vm6 = New-ProxmoxVM -Connection $connection -Node "pve1" -Builder $builder + # Disconnect from the server when done Disconnect-ProxmoxServer -Connection $connection diff --git a/PSProxmox/Cmdlets/NewProxmoxVMBuilderCmdlet.cs b/PSProxmox/Cmdlets/NewProxmoxVMBuilderCmdlet.cs index 02617fc..8f6fb65 100644 --- a/PSProxmox/Cmdlets/NewProxmoxVMBuilderCmdlet.cs +++ b/PSProxmox/Cmdlets/NewProxmoxVMBuilderCmdlet.cs @@ -135,10 +135,10 @@ namespace PSProxmox.Cmdlets public SwitchParameter AutomaticSMBIOS { get; set; } /// - /// The manufacturer profile to use for SMBIOS values. Valid values are: Proxmox, Dell, HP, Lenovo, VMware, HyperV, VirtualBox, Random. + /// The manufacturer profile to use for SMBIOS values. Valid values are: Proxmox, Dell, HP, Lenovo, Microsoft, VMware, HyperV, VirtualBox, Random. /// [Parameter(Mandatory = false)] - [ValidateSet("Proxmox", "Dell", "HP", "Lenovo", "VMware", "HyperV", "VirtualBox", "Random")] + [ValidateSet("Proxmox", "Dell", "HP", "Lenovo", "Microsoft", "VMware", "HyperV", "VirtualBox", "Random")] public string SMBIOSProfile { get; set; } = "Random"; /// diff --git a/PSProxmox/Cmdlets/NewProxmoxVMCmdlet.cs b/PSProxmox/Cmdlets/NewProxmoxVMCmdlet.cs index b378444..2424fd0 100644 --- a/PSProxmox/Cmdlets/NewProxmoxVMCmdlet.cs +++ b/PSProxmox/Cmdlets/NewProxmoxVMCmdlet.cs @@ -119,10 +119,10 @@ namespace PSProxmox.Cmdlets public SwitchParameter AutomaticSMBIOS { get; set; } /// - /// The manufacturer profile to use for SMBIOS values. Valid values are: Proxmox, Dell, HP, Lenovo, VMware, HyperV, VirtualBox, Random. + /// The manufacturer profile to use for SMBIOS values. Valid values are: Proxmox, Dell, HP, Lenovo, Microsoft, VMware, HyperV, VirtualBox, Random. /// [Parameter(Mandatory = false, ParameterSetName = "Direct")] - [ValidateSet("Proxmox", "Dell", "HP", "Lenovo", "VMware", "HyperV", "VirtualBox", "Random")] + [ValidateSet("Proxmox", "Dell", "HP", "Lenovo", "Microsoft", "VMware", "HyperV", "VirtualBox", "Random")] public string SMBIOSProfile { get; set; } = "Random"; /// diff --git a/PSProxmox/Cmdlets/SetProxmoxVMSMBIOSCmdlet.cs b/PSProxmox/Cmdlets/SetProxmoxVMSMBIOSCmdlet.cs index 59f9f60..8d23c7e 100644 --- a/PSProxmox/Cmdlets/SetProxmoxVMSMBIOSCmdlet.cs +++ b/PSProxmox/Cmdlets/SetProxmoxVMSMBIOSCmdlet.cs @@ -86,6 +86,19 @@ namespace PSProxmox.Cmdlets [Parameter(Mandatory = false, ParameterSetName = "Individual")] public string UUID { get; set; } + /// + /// Whether to use a manufacturer profile for SMBIOS values. + /// + [Parameter(Mandatory = false, ParameterSetName = "Profile")] + public SwitchParameter UseProfile { get; set; } + + /// + /// The manufacturer profile to use for SMBIOS values. Valid values are: Proxmox, Dell, HP, Lenovo, Microsoft, VMware, HyperV, VirtualBox, Random. + /// + [Parameter(Mandatory = true, ParameterSetName = "Profile")] + [ValidateSet("Proxmox", "Dell", "HP", "Lenovo", "Microsoft", "VMware", "HyperV", "VirtualBox", "Random")] + public string Profile { get; set; } + /// /// Return the updated SMBIOS settings. /// @@ -103,44 +116,61 @@ namespace PSProxmox.Cmdlets // Create SMBIOS settings ProxmoxVMSMBIOS smbiosSettings; + + // Get current settings first (for all parameter sets) + string response = client.Get($"nodes/{Node}/qemu/{VMID}/config"); + var configData = JsonUtility.DeserializeResponse(response); + + string currentSmbiosString = configData.data.smbios; + var currentSmbios = string.IsNullOrEmpty(currentSmbiosString) + ? new ProxmoxVMSMBIOS() + : ProxmoxVMSMBIOS.FromProxmoxString(currentSmbiosString); + if (ParameterSetName == "SMBIOSObject") { smbiosSettings = SMBIOS ?? new ProxmoxVMSMBIOS(); + + // Preserve UUID if it exists and a new one wasn't specified + if (string.IsNullOrEmpty(smbiosSettings.UUID) && !string.IsNullOrEmpty(currentSmbios.UUID)) + { + smbiosSettings.UUID = currentSmbios.UUID; + WriteVerbose("Preserved existing UUID from VM configuration"); + } + } + else if (ParameterSetName == "Profile") + { + // Use manufacturer profile but preserve existing UUID + smbiosSettings = ProxmoxVMSMBIOSProfile.GetProfile(Profile, currentSmbios); + WriteVerbose($"Using SMBIOS profile: {Profile}"); } else { - // Get current settings first - string response = client.Get($"nodes/{Node}/qemu/{VMID}/config"); - var configData = JsonUtility.DeserializeResponse(response); - - string currentSmbiosString = configData.data.smbios; - smbiosSettings = string.IsNullOrEmpty(currentSmbiosString) - ? new ProxmoxVMSMBIOS() - : ProxmoxVMSMBIOS.FromProxmoxString(currentSmbiosString); + // Start with current settings + smbiosSettings = currentSmbios; // Update with provided values if (!string.IsNullOrEmpty(Manufacturer)) smbiosSettings.Manufacturer = Manufacturer; - + if (!string.IsNullOrEmpty(Product)) smbiosSettings.Product = Product; - + if (!string.IsNullOrEmpty(Version)) smbiosSettings.Version = Version; - + if (!string.IsNullOrEmpty(Serial)) smbiosSettings.Serial = Serial; - + if (!string.IsNullOrEmpty(Family)) smbiosSettings.Family = Family; - + if (!string.IsNullOrEmpty(UUID)) smbiosSettings.UUID = UUID; } // Convert to Proxmox format string smbiosString = smbiosSettings.ToProxmoxString(); - + if (string.IsNullOrEmpty(smbiosString)) { WriteWarning("No SMBIOS settings specified. No changes will be made."); diff --git a/PSProxmox/Models/ProxmoxVMSMBIOS.cs b/PSProxmox/Models/ProxmoxVMSMBIOS.cs index 364792a..e03498d 100644 --- a/PSProxmox/Models/ProxmoxVMSMBIOS.cs +++ b/PSProxmox/Models/ProxmoxVMSMBIOS.cs @@ -54,19 +54,19 @@ namespace PSProxmox.Models if (!string.IsNullOrEmpty(Manufacturer)) parts.Add($"manufacturer={Manufacturer}"); - + if (!string.IsNullOrEmpty(Product)) parts.Add($"product={Product}"); - + if (!string.IsNullOrEmpty(Version)) parts.Add($"version={Version}"); - + if (!string.IsNullOrEmpty(Serial)) parts.Add($"serial={Serial}"); - + if (!string.IsNullOrEmpty(Family)) parts.Add($"family={Family}"); - + if (!string.IsNullOrEmpty(UUID)) parts.Add($"uuid={UUID}"); @@ -83,6 +83,10 @@ namespace PSProxmox.Models if (string.IsNullOrEmpty(smbiosString)) return new ProxmoxVMSMBIOS(); + // If the string is just "1", it means SMBIOS is enabled but no specific values are set + if (smbiosString == "1") + return new ProxmoxVMSMBIOS(); + var result = new ProxmoxVMSMBIOS(); var parts = smbiosString.Split(','); diff --git a/PSProxmox/Models/ProxmoxVMSMBIOSProfile.cs b/PSProxmox/Models/ProxmoxVMSMBIOSProfile.cs index b01826d..1830d4f 100644 --- a/PSProxmox/Models/ProxmoxVMSMBIOSProfile.cs +++ b/PSProxmox/Models/ProxmoxVMSMBIOSProfile.cs @@ -20,6 +20,7 @@ namespace PSProxmox.Models "Dell", "HP", "Lenovo", + "Microsoft", "VMware", "HyperV", "VirtualBox", @@ -30,8 +31,9 @@ namespace PSProxmox.Models /// Gets a SMBIOS profile for the specified manufacturer. /// /// The manufacturer profile to use. + /// Optional existing SMBIOS settings to preserve values from. /// A ProxmoxVMSMBIOS object with the manufacturer profile settings. - public static ProxmoxVMSMBIOS GetProfile(string manufacturer) + public static ProxmoxVMSMBIOS GetProfile(string manufacturer, ProxmoxVMSMBIOS existingSmbios = null) { if (string.IsNullOrEmpty(manufacturer) || manufacturer.Equals("Random", StringComparison.OrdinalIgnoreCase)) { @@ -40,35 +42,69 @@ namespace PSProxmox.Models manufacturer = profiles[_random.Next(profiles.Length)]; } + ProxmoxVMSMBIOS result; switch (manufacturer.ToLowerInvariant()) { case "proxmox": - return GetProxmoxProfile(); + result = GetProxmoxProfile(); + break; case "dell": - return GetDellProfile(); + result = GetDellProfile(); + break; case "hp": - return GetHPProfile(); + result = GetHPProfile(); + break; case "lenovo": - return GetLenovoProfile(); + result = GetLenovoProfile(); + break; + case "microsoft": + result = GetMicrosoftProfile(); + break; case "vmware": - return GetVMwareProfile(); + result = GetVMwareProfile(); + break; case "hyperv": - return GetHyperVProfile(); + result = GetHyperVProfile(); + break; case "virtualbox": - return GetVirtualBoxProfile(); + result = GetVirtualBoxProfile(); + break; default: throw new ArgumentException($"Unknown manufacturer profile: {manufacturer}"); } + + // Preserve UUID if it exists in the original SMBIOS settings + if (existingSmbios != null && !string.IsNullOrEmpty(existingSmbios.UUID)) + { + result.UUID = existingSmbios.UUID; + } + + return result; } private static ProxmoxVMSMBIOS GetProxmoxProfile() { + var versions = new string[] + { + "6.2", + "6.4", + "7.0", + "7.1", + "7.2", + "7.3", + "7.4", + "8.0" + }; + + string version = versions[_random.Next(versions.Length)]; + string buildNumber = $"{_random.Next(1, 20)}"; + return new ProxmoxVMSMBIOS { Manufacturer = "Proxmox", - Product = $"Virtual Environment {_random.Next(1, 8)}.{_random.Next(0, 10)}", - Version = $"{_random.Next(1, 10)}.{_random.Next(0, 10)}", - Serial = GenerateRandomSerial(10), + Product = $"Virtual Environment {version}", + Version = $"{version}-{buildNumber}", + Serial = $"PVE-{GenerateRandomString(8, false)}", UUID = GenerateRandomUUID(), Family = "Virtual Machine" }; @@ -76,92 +112,379 @@ namespace PSProxmox.Models private static ProxmoxVMSMBIOS GetDellProfile() { - var models = new string[] + // Decide between server or workstation + bool isServer = _random.Next(2) == 0; + + string product; + string family; + string serial; + + if (isServer) { - "PowerEdge R640", - "PowerEdge R740", - "PowerEdge R750", - "PowerEdge R840", - "PowerEdge R940", - "PowerEdge T640" - }; + var serverModels = new string[] + { + "PowerEdge R640", + "PowerEdge R740", + "PowerEdge R750", + "PowerEdge R840", + "PowerEdge R940", + "PowerEdge T640", + "PowerEdge R440", + "PowerEdge R540", + "PowerEdge R650", + "PowerEdge R7525", + "PowerEdge C6420" + }; + + product = serverModels[_random.Next(serverModels.Length)]; + family = "PowerEdge"; + + // Dell server serial format: typically 7 characters, service tag style + serial = GenerateRandomString(7, true); + } + else + { + var workstationModels = new string[] + { + "Precision 5820 Tower", + "Precision 7920 Tower", + "Precision 7820 Tower", + "Precision 3650 Tower", + "Precision 3450 SFF", + "Precision 5820 Rack", + "OptiPlex 7090", + "OptiPlex 5090", + "Latitude 7420", + "Latitude 5420", + "XPS 15 9510" + }; + + product = workstationModels[_random.Next(workstationModels.Length)]; + family = product.StartsWith("Precision") ? "Precision" : + product.StartsWith("OptiPlex") ? "OptiPlex" : + product.StartsWith("Latitude") ? "Latitude" : "XPS"; + + // Dell workstation serial format + serial = GenerateRandomString(7, true); + } return new ProxmoxVMSMBIOS { Manufacturer = "Dell Inc.", - Product = models[_random.Next(models.Length)], + Product = product, Version = $"{_random.Next(1, 5)}.{_random.Next(0, 10)}", - Serial = $"{GenerateRandomString(5, true)}{_random.Next(10000, 99999)}", + Serial = serial, UUID = GenerateRandomUUID(), - Family = "PowerEdge" + Family = family }; } private static ProxmoxVMSMBIOS GetHPProfile() { - var models = new string[] + // Decide between server or workstation + bool isServer = _random.Next(2) == 0; + + string product; + string family; + string serial; + string manufacturer = _random.Next(2) == 0 ? "HP" : "Hewlett-Packard"; + + if (isServer) { - "ProLiant DL360 Gen10", - "ProLiant DL380 Gen10", - "ProLiant DL560 Gen10", - "ProLiant ML350 Gen10", - "ProLiant BL460c Gen10" - }; + var serverModels = new string[] + { + "ProLiant DL360 Gen10", + "ProLiant DL380 Gen10", + "ProLiant DL560 Gen10", + "ProLiant ML350 Gen10", + "ProLiant BL460c Gen10", + "ProLiant DL380 Gen11", + "ProLiant DL360 Gen11", + "ProLiant ML30 Gen10 Plus", + "ProLiant DL20 Gen10", + "ProLiant DL325 Gen10 Plus", + "ProLiant DL385 Gen10 Plus" + }; + + product = serverModels[_random.Next(serverModels.Length)]; + family = "ProLiant"; + + // HP server serial format + serial = $"USE{_random.Next(100000, 999999)}"; + } + else + { + var workstationModels = new string[] + { + "Z4 G4 Workstation", + "Z6 G4 Workstation", + "Z8 G4 Workstation", + "Z2 Tower G8 Workstation", + "Z2 Mini G5 Workstation", + "EliteDesk 800 G6", + "EliteBook 840 G8", + "EliteBook 850 G8", + "ZBook Fury 15 G8", + "ZBook Fury 17 G8", + "ZBook Studio G8" + }; + + product = workstationModels[_random.Next(workstationModels.Length)]; + + if (product.StartsWith("Z") && !product.StartsWith("ZBook")) + { + family = "Z Workstation"; + } + else if (product.StartsWith("ZBook")) + { + family = "ZBook"; + } + else if (product.StartsWith("EliteDesk")) + { + family = "EliteDesk"; + } + else + { + family = "EliteBook"; + } + + // HP workstation serial format - typically 10 characters for newer models + serial = $"CZ{_random.Next(10000000, 99999999)}"; + } return new ProxmoxVMSMBIOS { - Manufacturer = "HP", - Product = models[_random.Next(models.Length)], + Manufacturer = manufacturer, + Product = product, Version = $"U{_random.Next(10, 50)}", - Serial = $"USE{_random.Next(100000, 999999)}", + Serial = serial, UUID = GenerateRandomUUID(), - Family = "ProLiant" + Family = family }; } private static ProxmoxVMSMBIOS GetLenovoProfile() { - var models = new string[] + // Decide between server or workstation + bool isServer = _random.Next(2) == 0; + + string product; + string family; + string serial; + + if (isServer) { - "ThinkSystem SR650", - "ThinkSystem SR630", - "ThinkSystem SR850", - "ThinkSystem SR950", - "ThinkSystem ST550" - }; + var serverModels = new string[] + { + "ThinkSystem SR650", + "ThinkSystem SR630", + "ThinkSystem SR850", + "ThinkSystem SR950", + "ThinkSystem ST550", + "ThinkSystem SR670 V2", + "ThinkSystem SR650 V2", + "ThinkSystem SR630 V2", + "ThinkSystem SR860 V2", + "ThinkSystem SD530", + "ThinkSystem SR550" + }; + + product = serverModels[_random.Next(serverModels.Length)]; + family = "ThinkSystem"; + + // Lenovo server serial format + serial = $"{GenerateRandomString(4, true)}{GenerateRandomString(6, false)}"; + } + else + { + var workstationModels = new string[] + { + "ThinkStation P620", + "ThinkStation P520", + "ThinkStation P720", + "ThinkStation P920", + "ThinkStation P340 Tiny", + "ThinkStation P340 Tower", + "ThinkPad P15 Gen 2", + "ThinkPad P17 Gen 2", + "ThinkPad P1 Gen 4", + "ThinkPad X1 Carbon Gen 9", + "ThinkPad T14 Gen 2" + }; + + product = workstationModels[_random.Next(workstationModels.Length)]; + + if (product.StartsWith("ThinkStation")) + { + family = "ThinkStation"; + } + else + { + family = "ThinkPad"; + } + + // Lenovo workstation serial format + if (family == "ThinkStation") + { + // ThinkStation format + serial = $"S{GenerateRandomString(2, true)}{GenerateRandomString(7, false)}"; + } + else + { + // ThinkPad format + serial = $"R{_random.Next(0, 9)}{GenerateRandomString(2, true)}{GenerateRandomString(6, false)}"; + } + } return new ProxmoxVMSMBIOS { Manufacturer = "Lenovo", - Product = models[_random.Next(models.Length)], - Version = $"ThinkSystem {_random.Next(1, 5)}", - Serial = $"{GenerateRandomString(4, true)}{GenerateRandomString(6, false)}", + Product = product, + Version = family == "ThinkSystem" ? $"ThinkSystem {_random.Next(1, 5)}" : + family == "ThinkStation" ? $"ThinkStation {_random.Next(1, 5)}" : + $"ThinkPad {_random.Next(1, 5)}", + Serial = serial, UUID = GenerateRandomUUID(), - Family = "ThinkSystem" + Family = family }; } private static ProxmoxVMSMBIOS GetVMwareProfile() { + var products = new string[] + { + "VMware Virtual Platform", + "VMware7,1", + "VMware7,2", + "VMware8,1", + "VMware ESXi", + "VMware Workstation", + "VMware Fusion" + }; + + string product = products[_random.Next(products.Length)]; + string version; + + if (product.Contains("Platform")) + { + version = $"VMware-{_random.Next(1, 10)}.{_random.Next(0, 10)}"; + } + else if (product.Contains("ESXi")) + { + version = $"{_random.Next(6, 8)}.{_random.Next(0, 10)}.{_random.Next(0, 10)}"; + } + else if (product.Contains("Workstation")) + { + version = $"{_random.Next(15, 17)}.{_random.Next(0, 10)}.{_random.Next(0, 10)}"; + } + else if (product.Contains("Fusion")) + { + version = $"{_random.Next(11, 13)}.{_random.Next(0, 10)}.{_random.Next(0, 10)}"; + } + else + { + version = $"{_random.Next(1, 10)}.{_random.Next(0, 10)}"; + } + return new ProxmoxVMSMBIOS { Manufacturer = "VMware, Inc.", - Product = $"VMware Virtual Platform {_random.Next(1, 8)}", - Version = $"VMware-{_random.Next(1, 10)}.{_random.Next(0, 10)}", - Serial = GenerateRandomSerial(10), + Product = product, + Version = version, + Serial = $"VMware-{GenerateRandomString(8, true)}-{GenerateRandomString(4, true)}-{GenerateRandomString(4, true)}-{GenerateRandomString(4, true)}-{GenerateRandomString(12, true)}", UUID = GenerateRandomUUID(), Family = "Virtual Machine" }; } - private static ProxmoxVMSMBIOS GetHyperVProfile() + private static ProxmoxVMSMBIOS GetMicrosoftProfile() { + // Decide between Surface or Server + bool isSurface = _random.Next(2) == 0; + + string product; + string family; + string serial; + + if (isSurface) + { + var surfaceModels = new string[] + { + "Surface Pro 8", + "Surface Pro 7", + "Surface Pro X", + "Surface Laptop 4", + "Surface Laptop Studio", + "Surface Book 3", + "Surface Go 3", + "Surface Studio 2", + "Surface Laptop Go", + "Surface Duo 2" + }; + + product = surfaceModels[_random.Next(surfaceModels.Length)]; + family = product.Contains("Laptop") ? "Surface Laptop" : + product.Contains("Book") ? "Surface Book" : + product.Contains("Studio") ? "Surface Studio" : + product.Contains("Go") ? "Surface Go" : + product.Contains("Duo") ? "Surface Duo" : "Surface Pro"; + + // Surface serial format + serial = $"{GenerateRandomString(12, false)}"; + } + else + { + var serverModels = new string[] + { + "Azure Stack HCI", + "Windows Server 2022", + "Windows Server 2019", + "Windows Server 2016", + "SQL Server 2022", + "SQL Server 2019" + }; + + product = serverModels[_random.Next(serverModels.Length)]; + family = product.Contains("Azure") ? "Azure Stack" : + product.Contains("SQL") ? "SQL Server" : "Windows Server"; + + // Microsoft server serial format + serial = $"MS-{GenerateRandomString(8, false)}"; + } + return new ProxmoxVMSMBIOS { Manufacturer = "Microsoft Corporation", - Product = $"Hyper-V {_random.Next(2012, 2023)}", + Product = product, Version = $"{_random.Next(1, 10)}.{_random.Next(0, 10)}", - Serial = $"MS-{GenerateRandomString(8, false)}", + Serial = serial, + UUID = GenerateRandomUUID(), + Family = family + }; + } + + private static ProxmoxVMSMBIOS GetHyperVProfile() + { + var versions = new string[] + { + "2016", + "2019", + "2022", + "10", + "11" + }; + + string version = versions[_random.Next(versions.Length)]; + string product = version == "10" || version == "11" ? + $"Windows {version} Hyper-V" : + $"Hyper-V Server {version}"; + + return new ProxmoxVMSMBIOS + { + Manufacturer = "Microsoft Corporation", + Product = product, + Version = $"{_random.Next(1, 10)}.{_random.Next(0, 10)}", + Serial = $"VM{_random.Next(1000000, 9999999)}", UUID = GenerateRandomUUID(), Family = "Virtual Machine" }; @@ -169,12 +492,24 @@ namespace PSProxmox.Models private static ProxmoxVMSMBIOS GetVirtualBoxProfile() { + var versions = new string[] + { + "5.2", + "6.0", + "6.1", + "7.0", + "7.1" + }; + + string version = versions[_random.Next(versions.Length)]; + string buildNumber = $"{_random.Next(1, 50)}"; + return new ProxmoxVMSMBIOS { Manufacturer = "Oracle Corporation", - Product = $"VirtualBox {_random.Next(5, 8)}.{_random.Next(0, 10)}", - Version = $"{_random.Next(1, 10)}.{_random.Next(0, 10)}", - Serial = $"VB-{GenerateRandomString(8, false)}", + Product = $"VirtualBox {version}", + Version = $"{version}.{buildNumber}", + Serial = $"0", // VirtualBox typically uses "0" as the serial number UUID = GenerateRandomUUID(), Family = "Virtual Machine" }; @@ -194,7 +529,7 @@ namespace PSProxmox.Models const string digits = "0123456789"; string chars = uppercase ? upperChars : lowerChars + digits; - + return new string(Enumerable.Repeat(chars, length) .Select(s => s[_random.Next(s.Length)]).ToArray()); }