Update HP BIOS from the Internet using HPCMS

12 posts / 0 new
Last post
Author
Message
estebby
Posted: 13 November 2019 - 4:54am
Update HP BIOS from the Internet using HPCMS

Hi guys,

Apologies if this is not the right forum to ask this question, but I have adapted a script which was a comment by a Jonathan in Gary Blok's blog article (https://garytown.com/update-hp-bios-using-powershell-and-internet-connection) to download and install the latest version of the HP BIOS. I have this working locally (after a bit of tinkering) but it fails in the MDT task sequence (it runs after the OS has been installed and a restart performed, also tried moving the TS to after the OS installed but before a restart).  I'm no powershell expert but know enough to be able to adapt existing scripts generally, but this one has me scratching my head.  If anyone has any idea of what I am missing, it would be greatly appreciated!

There are a few bits commented out here and there when i have been testing locally or via MDT, but rest assured, I have tried with them and without them enabled (in particular the return codes as a means of setting a Task Sequence variable as  a condition to reboot the machine after BIOS install if necessary - that said, even when it does install locally, it doesn't return a process exit code of 2!).

Many thanks,

Steve

##################################
<# SCRIPT INFO ####################
Alternative script proposed by Jonathan on https://garytown.com/update-hp-bios-using-powershell-and-internet-connection
# FUNCTIONS ######################
##################################>
Function Get-ScriptDirectory
{
If ($PSISE){
Split-Path $PSISE.CurrentFile.FullPath
}
Else{
$Global:PSScriptRoot
}
}
##################################
#Log file info
$tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment -ErrorAction SilentlyContinue
$LogPath = $tsenv.Value("LogPath") 
#If testing locally use the logPath below
#$LogPath = "$ENV:SystemDrive\Windows\Temp"
$LogFileName = "HPBiosUpdate.log"
$LogFile = Join-Path $LogPath $LogFileName
$Today = Get-Date -Format yyyy-MM-dd
$Time = Get-Date -Format HH:mm:ss
#Start logging
Out-File $LogFile -Append -InputObject ("")
Out-File $LogFile -Append -InputObject ("")
Out-File $LogFile -Append -InputObject ("$Today - $Time")
Out-File $LogFile -Append -InputObject ("")
#Define locations
$ScriptDir = Get-ScriptDirectory
#$ScriptDir = $PSScriptRoot
$SaveToRoot = "$ENV:SystemDrive\Windows\Temp"
$SaveToDirectory = "HP_BIOS"
$SaveToLocation = "$SaveToRoot\$SaveToDirectory"
$DownloadDir = "$($SaveToLocation)\HP_BIOS_Downloads"
$ExtractDir = "$($SaveToLocation)\HP_BIOS_Extract"
If (!(Test-Path $SaveToLocation)){
	$null = New-Item -Path $SaveToRoot\ -Name $SaveToDirectory -ItemType "Directory" -Force
}
If (!(Test-Path $DownloadDir)){
	$null = New-Item -Path $SaveToLocation\ -Name "HP_BIOS_Downloads" -ItemType "Directory" -Force
}
If (!(Test-Path $ExtractDir)){
	$null = New-Item -Path $SaveToLocation\ -Name "HP_BIOS_Extract" -ItemType "Directory" -Force
}
#Define variables
$OS = "Win10"
$Category = "BIOS"
$ProductCode = (Get-WmiObject -Class Win32_BaseBoard).Product
$Model = (Get-WmiObject -Class Win32_ComputerSystem).Model
$HP_CMSL_URL = "https://ftp.hp.com/pub/caps-softpaq/cmit/release/cmsl/hp-cmsl-latest.exe"
#Detect HP BIOS PS module
Try
{Get-HPBiosVersion | Out-Null
	Write-Host "HP Client Management Script Library already installed"
	Out-File $LogFile -Append -InputObject ("HP Client Management Script Library already installed")
}
Catch
{Write-Host "HP Client Management Script Library not loaded"
	Write-Host "Downloading from $HP_CMSL_URL"
	Out-File $LogFile -Append -InputObject ("HP Client Management Script Library not loaded")
	Out-File $LogFile -Append -InputObject ("Downloading from $HP_CMSL_URL")
	Invoke-WebRequest -Uri $HP_CMSL_URL -OutFile "$($DownloadDir)\HP_CMSL.exe"
	Write-Host "Installing HP Client Management Script Library from $($DownloadDir)\HP_CMSL.exe"
	Out-File $LogFile -Append -InputObject ("Installing HP Client Management Script Library from $($DownloadDir)\HP_CMSL.exe")
	Start-Process -FilePath "$($DownloadDir)\HP_CMSL.exe" -ArgumentList "/Silent /NoCancel /NoRestart /CloseApplications /Log" -Wait
	Write-Host "Finished downloading and installing HP Client Management Script Library"
	Out-File $LogFile -Append -InputObject ("Finished downloading and installing HP Client Management Script Library")
}
#Get BIOS info
$CurrentBIOS = Get-HPBiosVersion
Write-Host "Currently installed BIOS: version $($CurrentBIOS)"
Write-Host "Checking product code $($ProductCode) for BIOS updates"
Out-File $LogFile -Append -InputObject ("Currently installed BIOS: version $($CurrentBIOS)")
Out-File $LogFile -Append -InputObject ("Checking product code $($ProductCode) for BIOS updates")
$BIOS = Get-SoftpaqList -Platform $ProductCode -Os $OS -Category $Category
$MostRecent = ($BIOS | Measure-Object -Property "ReleaseDate" -Maximum).Maximum
$BIOS = $BIOS | Where "ReleaseDate" -eq "$MostRecent"

If ([VERSION]$CurrentBIOS -ge [VERSION]$BIOS.Version){
	Write-Host "BIOS already current"
	Out-File $LogFile -Append -InputObject ("BIOS already current")
}
Else{
	Write-Host "Updated BIOS available: version $([VERSION]$BIOS.Version)"
	Out-File $LogFile -Append -InputObject ("Updated BIOS available: version $([VERSION]$BIOS.Version)")
	#Create folders
	$DownloadPath = "$($DownloadDir)\$($Model)\$($BIOS.Version)"
	$ExtractPath = "$($ExtractDir)\$($Model)\$($BIOS.Version)"
	
	If (!(Test-Path $DownloadPath)){
		$null = New-Item $DownloadPath -ItemType Directory -Force
	}
	If (!(Test-Path $ExtractPath)){
		$null = New-Item $ExtractPath -ItemType Directory -Force
	}
}		
	#Download BIOS files
	$BIOS_CVA = "$($DownloadPath)\$($BIOS.Id).cva"
	$BIOS_HTML = "$($DownloadPath)\$($BIOS.Id).html"
	$BIOS_EXE = "$($DownloadPath)\$($BIOS.Id).exe"
	$BIOS_TXT = "$($DownloadPath)\$($BIOS.ReleaseDate).txt"
	Write-Host "Downloading BIOS update for model $($Model) / product $($ProductCode) to $($DownloadPath)"
	Out-File $LogFile -Append -InputObject ("Downloading BIOS update for model $($Model) / product $($ProductCode) to $($DownloadPath)")
	Get-Softpaq -Number $BIOS.Id -SaveAs $BIOS_EXE -Verbose
	Write-Host "Downloading BIOS CVA file to $BIOS_CVA"
	Out-File $LogFile -Append -InputObject ("Downloading BIOS CVA file to $BIOS_CVA")
	Invoke-WebRequest -Uri $BIOS.MetaData -OutFile $BIOS_CVA
	Write-Host "Downloading BIOS HTML file to $BIOS_HTML"
	Out-File $LogFile -Append -InputObject ("Downloading BIOS HTML file to $BIOS_HTML")
	Invoke-WebRequest -Uri $BIOS.ReleaseNotes -OutFile $BIOS_HTML
	Write-Host "Writing README file with BIOS info to $BIOS_TXT"
	Out-File $LogFile -Append -InputObject ("Writing README file with BIOS info to $BIOS_TXT")
	$BIOS | Out-File -FilePath $BIOS_TXT
	#Extract BIOS files
	Write-Host "Extracting downloaded BIOS file to $($ExtractPath)"
	Out-File $LogFile -Append -InputObject ("Extracting downloaded BIOS file to $($ExtractPath)")
	Start-Process $BIOS_EXE -ArgumentList "-pdf -e -s -f$($ExtractPath)" -Wait
	#Suspend Bitlocker
	If ((Get-BitLockerVolume -MountPoint "$ENV:SystemDrive").VolumeStatus -eq "FullyDecrypted"){
		Write-Host "Bitlocker not enabled"
		Out-File $LogFile -Append -InputObject ("Bitlocker not enabled")
	}
	Else{
		Write-Host "Suspending Bitlocker"
		Out-File $LogFile -Append -InputObject ("Suspending Bitlocker")
		Suspend-BitLocker -MountPoint "$ENV:SystemDrive" -RebootCount 1
	}
	#Search CVA to find path of executable that should be used to install the new BIOS version
	Write-Host "Looking for executable that should be used to install the new BIOS version in CVA file"
	Out-File $LogFile -Append -InputObject ("Looking for executable that should be used to install the new BIOS version in CVA file")
	$CVA_Install_Command = Get-Content $BIOS_CVA | Where {$_ -like "*SilentInstall*"}
	$CVA_Install_EXE = $CVA_Install_Command | %{$_.Split('"')[1]}
	Write-Host "Install command from CVA found: $CVA_Install_EXE"
	Out-File $LogFile -Append -InputObject ("Install command from CVA found: $CVA_Install_EXE")
	#Run update command with password file support
	$Updater_EXE = "$ExtractPath\$CVA_Install_EXE"
	$BIOS_PW = "$ScriptDir\HP_New.bin"
	If (Get-HPBiosSetupPasswordIsSet){
		Write-Host "BIOS password protection detected"
		Out-File $LogFile -Append -InputObject ("BIOS password protection detected")
		If (!(Test-Path $BIOS_PW)){
			Write-Host "HP BIOS password file missing: $BIOS_PW not found" -ForegroundColor Yellow
			Out-File $LogFile -Append -InputObject ("HP BIOS password file missing: $BIOS_PW not found")
		}
		Write-Host "Using $CVA_Install_EXE to Flash BIOS with arguments -s -r -b -l -p"
		Out-File $LogFile -Append -InputObject ("Using $CVA_Install_EXE to Flash BIOS with Args -s -r -b -l -p")
		#Flash BIOS
		Write-Host "Command = $Updater_EXE -s -r -b -l$($SaveToRoot)\HPBIOSUpdate.log -p$($BIOS_PW)"
		Out-File $LogFile -Append -InputObject ("Command = $Updater_EXE -s -r -b -l$($SaveToRoot)\HPBIOSUpdate.log -p$($BIOS_PW)")
		$Process = Start-Process $Updater_EXE -ArgumentList "-s -r -b -l$($SaveToRoot)\HPBIOSUpdate.log -p$($BIOS_PW)" -PassThru -Wait
		$Process.WaitForExit()

		<#if ($Process.ExitCode -eq 2){
			$tsenv.Value("SMSTS_BiosUpdateRebootRequired") = "True"}
		
		else{
			$tsenv.Value("SMSTS_BiosUpdateRebootRequired") = "False"}#>
	}
	

Else
{
	Write-Host "BIOS password protection not detected"
	Write-Host "Using $CVA_Install_EXE to Flash BIOS with Args -s -r -b -l"
	Out-File $LogFile -Append -InputObject ("BIOS password protection not detected")
	Out-File $LogFile -Append -InputObject ("Using $CVA_Install_EXE to Flash BIOS with arguments -s -r -b -l")
	#Flash BIOS
	Write-Host "Command = $Updater_EXE -s -r -b -l$($SaveToRoot)\HPBIOSUpdate.log"
	Out-File $LogFile -Append -InputObject ("Command = $Updater_EXE -s -r -b -l$($SaveToRoot)\HPBIOSUpdate.log)")
	$Process = Start-Process $Updater_EXE -ArgumentList "-s -r -b -l$($SaveToRoot)\HPBIOSUpdate.log" -PassThru -Wait 
	$Process.WaitForExit()
 

	<#if ($Process.ExitCode -eq 2){
		$tsenv.Value("SMSTS_BiosUpdateRebootRequired") = "True"}

    else{
		$tsenv.Value("SMSTS_BiosUpdateRebootRequired") = "False"}#>
}

#Cleanup update files
Write-Host "Removing folder $SaveToLocation to cleanup install files"
Out-File $LogFile -Append -InputObject ("Removing folder $SaveToLocation to cleanup install files")
Remove-Item -Recurse -Force $SaveToLocation -ErrorAction SilentlyContinue
#Notify user
#Write-Host "HP BIOS update applied, will install after next reboot" -ForegroundColor Green
Out-File $LogFile -Append -InputObject ("HP BIOS update applied, will install after next reboot")


Sleep 5

 

Top
Author
Message
nkofahl
Posted: 13 November 2019 - 6:56am
Looking at the script there

Looking at the script there are a bunch of places it could go wrong in your environment. That said if you all you are looking to do is get the latest bios installed you don't need that complicated of a script. 

Assuming MDT here you have 2 steps you need to take 

1. Copy the PowerShell modules into the PowerShell path. Start by downloading the 1.2.1 module and when you run the installer, select the unpack module cmd. Easy to just run this cmd (xcopy *.* "%ProgramFiles%\WindowsPowerShell\Modules" /E /Y) from the folder that has the actual modules. 

2. run one of these two PowerShell cmds (make sure you set the execution policy appropriately. 

Get-SoftpaqList -category bios |ForEach-Object {
 Get-Softpaq $_.Id -action silentinstall}

or 

Get-hpbiosupdates -flash -yes -bitlocker suspend 

That should get the bios updated without too much additional work.  

Top
Author
Message
estebby
Posted: 14 November 2019 - 1:01am
Thanks, I'll take a look.

Thanks, I'll take a look. Agreed it may be overly complex though I was looking for something that would do the logging and only check for and install the updated BIOS if needed (using the encrypted '.bin' password file). We have something similar for our Dell machines which uses an adapted version of Gary B's scripts (we're in the process of trialling HP which is why I'm trying to set up the same functionality).

So, just to clarify, I need to install the powershell modules on the MDT server? Can I use a password.bin file with the Get-hpbiosupdates command (the documentation suggests this has to be a string)?

Top
Author
Message
nkofahl
Posted: 14 November 2019 - 6:20am
Anywhere you want to call the

Anywhere you want to call the functions they need to be in the powershell modules path. So if you want to update the bios on a client, you'll want to copy them to the powerhsell path of winpe while it is running or the powershell path of the OS after it boots. 

If you want to leverage them for driver download and import on your MDT server as my post here https://developers.hp.com/hp-client-management/blog/automating-mdt-drivers-hp-client-management-script-library you'll need them on your MDT server as well. 

Top
Author
Message
dinar.galimov
Posted: 6 April 2021 - 10:34am
Re: Looking at the script there

Hi everyone,

I am preparing PS script to keep up-to-date BIOS version for all HP devices in company.

I am using Get-HPBIOSUpdates  -Download -SaveAs -Overwrite and then want to flash bios using downloaded file. I just want to clarify one point. How I can make sure, that the file has been downloaded succesfuuly? I did not find any verifications commands.

Thank you.

Top
Author
Message
dinar.galimov
Posted: 6 April 2021 - 10:37am
Re: Looking at the script there

Hi everyone,

I am preparing PS script to keep up-to-date BIOS version for all HP devices in company.

I am using Get-HPBIOSUpdates  -Download -SaveAs -Overwrite and then want to flash bios using downloaded file. I just want to clarify one point. How I can make sure, that the file has been successfully downloaded ? I did not find any verifications commands.

Thank you.

Top
Author
Message
txvalp
Posted: 6 April 2021 - 10:42am
Re: Update HP BIOS from the Internet using HPCMS

Currently the best way of doing this is to catch any exceptions thrown by the script. In the future, we are looking to add additonal metadata that will allow more elegant verification.

There are multiple checks downstream to make sure the file is correct, but for the download process the best way we have at this time is to handle exceptions.

 

Top
Author
Message
dinar.galimov
Posted: 7 April 2021 - 12:58am
Re: Update HP BIOS from the Internet using HPCMS

Thank you!

Top
Author
Message
dinar.galimov
Posted: 5 July 2021 - 5:20am
Re: Update HP BIOS from the Internet using HPCMS

sorry, was duplicated post.

Top
Author
Message
dinar.galimov
Posted: 1 July 2021 - 8:27am
Re: Update HP BIOS from the Internet using HPCMS

Hi Colleagues,

Could you please which URL should be added to whitelist on firewall to allow HP CMSL download BIOS .bin files under system context in under enterprise network?

All that i found it "https://ftp.hp.com/pub/pcbios". Is it right adress?

Thank you  in advance.

Top
Author
Message
txvalp
Posted: 21 July 2021 - 9:19am
Re: Update HP BIOS from the Internet using HPCMS

For BIOS files, that is correct: ftp.hp.com:443. There are different paths on there, depending on which CMSL features you use. 

The tool also uses hpia.hpcloud.hp.com/ref:443 for data files.

 

Top
Author
Message
dinar.galimov
Posted: 9 August 2021 - 10:20am
Re: Update HP BIOS from the Internet using HPCMS

I also added  ftp.ext.hp.com and ftp-hpcom.glb1.hp.com to authotization bypass. And it works.

Thank you.

I have another question. How can I check if current OS is waiting for computer reboot to applying BIOS update after .bin files has been deployed to current system?Is it possbile get something like "pending reboot" state using HP CMSL? Or How i can check if a BIOS .bin file has been copied to EFI partition and it still there?

Top
Please login to comment