mirror of
https://github.com/rbalsleyMSFT/FFU.git
synced 2026-06-14 02:09:35 -06:00
Improves driver mapping with vendor-specific identifiers
Implements manufacturer-specific device identification for automatic driver selection using System SKU, Machine Type, and other vendor identifiers instead of relying solely on model name pattern matching. Adds normalized manufacturer detection to handle vendor name variations consistently across Dell, HP, Lenovo, and Microsoft Surface devices. Extracts comprehensive system information from WMI including baseboard details, BIOS metadata, and firmware versions to support accurate device identification and troubleshooting. Refactors system information gathering into reusable functions that separate data collection from display logic, enabling the driver mapping feature to leverage device identifiers. Enhances logging by capturing vendor-specific identifiers while hiding internal matching fields from user-facing output to reduce confusion. Fixes minor log message wording for clarity when driver installation encounters expected failures.
This commit is contained in:
@@ -2882,7 +2882,7 @@ function New-PEMedia {
|
|||||||
Add-WindowsDriver -Path "$WinPEFFUPath\Mount" -Driver $PEDriversFolder -Recurse -ErrorAction SilentlyContinue -WarningAction SilentlyContinue | Out-null
|
Add-WindowsDriver -Path "$WinPEFFUPath\Mount" -Driver $PEDriversFolder -Recurse -ErrorAction SilentlyContinue -WarningAction SilentlyContinue | Out-null
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
WriteLog 'Some drivers failed to be added to the FFU. This can be expected. Continuing.'
|
WriteLog 'Some drivers failed to be added. This can be expected. Continuing.'
|
||||||
}
|
}
|
||||||
WriteLog "Adding drivers complete"
|
WriteLog "Adding drivers complete"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,47 +146,314 @@ function Write-SectionHeader($Title) {
|
|||||||
Write-Host ('-' * $width) -ForegroundColor Yellow
|
Write-Host ('-' * $width) -ForegroundColor Yellow
|
||||||
}
|
}
|
||||||
|
|
||||||
function Write-SystemInformation($hardDrive) {
|
function Get-NormalizedManufacturer {
|
||||||
# Gather all information first
|
param(
|
||||||
$systemManufacturer = (Get-CimInstance -Class Win32_ComputerSystem).Manufacturer
|
[string]$Manufacturer
|
||||||
|
)
|
||||||
|
|
||||||
|
if ([string]::IsNullOrWhiteSpace($Manufacturer)) {
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
|
||||||
|
$normalized = $Manufacturer.Trim().ToUpperInvariant()
|
||||||
|
if ($normalized -like '*DELL*') {
|
||||||
|
return 'Dell'
|
||||||
|
}
|
||||||
|
elseif ($normalized -like '*HP*' -or $normalized -like '*HEWLETT*') {
|
||||||
|
return 'HP'
|
||||||
|
}
|
||||||
|
elseif ($normalized -like '*LENOVO*') {
|
||||||
|
return 'Lenovo'
|
||||||
|
}
|
||||||
|
elseif ($normalized -like '*MICROSOFT*' -or $normalized -like '*SURFACE*') {
|
||||||
|
return 'Microsoft'
|
||||||
|
}
|
||||||
|
|
||||||
|
return $Manufacturer.Trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-SystemInformation {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[pscustomobject]$HardDrive
|
||||||
|
)
|
||||||
|
|
||||||
|
$computerSystem = Get-CimInstance -Class Win32_ComputerSystem
|
||||||
|
$systemManufacturer = $computerSystem.Manufacturer
|
||||||
$systemModel = if ($systemManufacturer -like '*LENOVO*') {
|
$systemModel = if ($systemManufacturer -like '*LENOVO*') {
|
||||||
(Get-CimInstance -Class Win32_ComputerSystemProduct).Version
|
(Get-CimInstance -Class Win32_ComputerSystemProduct).Version
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
(Get-CimInstance -Class Win32_ComputerSystem).Model
|
$computerSystem.Model
|
||||||
|
}
|
||||||
|
if ([string]::IsNullOrWhiteSpace($systemModel)) {
|
||||||
|
$systemModel = $computerSystem.Model
|
||||||
}
|
}
|
||||||
$biosInfo = Get-CimInstance -Class Win32_Bios
|
|
||||||
$processor = (Get-CimInstance -Class Win32_Processor).Name
|
|
||||||
$totalMemory = (Get-CimInstance -Class Win32_PhysicalMemory | Measure-Object -Property Capacity -Sum).Sum
|
|
||||||
$totalMemoryGB = [math]::Round($totalMemory / 1GB, 2)
|
|
||||||
$diskSizeGB = [math]::Round($hardDrive.DiskSize / 1GB, 2)
|
|
||||||
|
|
||||||
# Create a custom object for structured data
|
$biosInfo = Get-CimInstance -Class Win32_Bios
|
||||||
$sysInfoObject = [PSCustomObject]@{
|
$processorInfo = Get-CimInstance -Class Win32_Processor | Select-Object -First 1
|
||||||
"Manufacturer" = $systemManufacturer
|
$processor = if ($processorInfo) { $processorInfo.Name } else { 'Unknown' }
|
||||||
"Model" = $systemModel
|
$totalMemory = (Get-CimInstance -Class Win32_PhysicalMemory | Measure-Object -Property Capacity -Sum).Sum
|
||||||
"BIOS Version" = $biosInfo.Version
|
if ($null -eq $totalMemory) {
|
||||||
|
$totalMemory = 0
|
||||||
|
}
|
||||||
|
$totalMemoryGB = [math]::Round(($totalMemory / 1GB), 2)
|
||||||
|
$diskSizeGB = [math]::Round(($HardDrive.DiskSize / 1GB), 2)
|
||||||
|
|
||||||
|
$normalizedManufacturer = Get-NormalizedManufacturer -Manufacturer $systemManufacturer
|
||||||
|
$msSystemInformation = Get-CimInstance -Namespace 'root\WMI' -Class MS_SystemInformation -ErrorAction SilentlyContinue
|
||||||
|
$systemSkuValue = $null
|
||||||
|
$fallbackSkuValue = $null
|
||||||
|
$machineTypeValue = $null
|
||||||
|
$deviceIdentifierLabel = 'System ID'
|
||||||
|
$deviceIdentifierValue = $null
|
||||||
|
|
||||||
|
switch ($normalizedManufacturer) {
|
||||||
|
'Dell' {
|
||||||
|
if ($msSystemInformation -and $msSystemInformation.SystemSku) {
|
||||||
|
$systemSkuValue = $msSystemInformation.SystemSku.Trim()
|
||||||
|
}
|
||||||
|
$oemStringArray = $computerSystem | Select-Object -ExpandProperty OEMStringArray -ErrorAction SilentlyContinue
|
||||||
|
if ($oemStringArray) {
|
||||||
|
$joinedOemString = ($oemStringArray -join ' ')
|
||||||
|
$fallbackMatches = [regex]::Matches($joinedOemString, '\[\S*]')
|
||||||
|
if ($fallbackMatches.Count -gt 0) {
|
||||||
|
$fallbackSkuValue = $fallbackMatches[0].Value.TrimStart('[').TrimEnd(']')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
'HP' {
|
||||||
|
if ($msSystemInformation -and $msSystemInformation.BaseBoardProduct) {
|
||||||
|
$systemSkuValue = $msSystemInformation.BaseBoardProduct.Trim()
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
'Lenovo' {
|
||||||
|
$modelValue = $computerSystem.Model
|
||||||
|
if (-not [string]::IsNullOrWhiteSpace($modelValue) -and $modelValue.Length -ge 4) {
|
||||||
|
$machineTypeValue = $modelValue.Substring(0, 4).Trim()
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
default {
|
||||||
|
if ($msSystemInformation -and $msSystemInformation.SystemSku) {
|
||||||
|
$systemSkuValue = $msSystemInformation.SystemSku.Trim()
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$normalizedSystemSku = if ($systemSkuValue) { $systemSkuValue.Trim().ToUpperInvariant() } else { $null }
|
||||||
|
$normalizedFallbackSku = if ($fallbackSkuValue) { $fallbackSkuValue.Trim().ToUpperInvariant() } else { $null }
|
||||||
|
$normalizedMachineType = if ($machineTypeValue) { $machineTypeValue.Trim().ToUpperInvariant() } else { $null }
|
||||||
|
|
||||||
|
switch ($normalizedManufacturer) {
|
||||||
|
'Lenovo' {
|
||||||
|
$deviceIdentifierLabel = 'Machine Type'
|
||||||
|
if ($normalizedMachineType) {
|
||||||
|
$deviceIdentifierValue = $normalizedMachineType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'Dell' {
|
||||||
|
if ($normalizedFallbackSku) {
|
||||||
|
$deviceIdentifierValue = $normalizedFallbackSku
|
||||||
|
}
|
||||||
|
elseif ($normalizedSystemSku) {
|
||||||
|
$deviceIdentifierValue = $normalizedSystemSku
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'HP' {
|
||||||
|
if ($normalizedSystemSku) {
|
||||||
|
$deviceIdentifierValue = $normalizedSystemSku
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default {
|
||||||
|
if ($normalizedSystemSku) {
|
||||||
|
$deviceIdentifierValue = $normalizedSystemSku
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$baseBoardManufacturer = if ($msSystemInformation -and $msSystemInformation.BaseBoardManufacturer) { $msSystemInformation.BaseBoardManufacturer.Trim() } else { $null }
|
||||||
|
$baseBoardProduct = if ($msSystemInformation -and $msSystemInformation.BaseBoardProduct) { $msSystemInformation.BaseBoardProduct.Trim() } else { $null }
|
||||||
|
$baseBoardVersion = if ($msSystemInformation -and $msSystemInformation.BaseBoardVersion) { $msSystemInformation.BaseBoardVersion.Trim() } else { $null }
|
||||||
|
$biosMajorRelease = if ($msSystemInformation -and $null -ne $msSystemInformation.BiosMajorRelease) { [string]$msSystemInformation.BiosMajorRelease } else { $null }
|
||||||
|
$biosMinorRelease = if ($msSystemInformation -and $null -ne $msSystemInformation.BiosMinorRelease) { [string]$msSystemInformation.BiosMinorRelease } else { $null }
|
||||||
|
$biosReleaseDate = $null
|
||||||
|
if ($msSystemInformation -and $msSystemInformation.BiosReleaseDate) {
|
||||||
|
try {
|
||||||
|
$biosReleaseDate = [System.Management.ManagementDateTimeConverter]::ToDateTime($msSystemInformation.BiosReleaseDate).ToString('yyyy-MM-dd HH:mm:ss')
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
$biosReleaseDate = $msSystemInformation.BiosReleaseDate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$biosVendor = if ($msSystemInformation -and $msSystemInformation.BiosVendor) { $msSystemInformation.BiosVendor.Trim() } else { $null }
|
||||||
|
$biosVersion = if ($msSystemInformation -and $msSystemInformation.BiosVersion) { $msSystemInformation.BiosVersion.Trim() } else { $null }
|
||||||
|
$ecFirmwareMajorRelease = if ($msSystemInformation -and $null -ne $msSystemInformation.ECFirmwareMajorRelease) { [string]$msSystemInformation.ECFirmwareMajorRelease } else { $null }
|
||||||
|
$ecFirmwareMinorRelease = if ($msSystemInformation -and $null -ne $msSystemInformation.ECFirmwareMinorRelease) { [string]$msSystemInformation.ECFirmwareMinorRelease } else { $null }
|
||||||
|
|
||||||
|
$normalizedModel = ConvertTo-ComparableModelName -Text $systemModel
|
||||||
|
$sysInfoData = [ordered]@{
|
||||||
|
"Manufacturer" = if ($normalizedManufacturer) { $normalizedManufacturer } else { $systemManufacturer }
|
||||||
|
"Model" = if ($normalizedModel) { $normalizedModel } else { $systemModel }
|
||||||
"Serial Number" = $biosInfo.SerialNumber
|
"Serial Number" = $biosInfo.SerialNumber
|
||||||
"Processor" = $processor
|
"Processor" = $processor
|
||||||
"Memory" = "$($totalMemoryGB) GB"
|
"Memory" = "{0} GB" -f $totalMemoryGB
|
||||||
"Disk Size" = "$($diskSizeGB) GB"
|
"Disk Size" = "{0} GB" -f $diskSizeGB
|
||||||
"Logical Sector Size" = "$($hardDrive.BytesPerSector) Bytes"
|
"Logical Sector Size" = "$($HardDrive.BytesPerSector) Bytes"
|
||||||
|
"BaseBoardManufacturer" = if ($baseBoardManufacturer) { $baseBoardManufacturer } else { 'Not Detected' }
|
||||||
|
"BaseBoardProduct" = if ($baseBoardProduct) { $baseBoardProduct } else { 'Not Detected' }
|
||||||
|
"BaseBoardVersion" = if ($baseBoardVersion) { $baseBoardVersion } else { 'Not Detected' }
|
||||||
|
"BiosMajorRelease" = if ($biosMajorRelease) { $biosMajorRelease } else { 'Not Detected' }
|
||||||
|
"BiosMinorRelease" = if ($biosMinorRelease) { $biosMinorRelease } else { 'Not Detected' }
|
||||||
|
"BiosReleaseDate" = if ($biosReleaseDate) { $biosReleaseDate } else { 'Not Detected' }
|
||||||
|
"BiosVendor" = if ($biosVendor) { $biosVendor } else { 'Not Detected' }
|
||||||
|
"BiosVersion" = if ($biosVersion) { $biosVersion } else { 'Not Detected' }
|
||||||
|
"ECFirmwareMajorRelease" = if ($ecFirmwareMajorRelease) { $ecFirmwareMajorRelease } else { 'Not Detected' }
|
||||||
|
"ECFirmwareMinorRelease" = if ($ecFirmwareMinorRelease) { $ecFirmwareMinorRelease } else { 'Not Detected' }
|
||||||
|
"SystemSkuNormalized" = $normalizedSystemSku
|
||||||
|
"FallbackSkuNormalized" = $normalizedFallbackSku
|
||||||
|
"MachineTypeNormalized" = $normalizedMachineType
|
||||||
}
|
}
|
||||||
|
$sysInfoData[$deviceIdentifierLabel] = if ($deviceIdentifierValue) { $deviceIdentifierValue } else { 'Not Detected' }
|
||||||
|
|
||||||
# Log information line-by-line
|
return [PSCustomObject]$sysInfoData
|
||||||
WriteLog "--- System Information ---"
|
}
|
||||||
$sysInfoObject.psobject.Properties | ForEach-Object {
|
|
||||||
WriteLog "$($_.Name): $($_.Value)"
|
function Write-SystemInformation {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[pscustomobject]$SystemInformation
|
||||||
|
)
|
||||||
|
|
||||||
|
$hiddenProperties = @('SystemSkuNormalized', 'FallbackSkuNormalized', 'MachineTypeNormalized')
|
||||||
|
|
||||||
|
WriteLog '--- System Information ---'
|
||||||
|
foreach ($property in $SystemInformation.psobject.Properties) {
|
||||||
|
if ($hiddenProperties -contains $property.Name) {
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
WriteLog "--- End System Information ---"
|
WriteLog "$($property.Name): $($property.Value)"
|
||||||
|
}
|
||||||
|
WriteLog '--- End System Information ---'
|
||||||
|
|
||||||
# Console output
|
|
||||||
Write-SectionHeader -Title 'System Information'
|
Write-SectionHeader -Title 'System Information'
|
||||||
|
$displayData = [ordered]@{}
|
||||||
# Format for console using Format-List for better readability
|
foreach ($property in $SystemInformation.psobject.Properties) {
|
||||||
$consoleOutput = $sysInfoObject | Format-List | Out-String
|
if ($hiddenProperties -contains $property.Name) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
$displayData[$property.Name] = $property.Value
|
||||||
|
}
|
||||||
|
$consoleOutput = ([pscustomobject]$displayData | Format-List | Out-String)
|
||||||
Write-Host $consoleOutput.Trim()
|
Write-Host $consoleOutput.Trim()
|
||||||
Write-Host # Adds a blank line for spacing after the block
|
Write-Host
|
||||||
|
}
|
||||||
|
|
||||||
|
function Find-DriverMappingRule {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[pscustomobject]$SystemInformation,
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[object[]]$DriverMappings
|
||||||
|
)
|
||||||
|
|
||||||
|
$normalizedManufacturer = Get-NormalizedManufacturer -Manufacturer $SystemInformation.Manufacturer
|
||||||
|
if ([string]::IsNullOrWhiteSpace($normalizedManufacturer)) {
|
||||||
|
WriteLog 'DriverMapping: Unable to determine manufacturer for automatic matching.'
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
|
||||||
|
$driverMappingsArray = @()
|
||||||
|
foreach ($entry in @($DriverMappings)) {
|
||||||
|
if ($null -ne $entry) {
|
||||||
|
$driverMappingsArray += $entry
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($driverMappingsArray.Count -eq 0) {
|
||||||
|
WriteLog 'DriverMapping: Mapping file contained no entries.'
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
|
||||||
|
$rulesForMake = @($driverMappingsArray | Where-Object {
|
||||||
|
$entryManufacturer = Get-NormalizedManufacturer -Manufacturer $_.Manufacturer
|
||||||
|
$entryManufacturer -eq $normalizedManufacturer
|
||||||
|
})
|
||||||
|
if ($rulesForMake.Count -eq 0) {
|
||||||
|
WriteLog "DriverMapping: No entries found for manufacturer '$normalizedManufacturer'."
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
|
||||||
|
$systemSkuNormalized = if ($SystemInformation.PSObject.Properties['SystemSkuNormalized']) { $SystemInformation.SystemSkuNormalized } else { $null }
|
||||||
|
$fallbackSkuNormalized = if ($SystemInformation.PSObject.Properties['FallbackSkuNormalized']) { $SystemInformation.FallbackSkuNormalized } else { $null }
|
||||||
|
$machineTypeNormalized = if ($SystemInformation.PSObject.Properties['MachineTypeNormalized']) { $SystemInformation.MachineTypeNormalized } else { $null }
|
||||||
|
$normalizedModel = $SystemInformation.Model
|
||||||
|
if ([string]::IsNullOrWhiteSpace($normalizedModel)) {
|
||||||
|
$normalizedModel = ConvertTo-ComparableModelName -Text $SystemInformation.Model
|
||||||
|
}
|
||||||
|
switch ($normalizedManufacturer) {
|
||||||
|
'Dell' {
|
||||||
|
if (-not [string]::IsNullOrWhiteSpace($systemSkuNormalized)) {
|
||||||
|
$match = $rulesForMake | Where-Object { $_.PSObject.Properties['SystemId'] -and $_.SystemId.Trim().ToUpperInvariant() -eq $systemSkuNormalized } | Select-Object -First 1
|
||||||
|
if ($match) {
|
||||||
|
WriteLog "DriverMapping: Dell SystemId '$systemSkuNormalized' matched '$($match.Model)'."
|
||||||
|
return $match
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (-not [string]::IsNullOrWhiteSpace($fallbackSkuNormalized)) {
|
||||||
|
$match = $rulesForMake | Where-Object { $_.PSObject.Properties['SystemId'] -and $_.SystemId.Trim().ToUpperInvariant() -eq $fallbackSkuNormalized } | Select-Object -First 1
|
||||||
|
if ($match) {
|
||||||
|
WriteLog "DriverMapping: Dell fallback SKU '$fallbackSkuNormalized' matched '$($match.Model)'."
|
||||||
|
return $match
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WriteLog 'DriverMapping: Dell identifiers did not match any entries.'
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
'HP' {
|
||||||
|
if (-not [string]::IsNullOrWhiteSpace($systemSkuNormalized)) {
|
||||||
|
$match = $rulesForMake | Where-Object { $_.PSObject.Properties['SystemId'] -and $_.SystemId.Trim().ToUpperInvariant() -eq $systemSkuNormalized } | Select-Object -First 1
|
||||||
|
if ($match) {
|
||||||
|
WriteLog "DriverMapping: HP SystemId '$systemSkuNormalized' matched '$($match.Model)'."
|
||||||
|
return $match
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WriteLog 'DriverMapping: HP SystemId not detected or not present in mapping.'
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
'Lenovo' {
|
||||||
|
if (-not [string]::IsNullOrWhiteSpace($machineTypeNormalized)) {
|
||||||
|
$match = $rulesForMake | Where-Object { $_.PSObject.Properties['MachineType'] -and $_.MachineType.Trim().ToUpperInvariant() -eq $machineTypeNormalized } | Select-Object -First 1
|
||||||
|
if ($match) {
|
||||||
|
WriteLog "DriverMapping: Lenovo MachineType '$machineTypeNormalized' matched '$($match.Model)'."
|
||||||
|
return $match
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WriteLog 'DriverMapping: Lenovo MachineType not detected or not present in mapping.'
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
'Microsoft' {
|
||||||
|
if ($SystemInformation.Model -notmatch 'Surface') {
|
||||||
|
WriteLog "DriverMapping: Manufacturer Microsoft detected but model '$($SystemInformation.Model)' is not a Surface device."
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
foreach ($rule in $rulesForMake) {
|
||||||
|
$ruleModelNorm = ConvertTo-ComparableModelName -Text $rule.Model
|
||||||
|
if (-not [string]::IsNullOrWhiteSpace($ruleModelNorm) -and $ruleModelNorm -eq $normalizedModel) {
|
||||||
|
WriteLog "DriverMapping: Surface model '$normalizedModel' matched '$($rule.Model)'."
|
||||||
|
return $rule
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WriteLog 'DriverMapping: No Surface model match found in mapping.'
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
default {
|
||||||
|
WriteLog "DriverMapping: Automatic matching not implemented for manufacturer '$normalizedManufacturer'."
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Stop-Script {
|
function Stop-Script {
|
||||||
@@ -269,8 +536,9 @@ WriteLog "Physical DeviceID is $PhysicalDeviceID"
|
|||||||
$DiskID = $PhysicalDeviceID.substring($PhysicalDeviceID.length - 1, 1)
|
$DiskID = $PhysicalDeviceID.substring($PhysicalDeviceID.length - 1, 1)
|
||||||
WriteLog "DiskID is $DiskID"
|
WriteLog "DiskID is $DiskID"
|
||||||
|
|
||||||
# Write System Information to console and log
|
# Gather and write system information
|
||||||
Write-SystemInformation -hardDrive $hardDrive
|
$sysInfoObject = Get-SystemInformation -HardDrive $hardDrive
|
||||||
|
Write-SystemInformation -SystemInformation $sysInfoObject
|
||||||
|
|
||||||
#Find FFU Files
|
#Find FFU Files
|
||||||
Write-SectionHeader 'FFU File Selection'
|
Write-SectionHeader 'FFU File Selection'
|
||||||
@@ -363,8 +631,9 @@ If (Test-Path -Path $UnattendComputerNamePath) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#Ask for device name if unattend exists
|
#Ask for device name if unattend exists
|
||||||
Write-SectionHeader 'Device Name Selection'
|
If ($Unattend -or $UnattendPrefix -or $UnattendComputerName) {
|
||||||
if ($Unattend -and $UnattendPrefix) {
|
Write-SectionHeader 'Device Name Selection'
|
||||||
|
if ($Unattend -and $UnattendPrefix) {
|
||||||
Writelog 'Unattend file found with prefixes.txt. Getting prefixes.'
|
Writelog 'Unattend file found with prefixes.txt. Getting prefixes.'
|
||||||
$UnattendPrefixes = @(Get-content $UnattendPrefixFile)
|
$UnattendPrefixes = @(Get-content $UnattendPrefixFile)
|
||||||
$UnattendPrefixCount = $UnattendPrefixes.Count
|
$UnattendPrefixCount = $UnattendPrefixes.Count
|
||||||
@@ -409,8 +678,8 @@ if ($Unattend -and $UnattendPrefix) {
|
|||||||
$computername = Set-Computername($computername)
|
$computername = Set-Computername($computername)
|
||||||
Writelog "Computer name will be set to $computername"
|
Writelog "Computer name will be set to $computername"
|
||||||
Write-Host "Computer name will be set to $computername"
|
Write-Host "Computer name will be set to $computername"
|
||||||
}
|
}
|
||||||
elseif ($Unattend -and $UnattendComputerName) {
|
elseif ($Unattend -and $UnattendComputerName) {
|
||||||
Writelog 'Unattend file found with SerialComputerNames.csv. Getting name for current computer.'
|
Writelog 'Unattend file found with SerialComputerNames.csv. Getting name for current computer.'
|
||||||
$SerialComputerNames = Import-Csv -Path $UnattendComputerNameFile.FullName -Delimiter ","
|
$SerialComputerNames = Import-Csv -Path $UnattendComputerNameFile.FullName -Delimiter ","
|
||||||
|
|
||||||
@@ -431,14 +700,18 @@ elseif ($Unattend -and $UnattendComputerName) {
|
|||||||
Writelog "Computer name will be set to $computername"
|
Writelog "Computer name will be set to $computername"
|
||||||
Write-Host "Computer name will be set to $computername"
|
Write-Host "Computer name will be set to $computername"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elseif ($Unattend) {
|
elseif ($Unattend) {
|
||||||
Writelog 'Unattend file found with no prefixes.txt, asking for name'
|
Writelog 'Unattend file found with no prefixes.txt, asking for name'
|
||||||
Write-Host 'Unattend file found but no prefixes.txt. Please enter a device name.'
|
Write-Host 'Unattend file found but no prefixes.txt. Please enter a device name.'
|
||||||
[string]$computername = Read-Host 'Enter device name'
|
[string]$computername = Read-Host 'Enter device name'
|
||||||
$computername = Set-Computername($computername)
|
$computername = Set-Computername($computername)
|
||||||
Writelog "Computer name will be set to $computername"
|
Writelog "Computer name will be set to $computername"
|
||||||
Write-Host "Computer name will be set to $computername"
|
Write-Host "Computer name will be set to $computername"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WriteLog 'Device naming assets detected without unattend.xml. Skipping device naming prompts.'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
WriteLog 'No unattend folder found. Device name will be set via PPKG, AP JSON, or default OS name.'
|
WriteLog 'No unattend folder found. Device name will be set via PPKG, AP JSON, or default OS name.'
|
||||||
@@ -559,48 +832,34 @@ if (Test-Path -Path $driverMappingPath -PathType Leaf) {
|
|||||||
WriteLog "DriverMapping.json found at $driverMappingPath. Attempting automatic driver selection."
|
WriteLog "DriverMapping.json found at $driverMappingPath. Attempting automatic driver selection."
|
||||||
Write-Host "DriverMapping.json found. Attempting automatic driver selection."
|
Write-Host "DriverMapping.json found. Attempting automatic driver selection."
|
||||||
try {
|
try {
|
||||||
# Get system information
|
$driverMappings = Get-Content -Path $driverMappingPath | Out-String | ConvertFrom-Json -ErrorAction Stop
|
||||||
$systemManufacturer = (Get-CimInstance -Class Win32_ComputerSystem).Manufacturer
|
$driverMappings = @($driverMappings) | Where-Object { $null -ne $_ }
|
||||||
# Lenovo uses a different property for the model name
|
if ($driverMappings.Count -eq 0) {
|
||||||
$systemModel = if ($systemManufacturer -like '*LENOVO*') {
|
throw "DriverMapping.json does not contain any entries."
|
||||||
(Get-CimInstance -Class Win32_ComputerSystemProduct).Version
|
}
|
||||||
|
|
||||||
|
if ($null -eq $sysInfoObject) {
|
||||||
|
$sysInfoObject = Get-SystemInformation -HardDrive $hardDrive
|
||||||
|
}
|
||||||
|
|
||||||
|
$identifierLabelForLog = $null
|
||||||
|
$identifierValueForLog = $null
|
||||||
|
if ($sysInfoObject.PSObject.Properties['Machine Type'] -and -not [string]::IsNullOrWhiteSpace($sysInfoObject.'Machine Type')) {
|
||||||
|
$identifierLabelForLog = 'Machine Type'
|
||||||
|
$identifierValueForLog = $sysInfoObject.'Machine Type'
|
||||||
|
}
|
||||||
|
elseif ($sysInfoObject.PSObject.Properties['System ID'] -and -not [string]::IsNullOrWhiteSpace($sysInfoObject.'System ID')) {
|
||||||
|
$identifierLabelForLog = 'System ID'
|
||||||
|
$identifierValueForLog = $sysInfoObject.'System ID'
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
(Get-CimInstance -Class Win32_ComputerSystem).Model
|
$identifierLabelForLog = 'System ID'
|
||||||
|
$identifierValueForLog = 'Not Detected'
|
||||||
}
|
}
|
||||||
WriteLog "Detected System: Manufacturer='$systemManufacturer', Model='$systemModel'"
|
WriteLog ("Detected System: Manufacturer='{0}', Model='{1}', {2}='{3}'" -f $sysInfoObject.Manufacturer, $sysInfoObject.Model, $identifierLabelForLog, $identifierValueForLog)
|
||||||
|
Write-Host ("Detected System: Manufacturer='{0}', Model='{1}'" -f $sysInfoObject.Manufacturer, $sysInfoObject.Model)
|
||||||
|
|
||||||
# Load and parse the mapping file, ensuring it's always an array
|
$matchedRule = Find-DriverMappingRule -SystemInformation $sysInfoObject -DriverMappings $driverMappings
|
||||||
$driverMappings = Get-Content -Path $driverMappingPath | Out-String | ConvertFrom-Json -ErrorAction SilentlyContinue
|
|
||||||
|
|
||||||
# Find all matching rules and select the most specific one
|
|
||||||
$matchingRules = @()
|
|
||||||
# Normalize system model once outside the loop
|
|
||||||
$systemModelNorm = ConvertTo-ComparableModelName -Text $systemModel
|
|
||||||
foreach ($rule in $driverMappings) {
|
|
||||||
# Use -like for wildcard matching.
|
|
||||||
# Prepare normalized rule model string
|
|
||||||
$ruleModelNorm = ConvertTo-ComparableModelName -Text $rule.Model
|
|
||||||
# This checks if the system model starts with the rule model, or vice-versa, for flexibility.
|
|
||||||
if ($systemManufacturer -like "$($rule.Manufacturer)*" -and ($systemModelNorm -like "$($ruleModelNorm)*" -or $ruleModelNorm -like "$systemModelNorm*")) {
|
|
||||||
WriteLog "Match found: Manufacturer='$($rule.Manufacturer)', Model='$($rule.Model)' (Normalized: System='$systemModelNorm', Rule='$ruleModelNorm')"
|
|
||||||
$matchingRules += $rule
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Select the best match
|
|
||||||
$matchedRule = $null
|
|
||||||
if ($matchingRules.Count -gt 0) {
|
|
||||||
WriteLog "Found $($matchingRules.Count) potential driver mapping rule(s)."
|
|
||||||
Write-Host "Found $($matchingRules.Count) potential driver mapping rule(s)."
|
|
||||||
foreach ($rule in $matchingRules) {
|
|
||||||
WriteLog " - Potential Match: Manufacturer='$($rule.Manufacturer)', Model='$($rule.Model)', Path='$($rule.DriverPath)'"
|
|
||||||
Write-Host " - Potential Match: Manufacturer='$($rule.Manufacturer)', Model='$($rule.Model)', Path='$($rule.DriverPath)'"
|
|
||||||
|
|
||||||
}
|
|
||||||
# Sort by model name length, descending, to find the most specific match
|
|
||||||
$matchedRule = $matchingRules | Sort-Object -Property @{Expression = { $_.Model.Length } } -Descending | Select-Object -First 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($null -ne $matchedRule) {
|
if ($null -ne $matchedRule) {
|
||||||
WriteLog "Automatic match found: Manufacturer='$($matchedRule.Manufacturer)', Model='$($matchedRule.Model)'"
|
WriteLog "Automatic match found: Manufacturer='$($matchedRule.Manufacturer)', Model='$($matchedRule.Model)'"
|
||||||
@@ -609,7 +868,6 @@ if (Test-Path -Path $driverMappingPath -PathType Leaf) {
|
|||||||
|
|
||||||
if (Test-Path -Path $potentialDriverPath) {
|
if (Test-Path -Path $potentialDriverPath) {
|
||||||
$DriverSourcePath = $potentialDriverPath
|
$DriverSourcePath = $potentialDriverPath
|
||||||
# Determine if it's a WIM or a Folder
|
|
||||||
if ($DriverSourcePath -like '*.wim') {
|
if ($DriverSourcePath -like '*.wim') {
|
||||||
$DriverSourceType = 'WIM'
|
$DriverSourceType = 'WIM'
|
||||||
}
|
}
|
||||||
@@ -625,8 +883,8 @@ if (Test-Path -Path $driverMappingPath -PathType Leaf) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
WriteLog "No matching driver rule found in DriverMapping.json for this system. Falling back to manual selection."
|
WriteLog "No automatic driver mapping rule matched identifiers for this system. Falling back to manual selection."
|
||||||
Write-Host "No matching driver rule found in DriverMapping.json for this system. Falling back to manual selection."
|
Write-Host "No matching driver mapping rule was found for this system. Falling back to manual selection."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
|
|||||||
Reference in New Issue
Block a user