Changing BIOS Options on HP Computers Remotely

There may be a better way to do this, but from what I found there’s limited options to change HP BIOS options remotely. For their servers there are some nice PowerShell cmdlets, but for desktops the options are limited. HP does have a BIOS Configuration Utility (which can be found here: https://ftp.hp.com/pub/caps-softpaq/cmit/HP_BCU.html), but it doesn’t include remote options; you’d typically need to run it interactively on the computer you want to make changes to, which is a bit prohibitive. In order to get around this I wrote a little script that will copy the executable from a shared directory, and then invoke a command, which allows you to make changes on as many computers as you want at once.

The script I wrote was tooled specifically to change BIOS options, but it can be modified to be able to change any BIOS setting available.

Writing this wasn’t too difficult, but there was one piece that gave me a spot of trouble, which was the invoke command. Because I wanted to include a variable, run it from the command line, and had to include some quotations to make the command be interpreted correctly, I had to play around with that a fair bit. There are a couple of ways to run executables from PowerShell, but I went with using cmd /c from within an Invoke-Command, partially because it was one of the least complex methods, and because I was able to get it to work. To make use of the BootOption parameter I had to include a param() declaration in the ScriptBlock along with the ArgumentList parameter. And because commas and slashes are treated differently by the PowerShell interpreter, I had to escape these using the ` character (Be aware this also escapes the newline character, so it can be used to split up a command into multiple lines to increase readability).

Without further ado, here’s the script:

<#
.SYNOPSIS
This script is used to configure the boot order on a remote computer

.DESCRIPTION
It's a pretty simple script that just copies an executable to a remote computer, then runs it to set the boot order, and then removes the executable

.PARAMETER ComputerName
One or more computers

.Parameter BootOption
The BootOption that should be first

.EXAMPLE
Set-BIOSBootOrder -ComputerName Computer1 -BootOption "Network Controller"
This will set the first boot option to the network on Computer1
#> 
[CmdletBinding()]
param(
    [Parameter(ParameterSetName="ComputerName",Position=1,ValueFromPipeline=$True)][String[]]$ComputerName="localhost",
    [Parameter(Mandatory=$True)][ValidateSet("Network Controller","USB Floppy/CD","Hard Drive","ATAPI CD-ROM Drive")][String]$BootOption
)

Begin { }

Process
{
    Foreach ($Computer in $ComputerName)
    {
        If (Test-Connection $Computer -Count 2 -Quiet)
        {
            Try
            {
                # Copy the BIOS Configuration utility to the computer's C: drive
                Copy-Item "\\<Path to Share>\BIOS Configuration Utility" "\\$Computer\C$\BCU" -Recurse -Force -ErrorAction Stop 

                # Set the specified option to be the first then add the other options
                Switch ($BootOption)
                {
                    "Network Controller" {$BootString = "$BootOption,USB Floppy/CD,Hard Drive,ATAPI CD-ROM Drive"}
                    "USB Floppy/CD" {$BootString = "$BootOption,Hard Drive,Network Controller,ATAPI CD-ROM Drive"}
                    "Hard Drive" {$BootString = "$BootOption,Network Controller,USB Floppy/CD,ATAPI CD-ROM Drive"}
                    "ATAPI CD-ROM Drive" {$BootString = "$BootOption,USB Floppy/CD,Hard Drive,Network Controller"}
                }

                # Add the other devices
                $BootString += "PnP Device #1,PnP Device #2,PnP Device #3,PnP Device #4,PnP Device #5,PnP Device #6," + `
                               "PnP Device #7,PnP Device #8,PnP Device #9,PnP Device #10,PnP Device #11"

                # Run the BIOS Configuration utility
                Invoke-Command -ComputerName $Computer -ScriptBlock {param($BootString) cmd.exe /c 'C:\BCU\BiosConfigUtility64.exe' `
                                                                     `/setvalue:"Legacy Boot Order"`,"$BootString"} -ArgumentList `
                                                                     $BootString -ErrorAction Stop | Out-Null

                # Remove the BIOS Configuration utility
                Remove-Item "\\$Computer\C$\BCU" -Recurse -ErrorAction Stop 

                # Write some output
                Write-Output "Script completed successfully on $Computer"
            }

            Catch
            {
                # Display an error
                Write-Error "Unable to run the script on $Computer"
            }
        }
    }
}

End { }

To run this, you’ll first need to have the the BIOS  Configuration Utility in a shared location, then update the script so it knows where it is. With that you can then run it with:

Set-BIOSBootOrder -ComputerName Computer1 -BootOption "Network Controller"

You could also include any number of computers by separating them with commas:

Set-BIOSBootOrder -ComputerName Computer1, Computer2 -BootOption "Network Controller"

Or use a query from AD. For example, this will set the first boot option to the network controller on all computers in the Desktops OU:

Set-BIOSBootOrder -ComputerName $((Get-ADComputer -Filter * -SearchBase "OU=Desktops,DC=Domain,DC=TLD").name) -BootOption "Network Controller"

 

Leave a Reply

Your email address will not be published. Required fields are marked *