Dell BIOS Settings Management – WMI

Earlier this year, I wrote about how to manage Dell BIOS settings using PowerShell. The method described in that post uses the DellBIOSProvider PowerShell module. This method works, but I was not completely satisfied with it, as the PowerShell module needs to be downloaded and installed on every system the script runs on.

Thankfully, Dell recently released a technical whitepaper documenting WMI classes that can be used to directly modify BIOS settings without needing an outside program or PowerShell module. This allowed me to create a new version of the Dell BIOS Settings Management script that does not require any additional content to function.

One caveat for this new method is the WMI classes are only supported on Dell hardware released to market after calendar year 2018. Because of this, older Dell hardware will still require the use of the DellBIOSProvider PowerShell module.

The script can be downloaded from my GitHub: https://github.com/ConfigJon/Firmware-Management/blob/master/Dell/Manage-DellBiosSettings-WMI.ps1

Dell, WMI, and PowerShell

Dell provides a WMI interface that can be used for querying and modifying BIOS settings on their hardware models (only applies to models released after calendar year 2018). This means that we can use PowerShell to directly view and edit BIOS settings without the need for a vendor specific program. This script uses 7 of the Dell provided WMI classes.

The first WMI class is EnumerationAttribute. It is located in the root\dcim\sysman\biosattributes namespace. This class is used to return a list of all BIOS settings with a set of predefined values. This list includes the majority of the configurable BIOS settings.

#Connect to the EnumerationAttribute WMI class
$Enumeration = Get-CimInstance -Namespace root\dcim\sysman\biosattributes -ClassName EnumerationAttribute

#Return a list of settings
$Enumeration | Select-Object AttributeName,CurrentValue,PossibleValue

#Return a specific setting and value
$Enumeration | Where-Object AttributeName -eq "WakeOnLan" | Select-Object AttributeName,CurrentValue,PossibleValue

The second WMI class is IntegerAttribute. It is located in the root\dcim\sysman\biosattributes namespace. This class is used to return a list of all BIOS settings with an integer value. This list includes things like the power on hours and password length requirements.

#Connect to the IntegerAttribute WMI class
$Integer = Get-CimInstance -Namespace root\dcim\sysman\biosattributes -ClassName IntegerAttribute

#Return a list of settings
$Integer | Select-Object AttributeName,CurrentValue,PossibleValue

#Return a specific setting and value
$Integer | Where-Object AttributeName -eq "AutoOnHr" | Select-Object AttributeName,CurrentValue,PossibleValue

The third WMI class is StringAttribute. It is located in the root\dcim\sysman\biosattributes namespace. This class is used to return a list of all BIOS settings with a string value. This list includes things like the service tag and asset tag.

#Connect to the StringAttribute WMI class
$String = Get-CimInstance -Namespace root\dcim\sysman\biosattributes -ClassName StringAttribute

#Return a list of settings
$String | Select-Object AttributeName,CurrentValue,PossibleValue

#Return a specific setting and value
$String | Where-Object AttributeName -eq "SvcTag" | Select-Object AttributeName,CurrentValue,PossibleValue

The fourth WMI class is BIOSAttributeInterface. It is located in the root\dcim\sysman\biosattributes namespace. This class contains a method called SetAttribute which is used to modify BIOS settings. This class also contains a method called SetBIOSDefaults which can be used to set all BIOS settings to default values.

#Connect to the BIOSAttributeInterface WMI class
$AttributeInterface = Get-WmiObject -Namespace root\dcim\sysman\biosattributes -Class BIOSAttributeInterface

#Set a specific BIOS setting (BIOS password is not set)
$AttributeInterface.SetAttribute(0,0,0,"SettingName","SettingValue")

#Set a specific BIOS setting (BIOS password is set)
$AttributeInterface.SetAttribute(1,$Bytes.Length,$Bytes,"SettingName","SettingValue")

<# BIOS Defaults Value Reference
   0 - BuiltInSafeDefaults
   1 - LastKnownGood
   2 - Factory
   3 - UserConf1
   4 - UserConf2
#>

#Set all BIOS settings to factory defaults (BIOS password is not set)
$AttributeInterface.SetBIOSDefaults(0,0,0,2) 

The fifth WMI class is BootOrder. It is located in the root\dcim\sysman\biosattributes namespace. This class is used to return the boot order settings.

#Connect to the BootOrder WMI class
$BootOrder = Get-CimInstance -Namespace root\dcim\sysman\biosattributes -ClassName BootOrder

#Return the current boot order settings
$BootOrder | Select-Object BootListType,BootOrder

The sixth WMI class is BootOrderInterface. It is located in the root\dcim\sysman\biosattributes namespace. This class contains a method called Set which is used to modify the boot order settings.

#Connect to the BootOrderInterface WMI class
$BootOrderInterface = Get-WmiObject -Namespace root\dcim\sysman\biosattributes -Class BootOrderInterface

#Save the new boot order to a variable
$NewBootOrder = "Windows Boot Manager","Onboard NIC(IPV4)","Onboard NIC(IPV6)"

#Set the UEFI boot order (BIOS password is not set)
$BootOrderInterface.Set(0,0,0,"UEFI",$NewBootOrder.Count,$NewBootOrder)

#Set the UEFI boot order (BIOS password is set)
$BootOrderInterface.Set(1,$Bytes.Length,$Bytes,"UEFI",$NewBootOrder.Count,$NewBootOrder)

The seventh WMI class is SecurityInterface. It is located in the root\dcim\sysman\wmisecurity namespace. This class contains a method called SetNewPassword. In this script this method is used to test the existing BIOS password. For more information about this class, see this post Dell BIOS Password Management – WMI.

BIOS Password Encoding

The above information contains examples for modifying the BIOS with and without an existing BIOS password. When a BIOS password is set, it must first be encoded before it can be passed to a method.

$Password = "ExamplePass"
$Encoder = New-Object System.Text.UTF8Encoding
$Bytes = $Encoder.GetBytes($Password)

Each of the methods used to modify BIOS settings starts with 3 arguments. The 3 arguments are:

  • The type of text
  • The length of the byte array
  • The byte array containing the encoded password

When no password is set, these arguments are set to 0,0,0. The type of text is 0 (None), the length of the byte array is 0, and the byte array itself is 0.

When a password is set, these arguments are set to 1,$Bytes.Length,$Bytes. The type of text is 1 (plain text), the length of the byte array is set to $Bytes.Length, and the byte array is $Bytes.

Status Codes

For reference, when calling the Set or SetAttribute or SetBIOSDefaults methods, the possible status codes are:

  • 0 – Success
  • 1 – Failed
  • 2 – Invalid Parameter
  • 3 – Access Denied
  • 4 – Not Supported
  • 5 – Memory Error
  • 6 – Protocol Error

For more detailed information on the Dell WMI interface, refer to the official documentation. http://downloads.dell.com/manuals/common/dell-agentless-client-manageability.pdf

Manage-DellBiosSettings-WMI.ps1

This script takes the basic commands and adds logic to allow for a more automated settings management process. The script has 7 parameters.

  • GetSettings – Use this parameter to instruct the script to generate a list of all current BIOS settings. The settings will be displayed on the screen by default.
  • SetSettings – Use this parameter to instruct the script to set specific BIOS settings. Settings can be specified either in the body of the script or from a CSV file.
  • CsvPath – Use this parameter to specify the location of a CSV file. If used with the GetSettings switch, this acts as the location where a list of current BIOS settings will be saved. If used with the SetSettings switch, this acts as the location where the script will read BIOS settings to be set from. Using this switch with the SetSettings switch will also cause the script to ignore any settings specified in the body of the script.
  • AdminPassword – Used to specify the BIOS password.
  • SetDefaults – Use this parameter to instruct the script to set all BIOS settings to default values. Acceptable values for this parameter are (BuiltInSafeDefaults, LastKnownGood, Factory, UserConf1, UserConf2)
  • SetBootOrder – Used to specify the desired boot order to be set on the system. Values should be specified in a comma separated list.
  • BootMode – Used to specify which boot mode the boot order should be applied to. Acceptable values for this parameter are (UEFI, Legacy)

When using the script to set settings, the list of settings can either be specified in the script itself or in a CSV file. To specify settings in the script, look for the $Settings array near the top of the script. The settings should be in the format of “Setting Name,Setting Value”

#List of settings to be configured =================================
#===================================================================
$Settings = (
    "FingerprintReader,Enabled",
    "FnLock,Enabled",
    "IntegratedAudio,Enabled",
    "NumLock,Enabled",
    "SecureBoot,Enabled",
    "TpmActivation,Enabled",
    "TpmClear,Disabled",
    "TpmPpiClearOverride,Disabled",
    "TpmPpiDpo,Disabled",
    "TpmPpiPo,Enabled",
    "TpmSecurity,Enabled",
    "UefiNwStack,Enabled",
    "Virtualization,Enabled",
    "VtForDirectIo,Enabled",
    "WakeOnLan,Disabled"
)
#===================================================================
#===================================================================

A full list of configurable settings can be exported from a device by calling the script with the GetSettings parameter. The CsvPath parameter can also be specified to output the list of settings to a CSV file.

When the script runs, it will write to a log file. By default, this log file will be named Manage-DellBiosSettings-WMI.Log. If the script is being run during a task sequence, the log file will be located in the _SMSTSLogPath. Otherwise, the log file will be located in ProgramData\ConfigJonScripts\Dell. The log file name and path can be changed using the LogFile parameter. Note that the log file path will always be set to _SMSTSLogPath when run during a task sequence.

The script has logic built-in to detect if settings were already set correctly, were successfully set, failed to set, or were not found on the device. The script will output these counts to the screen at the end. More detailed information about the settings will be written to the log file.

I have included a few example settings files in my GitHub. These settings files contain commonly configured Dell BIOS settings.

  • Settings_CSV_SecureBoot.csv – Contains settings for enabling UEFI and SecureBoot
  • Settings_CSV_TPM.csv – Contains settings for enabling and activating TPM
  • Settings_CSV_General.csv – Contains other common settings
  • Settings_In-Script_All.txt – Contains common settings formatted for use in the body of the script

Examples

The script can be run as a standalone script in Windows, or as part of a Configuration Manager task sequence. It can also be run in the full Windows OS or in WinPE.

Here are a few examples of calling the script from a PowerShell prompt.

#Set BIOS settings supplied in the script
Manage-DellBiosSettings-WMI.ps1 -SetSettings -AdminPassword ExamplePassword

#Set BIOS settings supplied in a CSV file
Manage-DellBiosSettings-WMI.ps1 -SetSettings -CsvPath C:\Temp\Settings.csv -AdminPassword ExamplePassword

#Set all BIOS settings to factory default values
Manage-DellBiosSettings-WMI.ps1 -SetDefaults Factory -AdminPassword ExamplePassword

#Set the UEFI boot order
Manage-DellBiosSettings-WMI.ps1 -SetBootOrder "Windows Boot Manager","Onboard NIC(IPV4)","Onboard NIC(IPV6)" -BootMode UEFI -AdminPassword ExamplePassword

#Set BIOS settings supplied in the script and set the UEFI boot order
Manage-DellBiosSettings-WMI.ps1 -SetSettings -SetBootOrder "Windows Boot Manager","Onboard NIC(IPV4)","Onboard NIC(IPV6)" -BootMode UEFI -AdminPassword ExamplePassword

#Output a list of current BIOS settings to the screen
Manage-DellBiosSettings-WMI.ps1 -GetSettings

#Output a list of current BIOS settings to a CSV file
Manage-DellBiosSettings-WMI.ps1 -GetSettings -CsvPath C:\Temp\Settings.csv

Here is an example of calling the script during a task sequence. In this example the settings are specified in the body of the script, so the script can be stored directly in the task sequence step. Also the admin password is set, so the AdminPassword parameter is specified.

In this second example, the script is being called from a package and the settings are being supplied from a CSV file.

Notes and Additional Reading

  • When booting into WinPE, the Dell WMI classes take a couple of minutes to install or initialize. Because of this, if the script fails to connect to a WMI class, it will retry every 30 seconds for 3 minutes before failing.
  • The GetSettings parameter does not write the current Boot Order to the screen or to the CSV. This information is recorded in the log file. I’m hoping to improve this functionality in the future.

For information on configuring Dell BIOS passwords using PowerShell and WMI, see my post Dell BIOS Password Management – WMI. If you need to support older dell hardware that does not support the WMI classes, see my other Dell posts Dell BIOS Password Management – PSModule and Dell BIOS Settings Management – PSModule. If you’re looking for other options for managing Dell BIOS settings, check out the Dell Command Configure utility.