Public/OSDCloudTS/Get-HPTPMDetermine.ps1
|
function Install-ModuleHPCMSL { <# .SYNOPSIS Installs or updates the HP Client Management Script Library (HPCMSL) PowerShell module. .DESCRIPTION Ensures the HPCMSL module (version 1.8.5) is installed and up to date from the PowerShell Gallery. If PowerShellGet 2.2.5 or later is not present, it is installed first. Compares the installed HPCMSL version against the Gallery version and installs if missing or outdated. Supports both WinPE and full Windows environments. After installation, the module is imported into the global scope. .EXAMPLE Install-ModuleHPCMSL Installs or updates HPCMSL 1.8.5 for all users and imports it into the current session. .NOTES Requires internet access to reach the PowerShell Gallery. Must be run with administrator privileges. Uses the $WindowsPhase variable to detect WinPE vs. full OS context. #> [CmdletBinding()] param () if ((Get-ExecutionPolicy) -ne 'Bypass') { Set-ExecutionPolicy -ExecutionPolicy Bypass -Force -ErrorAction SilentlyContinue } $InstallModule = $false $PSModuleName = 'HPCMSL' if (-not (Get-Module -Name PowerShellGet -ListAvailable | Where-Object { $_.Version -ge '2.2.5' })) { Write-Host -ForegroundColor DarkGray 'Install-Package PackageManagement,PowerShellGet [AllUsers]' Install-Package -Name PowerShellGet -MinimumVersion 2.2.5 -Force -Confirm:$false -Source PSGallery | Out-Null Write-Host -ForegroundColor DarkGray 'Import-Module PackageManagement,PowerShellGet [Global]' Import-Module PackageManagement, PowerShellGet -Force -Scope Global -WarningAction SilentlyContinue -ErrorAction SilentlyContinue } $InstalledModule = Get-InstalledModule $PSModuleName -ErrorAction Ignore if ($InstalledModule.count -gt 1) { $InstalledModule = $InstalledModule | Select-Object -First 1 } $GalleryPSModule = Find-Module -Name $PSModuleName -ErrorAction Ignore if ($InstalledModule) { write-host "$PSModuleName in Gallery: $($GalleryPSModule.Version) vs Installed: $($InstalledModule.Version)" if (($GalleryPSModule.Version -as [version]) -gt ($InstalledModule.Version -as [version])) { $InstallModule = $true } } else { Write-Host "$PSModuleName is not Installed" $InstallModule = $true } if ($InstallModule) { if ($WindowsPhase -eq 'WinPE') { Write-Host -ForegroundColor DarkGray "Install-Module $PSModuleName 1.8.5 [AllUsers]" Install-Module $PSModuleName -RequiredVersion 1.8.5 -SkipPublisherCheck -Scope AllUsers -Force -AcceptLicense -ErrorAction SilentlyContinue -WarningAction SilentlyContinue } else { Write-Host -ForegroundColor DarkGray "Install-Module $PSModuleName 1.8.5 [AllUsers]" Install-Module $PSModuleName -RequiredVersion 1.8.5 -SkipPublisherCheck -AcceptLicense -Scope AllUsers -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue } } Import-Module -Name $PSModuleName -Force -Global -ErrorAction SilentlyContinue -WarningAction SilentlyContinue } Function Test-HPTPMFromOSDCloudUSB { <# .SYNOPSIS Tests whether HP TPM firmware packages exist on an OSDCloud USB drive. .DESCRIPTION Searches for HP TPM firmware softpaq files (SP87753 and/or SP94937) on a connected OSDCloud USB volume. If found, optionally copies them to C:\OSDCloud\HP for local use. Returns $true if the requested package(s) are found, otherwise $false. .PARAMETER PackageID The HP softpaq package ID to check for. Valid values are 'SP87753' or 'SP94937'. If not specified, both packages are checked. .PARAMETER TryToCopy Switch to indicate that found firmware files should be copied to C:\OSDCloud\HP. Note: this parameter is currently unreachable due to early return statements when a PackageID is specified. .EXAMPLE Test-HPTPMFromOSDCloudUSB -PackageID SP94937 Returns $true if SP94937.exe exists on the OSDCloud USB and copies it to C:\OSDCloud\HP. .EXAMPLE Test-HPTPMFromOSDCloudUSB Returns $true only if both SP87753.exe and SP94937.exe exist on the OSDCloud USB. .OUTPUTS System.Boolean #> [CmdletBinding()] param ( [Parameter()] [System.String] $PackageID, [switch] $TryToCopy ) $ComputerManufacturer = (Get-MyComputerManufacturer -Brief) $OSDCloudUSB = Get-Volume.usb | Where-Object { ($_.FileSystemLabel -match 'OSDCloud') -or ($_.FileSystemLabel -match 'BHIMAGE') } | Select-Object -First 1 if (!(Test-Path -Path "C:\OSDCloud")) { Write-Host -ForegroundColor Yellow "C:\OSDCloud does not exist, will be unable to copy TPM files local" } else { if (!(Test-Path -Path "C:\OSDCloud\HP")) { New-Item -Path "C:\OSDCloud\HP" -ItemType Directory -Force | Out-Null } } $HPTPMSP87753 = "$($OSDCloudUSB.DriveLetter):\OSDCloud\Firmware\$ComputerManufacturer\TPM\SP87753.exe" $HPTPMSP94937 = "$($OSDCloudUSB.DriveLetter):\OSDCloud\Firmware\$ComputerManufacturer\TPM\SP94937.exe" if ($PackageID) { if ($PackageID -eq 'SP87753') { if (Test-Path -Path $HPTPMSP87753) { if (Test-Path -Path "C:\OSDCloud") { Copy-Item -Path $HPTPMSP87753 -Destination "C:\OSDCloud\HP\SP87753.exe" -Force } return $true } else { return $false } } if ($PackageID -eq 'SP94937') { if (Test-Path -Path $HPTPMSP94937) { if (Test-Path -Path "C:\OSDCloud") { Copy-Item -Path $HPTPMSP94937 -Destination "C:\OSDCloud\HP\SP94937.exe" -Force } return $true } else { return $false } } } else { if ((Test-Path -Path $HPTPMSP94937) -and (Test-Path -Path $HPTPMSP87753)) { if (Test-Path -Path "C:\OSDCloud") { Copy-Item -Path $HPTPMSP94937 -Destination "C:\OSDCloud\HP\SP94937.exe" -Force } if (Test-Path -Path "C:\OSDCloud") { Copy-Item -Path $HPTPMSP87753 -Destination "C:\OSDCloud\HP\SP87753.exe" -Force } return $true } else { return $false } } if ($TryToCopy) { if (Test-Path -Path $HPTPMSP94937) { if (Test-Path -Path "C:\OSDCloud") { Write-Host "Copy-Item -Path $HPTPMSP94937 -Destination 'C:\OSDCloud\HP\SP94937.exe' -Force" Copy-Item -Path $HPTPMSP94937 -Destination "C:\OSDCloud\HP\SP94937.exe" -Force } } if (Test-Path -Path $HPTPMSP87753) { if (Test-Path -Path "C:\OSDCloud") { Write-Host "Copy-Item -Path $HPTPMSP87753 -Destination 'C:\OSDCloud\HP\SP87753.exe' -Force" Copy-Item -Path $HPTPMSP87753 -Destination "C:\OSDCloud\HP\SP87753.exe" -Force } } } } function Get-HPTPMDetermine { <# .SYNOPSIS Determines which HP TPM firmware update package is required for the current device. .DESCRIPTION Queries the TPM via WMI (win32_tpm) to identify the manufacturer and firmware version. For Infineon (IFX) TPMs, compares the firmware version against known vulnerable version ranges and returns the appropriate HP softpaq package ID. Returns 'SP87753' for firmware requiring an older update package, 'SP94937' for firmware requiring the newer package, or $false if no update is needed or the TPM is not Infineon. .EXAMPLE $Package = Get-HPTPMDetermine Returns 'SP87753', 'SP94937', or $false. .OUTPUTS System.String Returns 'SP87753', 'SP94937', or $false. .NOTES Requires access to the root\cimv2\security\MicrosoftTPM WMI namespace. Must be run with administrator privileges. #> [CmdletBinding()] param () $TPM = Get-CimInstance -Namespace "root\cimv2\security\MicrosoftTPM" -ClassName win32_tpm if ($TPM.ManufacturerIdTxt -match "IFX") { $SP87753 = Get-CimInstance -Namespace "root\cimv2\security\MicrosoftTPM" -query "select * from win32_tpm where IsEnabled_InitialValue = 'True' and ((ManufacturerVersion like '7.%' and ManufacturerVersion < '7.63.3353') or (ManufacturerVersion like '5.1%') or (ManufacturerVersion like '5.60%') or (ManufacturerVersion like '5.61%') or (ManufacturerVersion like '4.4%') or (ManufacturerVersion like '6.40%') or (ManufacturerVersion like '6.41%') or (ManufacturerVersion like '6.43.243.0') or (ManufacturerVersion like '6.43.244.0'))" $SP94937 = Get-CimInstance -Namespace "root\cimv2\security\MicrosoftTPM" -query "select * from win32_tpm where IsEnabled_InitialValue = 'True' and ((ManufacturerVersion like '7.62%') or (ManufacturerVersion like '7.63%') or (ManufacturerVersion like '7.83%') or (ManufacturerVersion like '6.43%') )" if (!($SP87753)) { $TPM = Get-CimInstance -Namespace "root\cimv2\security\MicrosoftTPM" -ClassName win32_tpm #Testing change below, from -eq to -lt. If you manually downgrade using 94937 from 2.0 to 1.2, it sets the version to 6.43.X if ($TPM.SpecVersion -match "1.2" -and $TPM.ManufacturerVersion -lt "6.43") { $SP87753 = 'SP87753' } } if ($SP87753) { Return "SP87753" } elseif ($SP94937) { Return "SP94937" } else { Return $false } } else { Return $false } } function Invoke-HPTPMDownload { <# .SYNOPSIS Downloads and extracts the required HP TPM firmware update softpaq using HPCMSL. .DESCRIPTION Calls Get-HPTPMDetermine to identify the required softpaq, then uses the HPCMSL Get-Softpaq cmdlet to download it to the specified working folder. The downloaded EXE is silently extracted to a subfolder. Returns the path to the extracted folder. Intended for manual download and testing scenarios. .PARAMETER WorkingFolder The folder path where the softpaq EXE will be downloaded and extracted. Defaults to $env:TEMP\TPM if not specified. .EXAMPLE Invoke-HPTPMDownload Downloads and extracts the required TPM firmware softpaq to $env:TEMP\TPM. .EXAMPLE Invoke-HPTPMDownload -WorkingFolder 'C:\Temp\TPMWork' Downloads and extracts the required TPM firmware softpaq to C:\Temp\TPMWork. .OUTPUTS System.String Returns the path to the extracted firmware folder. .NOTES Requires internet access and the HPCMSL PowerShell module. Must be run with administrator privileges. #> [CmdletBinding()] param ($WorkingFolder) Install-ModuleHPCMSL Import-Module -Name HPCMSL -Force $TPMUpdate = Get-HPTPMDetermine if (!(($TPMUpdate -eq $false) -or ($TPMUpdate -eq "False"))) { if ((!($WorkingFolder)) -or ($null -eq $WorkingFolder)) { $WorkingFolder = "$env:TEMP\TPM" } if (!(Test-Path -Path $WorkingFolder)) { New-Item -Path $WorkingFolder -ItemType Directory -Force | Out-Null } $UpdatePath = "$WorkingFolder\$TPMUpdate.exe" $extractPath = "$WorkingFolder\$TPMUpdate" Write-Host "Starting downlaod & Install of TPM Update $TPMUpdate" Get-Softpaq -Number $TPMUpdate -SaveAs $UpdatePath -Overwrite yes if (!(Test-Path -Path $UpdatePath)) { Throw "Failed to Download TPM Update" } Start-Process -FilePath $UpdatePath -ArgumentList "/s /e /f $extractPath" -Wait if (!(Test-Path -Path $extractPath)) { Throw "Failed to Extract TPM Update" } else { Return $extractPath } } else { Write-Host "No TPM Softpaq to Download" } } function Invoke-HPTPMDowngrade { <# .SYNOPSIS Downloads and applies the HP SP94937 softpaq to downgrade a TPM from 2.0 to 1.2. .DESCRIPTION Downloads softpaq SP94937 using HPCMSL, extracts it, and runs TPMConfig64.exe with the '-a 1.2' argument to downgrade an Infineon TPM from firmware version 2.0 to 1.2. Disables Virtualization Technology (VTx) in the BIOS via Set-HPBIOSSetting before applying the firmware change. .PARAMETER WorkingFolder The folder path where the softpaq EXE will be downloaded and extracted. Defaults to $env:TEMP\TPM if not specified. .EXAMPLE Invoke-HPTPMDowngrade Downloads SP94937 to $env:TEMP\TPM and downgrades the Infineon TPM to spec 1.2. .NOTES Requires HPCMSL and the HP BIOS WMI interface (Set-HPBIOSSetting). Must be run with administrator privileges. A system reboot is typically required after the firmware change takes effect. #> [CmdletBinding()] param ($WorkingFolder) Install-ModuleHPCMSL Import-Module -Name HPCMSL -Force $TPMUpdate = 'SP94937' if (!(($TPMUpdate -eq $false) -or ($TPMUpdate -eq "False"))) { if ((!($WorkingFolder)) -or ($null -eq $WorkingFolder)) { $WorkingFolder = "$env:TEMP\TPM" } if (!(Test-Path -Path $WorkingFolder)) { New-Item -Path $WorkingFolder -ItemType Directory -Force | Out-Null } $UpdatePath = "$WorkingFolder\$TPMUpdate.exe" $extractPath = "$WorkingFolder\$TPMUpdate" Write-Host "Starting downlaod & Install of TPM Update $TPMUpdate" Get-Softpaq -Number $TPMUpdate -SaveAs $UpdatePath -Overwrite yes if (!(Test-Path -Path $UpdatePath)) { Throw "Failed to Download TPM Update" } Start-Process -FilePath $UpdatePath -ArgumentList "/s /e /f $extractPath" -Wait if (!(Test-Path -Path $extractPath)) { Throw "Failed to Extract TPM Update" } else { Write-Host "TPM Downloaded to $extractPath" } } else { Write-Host "No TPM Softpaq to Download" } if ($extractPath) { Set-HPBIOSSetting -SettingName 'Virtualization Technology (VTx)' -Value 'Disable' $spec = '1.2' $Process = "$extractPath\TPMConfig64.exe" $TPMArg = "-s -a$spec -l$($LogFolder)\TPMConfig.log" Write-Host -ForegroundColor Green "Running Command: Start-Process -FilePath $Process -ArgumentList $TPMArg -PassThru -Wait" $TPMUpdate = Start-Process -FilePath $Process -ArgumentList $TPMArg -PassThru -Wait write-output "Exit Code: $($TPMUpdate.exitcode)" } } function Invoke-HPTPMEXEDownload { <# .SYNOPSIS Downloads the required HP TPM firmware EXE to C:\OSDCloud\HP\TPM. .DESCRIPTION Calls Get-HPTPMDetermine to identify the required softpaq, then downloads the firmware EXE to C:\OSDCloud\HP\TPM. If the file is already present on a connected OSDCloud USB drive it is copied locally instead of being downloaded from the internet. The destination folder is cleared before each run. Also disables Virtualization Technology (VTx) in the BIOS via Set-HPBIOSSetting. .EXAMPLE Invoke-HPTPMEXEDownload Determines the required TPM softpaq and downloads (or copies) it to C:\OSDCloud\HP\TPM. .NOTES Requires HPCMSL if the firmware file is not already available on an OSDCloud USB drive. Must be run with administrator privileges. #> [CmdletBinding()] param () Set-HPBIOSSetting -SettingName 'Virtualization Technology (VTx)' -Value 'Disable' $TPMUpdate = Get-HPTPMDetermine if (!(($TPMUpdate -eq $false) -or ($TPMUpdate -eq "False"))) { $DownloadFolder = "C:\OSDCloud\HP\TPM" if (Test-Path -Path $DownloadFolder) { Remove-Item -Path $DownloadFolder -Force -Recurse New-Item -Path $DownloadFolder -ItemType Directory -Force | Out-Null } $UpdatePath = "$DownloadFolder\$TPMUpdate.exe" if ((Test-HPTPMFromOSDCloudUSB -PackageID $TPMUpdate) -eq $true) { if (Test-Path -Path "C:\OSDCloud\HP\$TPMUpdate.exe") { "Found Local Copy of TPM Update $TPMUpdate, Copying to Staging Area" Copy-Item -Path "C:\OSDCloud\HP\$TPMUpdate.exe" -Destination $UpdatePath -Force -Verbose } } if (!(Test-Path -Path $UpdatePath)) { Write-Host "Starting download of TPM Update $TPMUpdate" Install-ModuleHPCMSL Import-Module -Name HPCMSL -Force Get-Softpaq -Number $TPMUpdate -SaveAs $UpdatePath -Overwrite yes } if (!(Test-Path -Path $UpdatePath)) { Throw "Failed to Download TPM Update" } } } function Invoke-HPTPMEXEInstall { <# .SYNOPSIS Extracts and installs the HP TPM firmware update from C:\OSDCloud\HP\TPM. .DESCRIPTION Locates the firmware EXE in C:\OSDCloud\HP\TPM, silently extracts it, then runs TPMConfig64.exe with the specified arguments to apply the TPM firmware update. Logs activity to C:\OSDCloud\Logs\TPMConfig.log. Outputs the exit code from TPMConfig64 along with a human-readable description for all documented exit codes. .PARAMETER path Reserved parameter. Not currently used. .PARAMETER filename Optional firmware binary filename passed to TPMConfig64 via the -f argument. .PARAMETER spec Optional TPM specification version to target (e.g., '1.2' or '2.0'). Passed to TPMConfig64 via the -a argument. .PARAMETER logsuffix Reserved parameter. Not currently used. .PARAMETER WorkingFolder Reserved parameter. Not currently used. .EXAMPLE Invoke-HPTPMEXEInstall Installs the TPM firmware using default TPMConfig64 arguments. .EXAMPLE Invoke-HPTPMEXEInstall -spec '1.2' Installs the TPM firmware targeting the 1.2 specification. .NOTES Run Invoke-HPTPMEXEDownload first to stage the firmware file. Must be run with administrator privileges. Exit code 3010 indicates success with a required reboot. #> [CmdletBinding()] Param ( [Parameter(Mandatory = $false)] $path, [Parameter(Mandatory = $false)] $filename, [Parameter(Mandatory = $false)] $spec, [Parameter(Mandatory = $false)] $logsuffix, [Parameter(Mandatory = $false)] $WorkingFolder ) $TPM = Get-HPTPMDetermine if ($TPM) { $DownloadFolder = "C:\OSDCloud\HP\TPM" $LogFolder = "C:\OSDCloud\Logs" $TPMUpdate = (Get-ChildItem -Path $DownloadFolder -Filter *.exe).FullName if (Test-Path $TPMUpdate) { Start-Process -FilePath $TPMUpdate -ArgumentList "/s /e /f $DownloadFolder" -Wait if (!(Test-Path -Path "$DownloadFolder\TPMConfig64.exe")) { Throw "Failed to Extract TPM Update" } $Process = "$DownloadFolder\TPMConfig64.exe" #Create Argument List if ($filename -and $spec) { $TPMArg = "-s -f$filename -a$spec -l$($LogFolder)\TPMConfig.log" } elseif ($filename -and !($spec)) { $TPMArg = "-s -f$filename -l$($LogFolder)\TPMConfig.log" } elseif (!($filename) -and $spec) { $TPMArg = "-s -a$spec -l$($LogFolder)\TPMConfig.log" } elseif (!($filename) -and !($spec)) { $TPMArg = "-s -l$($LogFolder)\TPMConfig.log" } Write-Output "Running Command: Start-Process -FilePath $Process -ArgumentList $TPMArg -PassThru -Wait" $TPMUpdate = Start-Process -FilePath $Process -ArgumentList $TPMArg -PassThru -Wait write-output "TPMUpdate Exit Code: $($TPMUpdate.exitcode)" If ($TPMUpdate.ExitCode -eq 3010) { write-output "$($TPMUpdate.exitcode): Success, Reboot Required" } else { Switch ($TPMUpdate.ExitCode) { 0 { $ErrorDescription = "Success" } 128 { $ErrorDescription = " Invalid command line option" } 256 { $ErrorDescription = "No BIOS support" } 257 { $ErrorDescription = "No TPM firmware bin file" } 258 { $ErrorDescription = " Failed to create HP_TOOLS partition" } 259 { $ErrorDescription = "Failed to flash the firmware" } 260 { $ErrorDescription = "No EFI partition (for GPT)" } 261 { $ErrorDescription = "Bad EFI partition" } 262 { $ErrorDescription = "Cannot create HP_TOOLS partition (because the maximum number of partitions has been reached)" } 263 { $ErrorDescription = "Not enough space partition (when the size of the firmware binary file is greater than the free space of EFI or HP_TOOLS partition)" } 264 { $ErrorDescription = " Unsupported operating system" } 265 { $ErrorDescription = "Elevated (administrator) privileges are required" } 273 { $ErrorDescription = "Not supported chipset" } 274 { $ErrorDescription = "No more firmware upgrade is allowed" } 275 { $ErrorDescription = "Invalid firmware binary file " } 290 { $ErrorDescription = "BitLocker is currently enabled." } 291 { $ErrorDescription = "Unknown BitLocker status" } 292 { $ErrorDescription = "WinMagic encryption is currently enabled" } 293 { $ErrorDescription = "WinMagic SecureDoc is currently enabled" } 296 { $ErrorDescription = "No system information" } 305 { $ErrorDescription = "Intel TXT is currently enabled." } 306 { $ErrorDescription = "VTx is currently enabled." } 307 { $ErrorDescription = "SGX is currently enabled." } 1602 { $ErrorDescription = "User cancelled the operation" } 3010 { $ErrorDescription = "Success reboot required" } 3011 { $ErrorDescription = "Success rollback" } 3012 { $ErrorDescription = "Failed rollback" } } write-output "$($TPMUpdate.exitcode): $ErrorDescription" } } else { Throw "Failed to Locate Update Path" } } } |