Last week my coworker Sassan (@sassan_f) and I wrote a post on how to manage Dell BIOS/UEFI settings using PowerShell and wrap that in a Win32app in Intune. After that post there was many asks on how to do it for HP so here it is.
Setting the password is important because knowing the password is a requirement for all future BIOS modifications we need to do in the future, it is of course also a security concern so it should be password protected.
HP provides a Powershell module to manipulate BIOS/UEFI settings just as Dell does. One difference is that the HP module does not require Visual Studio Runtimes to work 😀
The PowerShell modules can be downloaded from here: https://developers.hp.com/hp-client-management/doc/client-management-script-library The script posted here can easily be modified to configure settings as well, HP also has a great sample script included in the download above.
Preparing the source files
After we downloaded the Script library from HP we extract it to a folder and just grab the modules we need to manage BIOS settings. We need the following two folders and add our script to it:
The whole script is here:
Start-Transcript -Path "$env:TEMP\$($(Split-Path $PSCommandPath -Leaf).ToLower().Replace(".ps1",".log"))" | Out-Null
$NewPassword = "MegaSecret1"
$OldPassword = "TopSecret1"
$DetectionRegPath = "HKLM:\SOFTWARE\Onevinn\Intune\HPClientMgmt"
$DetectionRegName = "PasswordSet"
if (-not (Test-Path -Path $DetectionRegPath)) {
New-Item -Path $DetectionRegPath -Force | Out-Null
}
if (Test-Path -Path "$env:ProgramFiles\WindowsPowerShell\Modules\HP.ClientManagement") {
Write-Output "HP.ClientManagement folder already exists @ $env:ProgramFiles\WindowsPowerShell\Modules\HP.ClientManagement."
Write-Output "Deleting the folder..."
Remove-Item -Path "$env:ProgramFiles\WindowsPowerShell\Modules\HP.ClientManagement" -Recurse -Force
}
if (Test-Path -Path "$env:ProgramFiles\WindowsPowerShell\Modules\HP.SoftPaq.Shared") {
Write-Output "HP.SoftPaq.Shared folder already exists @ $env:ProgramFiles\WindowsPowerShell\Modules\HP.SoftPaq.Shared."
Write-Output "Deleting the folder..."
Remove-Item -Path "$env:ProgramFiles\WindowsPowerShell\Modules\HP.SoftPaq.Shared" -Recurse -Force
}
Write-Output "Copying HP.ClientManagement module to: $env:ProgramFiles\WindowsPowerShell\Modules\HP.ClientManagement"
Copy-Item -Path "$PSScriptRoot\HP.ClientManagement\" -Destination "$env:ProgramFiles\WindowsPowerShell\Modules\HP.ClientManagement" -Recurse -Force
Write-Output "Copying HP.SoftPaq.Shared module to: $env:ProgramFiles\WindowsPowerShell\Modules\HP.SoftPaq.Shared"
Copy-Item -Path "$PSScriptRoot\HP.SoftPaq.Shared\" -Destination "$env:ProgramFiles\WindowsPowerShell\Modules\HP.SoftPaq.Shared" -Recurse -Force
try {
Import-Module "HP.ClientManagement" -Force -Verbose -ErrorAction Stop
}
catch {
Write-Output "Error importing module: $_"
exit 1
}
$IsAdminPassSet = Get-HPBiosSetupPasswordIsSet
if ($IsAdminPassSet -eq $false) {
Write-Output "Admin password is not set at this moment, will try to set it."
Set-HPBiosSetupPassword -newPassword "$NewPassword"
if ( (Get-HPBiosSetupPasswordIsSet) -eq $true ){
Write-Output "Admin password has now been set."
New-ItemProperty -Path "$DetectionRegPath" -Name "$DetectionRegName" -Value 1 | Out-Null
}
}
else {
Write-Output "Admin password is already set"
if ($null -eq $OldPassword) {
Write-Output "`$OldPassword variable has not been specified, will not attempt to change admin password"
}
else {
Write-Output "`$OldPassword variable has been specified, will try to change the admin password"
try {
Set-HPBiosSetupPassword -newPassword "$NewPassword" -Password "$OldPassword"
}
catch [System.Management.Automation.RuntimeException] {
Write-Output "Access Denied error, verify that `$OldPassword is correct"
}
New-ItemProperty -Path "$DetectionRegPath" -Name "$DetectionRegName" -Value 1 -Force | Out-Null
}
}
Stop-Transcript
The following lines needs to be modified both with a new password and an old one if the purpose is to change the password. The next two values are the registry key and registry value that is written to the registry when the script is successful so we can use that as the detection method.
$NewPassword – The password we want to set
$OldPassword – The password that is already set and that we want to change from – if applicable
$DetectionRegPath – Registry key that will be created and that will be used for detection method
$DetectionRegName – Name of the registry DWORD that will be set, used as detection method
$NewPassword = "MegaSecret1"
$OldPassword = "TopSecret1"
$DetectionRegPath = "HKLM:\SOFTWARE\Onevinn\Intune\HPClientMgmt"
$DetectionRegName = "PasswordSet"
Passwords in clear text is obviously not great but hardcoding them in the script and deploying it as a Win32 app in this case will at least not show the password in any log files on the clients or in the Intune portal. Ideally the password would be read from a secure vault of some sorts
Creating the Win32app in Intune
Download the Microsoft Win32 Content Prep Tool from https://github.com/Microsoft/Microsoft-Win32-Content-Prep-Tool if you haven’t already. Run the tool with the correct paths to create the -.intunewin file.
Next we logon to the Device Management portal and select create a new App under Client Apps. As app type we select “Windows app (Win32)”.
We upload the .intunewin file we created before as the app package file.
All that’s left now is to create the Win32 app and deploy it to our test user/device. When creating the Win32 app, make sure to use sysnative in the path of the install command. In my case the install command is: C:\Windows\Sysnative\WindowsPowerShell\v1.0\powershell.exe -noprofile -executionpolicy Bypass -file .\HPClientMgmt-SetAdmPass.ps1. We are also not using a separate uninstall script/command in this example so we just using the same command for both install and uninstall, you can of course change this to whatever fits your scenario.
In the Detection rules pane we will configure a manual detection rule type based on the registry key and value name that we specified in the script. In this example that is:
Key path: Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Onevinn\Intune\HPClientMgmt
Value name: PasswordSet
Detection method: Integer comparison
Operator: Equals
Value: 1
After that we’re done, and we can assign the Win32 app as soon as the file has been uploaded.
To verify we can verify that the detection rule is there and we also have the transcript/log file: C:\Windows\Temp\hpclientmgmt-setadmpass.log
Now we can configure HP BIOS passwords which is important even if new computers are shipped with the correct configuration.
Hi,
I read from Oliver that it’s best not to store the password in the powershell scripts?.
The password will end up in IntuneManagementExtension.log file !!!!
https://oliverkieselbach.com/2018/02/12/part-2-deep-dive-microsoft-intune-management-extension-powershell-scripts/
I have used the dell command configure tool (Our PC devices are of the same model/make). On one of the PC I first configured the BIOS to my expected settings(Setup password, disable wi-fi, sd card.. etc) then used the below tool to generate an EXE and deployed using intune win32 conversion tool
https://www.dell.com/support/article/us/en/04/sln311302/dell-command-configure?lang=en
this was an easier solution for me.
Thanks for blogging
Very nice!
Just a few modifications to get it to work. First: Folder HP.Softpaq.Shared does not exist in the new package from HP. I used HP.Softpaq instead.
Second: Needed to include forlder HP.Private – Otherwise password would not be set.
Thanks.
How did you fix the hp.private folder issue? I included it in the temp folder with the other two modules and still the same “statements of the script are missing: HP.Private.”
Placed hp.private in the same folder as the other modules
I edited the script to import the hc.private before the hp.clientmanagement and the hp.softpaq by just copying those other two portions and that seems to have done it.
Sorry, im slightly confused, on your screenshot. your only packaging the powershell script, Which i find weird because in the script your calling upon the other HP Folders, Are you supposed to package the folder that contains everything instead?
Renamed Softpaq.Shared to only Softpaq.
Added HP.Private module.
Remember to change the name everywhere and add a few rows for copy-item of the extra added module. Then it worked for me, couldnt find password in any log file either.