Today I will write me first English private Blog to share with you my project experience.
My learning since a couple of years are everyone is talking about BIOS passwords as part of security but in real life the most BIOS password will be set one time and never change in the time of using the device. With modern work and more mobility, it would be more and more complicated to change BIOS settings because not all devices are in your own network. I will show you in this blog how you could set a BIOS password on a device by PowerShell and Configuration Service Provider (CSP). All scripts are free, and you could use this own your risk without support.
BIOS password by PowerShell
There are a lot of different options to set a BIOS password on a Dell device, like WMI, Dell Command | PowerShell Provider and Dell Command | Configure.
In this Blog I will use the Dell Command | Monitor (DCM) because DCM can do more than BIOS settings e.g. Hardware monitoring by SNMP or Microsoft Event Viewer.
Download Software: https://www.dell.com/support/kbdoc/en-us/000177080/dell-command-monitor
If you click on extract at the installation GUI you will get the MSI for this software which make the deployment much easier.

Documentation: https://www.dell.com/support/home/en-us/product-support/product/command-monitor/docs
The easiest way to modify BIOS settings in a full OS installation is by using PowerShell. DCM is offering a new class called DCIM_BIOSService which allow us to change BIOS settings.
We have talked about setting a BIOS password, but as a first step I would recommend to check if an BIOS password is already set. DCM is offering an own class DCIM_BIOSPassword which checks the status of AdminPwd and SystemPwd.
Today we are working with AdminPwd setting only so I will check this value on my machine first.
Get-CimInstance -Namespace root\dcim\sysman -ClassName DCIM_BIOSPassword -Filter "AttributeName='AdminPwd'" | select isSet
The result will be true (password is set) or false (password is not set).
In our first scenario we assume that no password is set. With the following string set you can set AdminPwd on a machine (Note: You need to start PowerShell ISE in Admin Mode)
Get-CimInstance -Namespace root\dcim\sysman -ClassName DCIM_BIOSService | Invoke-CimMethod -MethodName SetBIOSAttributes -Arguments @{AttributeName=@("AdminPwd");AttributeValue=@(“Your Password”)}
If anything is all right you get a set result 0.
The method may return the following errors:
0 (Success)—If the method is completed successfully.
1 (Failure) — If
- the possible value is out of range. For example, trying to set value other than 0 to 23 for the attribute Autonoe Hour.
- it is an unsupported BIOS operation. For example, trying to enable TPM when TPM is disabled.
2 (Authentication failure)—If the BIOS password is incorrect.
4294967295 (Invalid Possible Value)—If the possible value is invalid; or read-only.
Ok 😊 now we have set a AdminPwd on the machine, but we would like to change this. DCM is offering an attribute with the name AuthorizationToken. The AuthorizationToken is your old AdminPwd and need for authorization of change.
Get-CimInstance -Namespace root\dcim\sysman -ClassName DCIM_BIOSService | Invoke-CimMethod -MethodName SetBIOSAttributes -Arguments @{AttributeName=@("AdminPwd");AttributeValue=@(“Your New Password”);AuthorizationToken=”Your Old Password”}
We have set and change a BIOS Password now but if you have enterprise environment, we need more automation.
I have written the following script for one of my customers. The script will set a new password if the device has no password and change it if there is an existing password. The most of customer using a password on a machine generation which are equal on all machines. From the point of security there is a risk. The script generates a unique password for each device, based on two parts. The first one is the ServiceTag and second a static key. If you don´t want use ServiceTag you could use every unique identifier of the machine like UUID, etc.
For the password change I have a problem where I can store the password of the device? I am using the Win10 Registry and stored the information on the machine locally. Yes, I am knowing it is not high secure, but you need access to the device, and you need to know which Keys are set and needed to have the password of the BIOS.
If the community have any great ideas where it is possible to store the information without need external licenses and it could be used if the device is in internal network or in internet, please let me know your ideas. The Password is split in two parts, so I am not spending time to encrypt these values, but it is on my list to test that as well in the future.
All scripts and Workspace One Sensors you can download here: https://github.com/SvenRiebe/BIOSPassword
######################################### # Name: PowerShell Script for BIOS AdminPW setting on Dell Devices # # Description: PowerShell using Dell Command | Monitor for setting AdminPW on the machine. The script checking if any PW is existing and can setup new and change PW. # # Author: Sven Riebe Twitter: @SvenRiebe # Version: 1.2.2 # Status: Test <# 1.2.2 add check folder c:\temp if not there new-item for $Path log path is now a variable $Path #> #Variable for change $PWKey = "Your Static Key" #Variable not for change # Check if BIOS Admin PW is set $PWset = Get-CimInstance -Namespace root\dcim\sysman -ClassName dcim_BIOSPassword -Filter "AttributeName='AdminPwd'" | select -ExpandProperty isSet # Return code form Dell Command | Monitor for setting Admin PW - Value 0 = OK rest issue is happen $PWstatus = "" # Computername of system $DeviceName = Get-CimInstance -ClassName win32_computersystem | select -ExpandProperty Name # OEM Serial number of device $serviceTag = Get-CimInstance -ClassName win32_bios | select -ExpandProperty SerialNumber # will be used as BIOS Admin PW build from $ServiceTag and $PWKey $AdminPw = "$serviceTag$PWKey" # actual system date $Date = Get-Date # Check if registry path is availible $RegKeyexist = Test-Path 'HKLM:\SOFTWARE\Dell\BIOS' # Value HKLM:\SOFTWARE\Dell\BIOS BIOS use value from registry $PWKeyOld = "" # Value HKLM:\SOFTWARE\Dell\BIOS ServiceTag use value from registry $serviceTagOld = "" # Old Admin PW generate by registry later $AdminPwOld = "" # Path for logging $PATH = "C:\Temp\" #check if c:\temp exist if (!(Test-Path $PATH)) {New-Item -Path $PATH -ItemType Directory} #Logging device data Write-Output $env:COMPUTERNAME | out-file "$PATH\BIOS_Profile.txt" -Append Write-Output "ServiceTag: $serviceTag" | out-file "$PATH\BIOS_Profile.txt" -Append Write-Output "Profile install at: $Date" | out-file "$PATH\BIOS_Profile.txt" -Append #Checking RegistryKey availbility if ($RegKeyexist -eq "True") { $PWKeyOld = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Dell\BIOS\' -Name BIOS | select -ExpandProperty BIOS $serviceTagOld = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Dell\BIOS\' -Name ServiceTag | select -ExpandProperty ServiceTag $AdminPwOld = "$serviceTagOld$PWKeyOld" Write-Output "RegKey exist" | out-file "$PATH\BIOS_Profile.txt" -Append } Else { New-Item -path "hklm:\software\Dell\BIOS" -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "BIOS" -value "" -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "ServiceTag" -value "" -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Date" -value "" -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Status" -value "" -type string -Force Write-Output "RegKey is set" | out-file "$PATH\BIOS_Profile.txt" -Append } #Checking AdminPW is not set on the machine If ($PWset -eq $false) { $PWstatus = Get-CimInstance -Namespace root\dcim\sysman -ClassName DCIM_BIOSService | Invoke-CimMethod -MethodName SetBIOSAttributes -Arguments @{AttributeName=@("AdminPwd");AttributeValue=@($AdminPw)} | select -ExpandProperty Setresult #Setting of AdminPW was successful If ($PWstatus -eq 0) { New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "BIOS" -value $PWKey -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "ServiceTag" -value $serviceTag -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Date" -value $Date -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Status" -value "Ready" -type string -Force Write-Output "Password is set successful for first time" | out-file "$PATH\BIOS_Profile.txt" -Append } #Setting of AdminPW was unsuccessful else { New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Status" -value "Error" -type string -Force Write-Output "Error Passwort could not set" | out-file "$PATH\BIOS_Profile.txt" -Append } } #Checking AdminPW is exsting on the machine else { #Compare old and new AdminPW are equal If ($AdminPw -eq $AdminPwOld) { Write-Output "Password no change" | out-file "$PATH\BIOS_Profile.txt" -Append } #Old and new AdminPW are different make AdminPW change else { $PWstatus = Get-CimInstance -Namespace root\dcim\sysman -ClassName DCIM_BIOSService | Invoke-CimMethod -MethodName SetBIOSAttributes -Arguments @{AttributeName=@("AdminPwd");AttributeValue=@($AdminPw);AuthorizationToken=$AdminPwOld} | select -ExpandProperty Setresult #Checking if change was successful If($PWstatus -eq 0) { Write-Output "Password is change successful" | out-file "$PATH\BIOS_Profile.txt" -Append New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Status" -value "Ready" -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "BIOS" -value $PWKey -type string -Force } #Checking if change was unsuccessful. Most reason is there is a AdminPW is set by user or admin before the profile is enrolled else { New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Status" -value "Unknown" -type string -Force Write-Output "Unknown password on machine. This need to delete first" | out-file "$PATH\BIOS_Profile.txt" -Append } } }
The script is storing all relevant information in the Registry.
BIOS = Static part of Password
Date = Date of setting/deleting Password
ServiceTag = Unique Part of Password (in my case I use the Serial No. Of the device)
Status = result of setting
Unknown = There is an existing password but not set by this script
Error = general issue e.g. Password does not match password policy
Ready = Success
Delete = Password is deleted by script

For a better troubleshooting the script is writing a log in Folder Temp which shows me when does the script execute on the machine and what is the result. No confidential information’s are stored in this file.

If you need to delete the Password, e.g. retiring device, etc. I have made a second script. The success will be stored in Registry and Log file as well.
######################################### # Name: Powershell Script for BIOS AdminPW delete on Dell Devices # # Description: Powershell using Dell Command | Monitor for deleting AdminPW on the machine. The script checking if any PW is exist and can delete known PW on the machine. # # Author: Sven Riebe Twitter: @SvenRiebe # Version: 1.0.2 # Status: Test #Variable not for change $PWset = Get-CimInstance -Namespace root\dcim\sysman -ClassName dcim_BIOSPassword -Filter "AttributeName='AdminPwd'" | select -ExpandProperty isSet $PWstatus = "" $DeviceName = Get-CimInstance -ClassName win32_computersystem | select -ExpandProperty Name $serviceTag = Get-CimInstance -ClassName win32_bios | select -ExpandProperty SerialNumber $AdminPw = "$serviceTag$PWKey" $Date = Get-Date $RegKeyexist = Test-Path 'HKLM:\SOFTWARE\Dell\BIOS' $PWKeyOld = "" $serviceTagOld = "" $AdminPwOld = "" #Logging device data Write-Output $env:COMPUTERNAME | out-file "c:\temp\BIOS_Profile.txt" -Append Write-Output "ServiceTag: $serviceTag" | out-file "c:\temp\BIOS_Profile.txt" -Append Write-Output "Profile install at: $Date" | out-file "c:\temp\BIOS_Profile.txt" -Append #Generate exiting PW from Registry $PWKeyOld = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Dell\BIOS\' -Name BIOS | select -ExpandProperty BIOS $serviceTagOld = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Dell\BIOS\' -Name ServiceTag | select -ExpandProperty ServiceTag $AdminPwOld = "$serviceTagOld$PWKeyOld" #Checking AdminPW is not set on the machine If ($PWset -eq $false) { Write-Output "No password is set on machine" | out-file "c:\temp\BIOS_Profile.txt" -Append } else { $PWstatus = Get-CimInstance -Namespace root\dcim\sysman -ClassName DCIM_BIOSService | Invoke-CimMethod -MethodName SetBIOSAttributes -Arguments @{AttributeName=@("AdminPwd");AttributeValue=@("");AuthorizationToken=$AdminPwOld} | select -ExpandProperty Setresult #Checking if change was successful If($PWstatus -eq 0) { Write-Output "Password is delete from the machine" | out-file "c:\temp\BIOS_Profile.txt" -Append New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "BIOS" -value "" -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "ServiceTag" -value "" -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Date" -value $Date -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Status" -value "Delete" -type string -Force } #Checking if change was unsuccessful. Most reason is there is a AdminPW is set by user or admin before the profile is enrolled else { New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Status" -value "Unknown" -type string -Force Write-Output "Unknown password on machine. This need to delete first" | out-file "c:\temp\BIOS_Profile.txt" -Append } }
You can run these scripts in different environments. For my environment I am using Workspace One. I want to be managing and control the status of deployment/undeployment of the password.
My first step is to encode the PowerShell script so that I can deploy this as CSP with include PowerShell.
There is an easy way for encoding. Camille Daybay (VMware) made a script which transfer the script in an xml. All you need to will find here.
https://github.com/CamilleDebay/Scripts/blob/master/UEM/Create-PowerShellProfile.ps1
After we have encoded the two script, we could make a custom profile in Workspace One UEM.
Start a new Profile and give them a specific name and assign a smart group with dell devices.

Switch to Custom settings and change Target to Workspace One Intelligent Hub and deselect Make Commands Atomic.
Now you can copy the Password setting xml information in Install Settings and Password delete xml in Remove settings.

Now click Save and Publish and the password will set on all devices of this smart group.

I have in my environment as well a data collection and orchestration tool Workspace One Intelligence. All my data´s are stored locally but how you could use these information’s for support cases?
I have created Workspace One Sensors which help me to get all data´s on a central place.
There are three relevant information´s I need to know.
- What is the password of this BIOS?
- When does is deployed to the device?
- Status of deployment (Unknown, Error, Ready, Delete)

Sensor BIOS_Profile_Date
################################################################## # # Name: Sensor Dell status change date AdminPW by BIOS Profile # # Author: Sven Riebe # # Status: test # # Version 1.0.0 # # Date: 08-06-2021 $BiosProfilDate = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Dell\BIOS\' -Name Date | select -ExpandProperty Date Write-Output $BiosProfilDate
Sensor BIOS_Profile_Password
# Description # Return Type: String # Execution Context: System ################################################################## # # Name: Sensor Dell actual AdminPW on the Device by BIOS Profile # # Author: Sven Riebe # # Status: test # # Version 1.0.1 # # Date: 09-14-2021 <# 1.0.1 cover Static and Random PW #> #Variables $HashKeyCheck = "" $PWKey = "" $serviceTag = "" $AdminPw = "" # this function is from https://stackoverflow.com/questions/5648931/test-if-registry-value-exists function Test-RegistryValue { param ( [parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()]$Path, [parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()]$Value ) try { Get-ItemProperty -Path $Path | Select-Object -ExpandProperty $Value -ErrorAction Stop | Out-Null return $true } catch { return $false } } $HashKeyCheck = Test-RegistryValue -Path HKLM:\SOFTWARE\Dell\BIOS -Value Hash If ($HashKeyCheck -match "false") { $PWKey = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Dell\BIOS\' -Name BIOS | select -ExpandProperty BIOS $serviceTag = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Dell\BIOS\' -Name ServiceTag | select -ExpandProperty ServiceTag $AdminPw = "$serviceTag$PWKey" } else { $AdminPw = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Dell\BIOS\' -Name Hash | select -ExpandProperty Hash }
Sensor BIOS_Profile_Status
################################################################## # # Name: Sensor Dell status AdminPW by BIOS Profile # # Author: Sven Riebe # # Status: test # # Version 1.0.0 # # Date: 08-06-2021 $BiosProfilStatus = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Dell\BIOS\' -Name Status | select -ExpandProperty Status Write-Output $BiosProfilStatus
You will find these three sensors in the same repository as the other scripts.
It takes some time but now I can use Dashboards and Reports to work with the device BIOS password.
Status of BIOS Password status

Audit Report
If you want to have an audit report, you can do this as well. You get a view about status and date of change, e.g. if you have a policy which rules all passwords need to be change all three month you could make filters to show you all relevant devices.

If you like more security I am make a new script which working with a random generated password. My learning with Workspace One and custom profile, it will run at each start of the machine. This is a huge problem because every restart the machine gets a new BIOS password if anything is going wrong there are lot of device with unknown BIOS passwords. To be secure that the profile not generated each start a BIOS password I am making a time loop for 180 days. What does this mean? If the BIOS password not older then 179 days, the password change is skipped after 180 days it will be changed. The random password will be stored in Win10 Registry as well in the value Hash.
The PW generator is base on the following source code https://gist.github.com/indented-automation/2093bd088d59b362ec2a5b81a14ba84e and the function check if a Reg Key available by https://stackoverflow.com/questions/5648931/test-if-registry-value-exists.
Thx for sharing 😊
I have integrated both functions in my script base on the existing version with a time check of the last BIOS password check.
######################################### # Name: Powershell Script for BIOS AdminPW setting on Dell Devices # # Description: Powershell using Dell Command | Monitor for setting AdminPW with random PW on the machine. The script checking if any PW is exist and can setup new and change PW. # # Author: Sven Riebe Twitter: @SvenRiebe # Version: 1.0.3 # Status: Test <# 1.0.1 add check folder c:\temp if not there new-item for $Path log path is now a variable $Path 1.0.2 move request for AdminPwold from line 104 to 168 additional setting RegKey "Hash" at unsuccessfull to be secure that Hash is not empty if AdminPWOld asking for 1.0.3 checking if password older than 180 days before a new PW will deployed New Function Test-RegistryValue Adjust special char to use only Char are same keyboard position on DE / US Keyboard to make it easier for manuel typing later #> #Variable you can change ## Days a password need exist before it will be change $PWTime = "180" ## Logging Path $PATH = "C:\Temp\" ## length of your BIOS Password max 32 char. The BIOS supporting only a max 0f 32 Characters. Recommand to set 12. $PWLength = 12 # This function is from https://gist.github.com/indented-automation/2093bd088d59b362ec2a5b81a14ba84e function New-Password { [CmdletBinding()] [OutputType([String])] param ( # The length of the password which should be created. [Parameter(ValueFromPipeline)] [ValidateRange(8, 255)] [Int32]$Length = 10, # The character sets the password may contain. A password will contain at least one of each of the characters. [String[]]$CharacterSet = ('abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', '0123456789', '!$%'), <# For Dell 7th Generation and newer client products, you should use the following guidelines: BIOS passwords can include: The following special characters (ASCII 0x21 – 0x2f): ! " # $ % & ' ( ) * + , - . / A number (ASCII 0x30 – 0x39): 0 1 2 3 4 5 6 7 8 9 One of the following special characters (ASCII 0x3a – 0x40): : ; < = > ? @ A capital English letter (ASCII 0x41 – 0x5a): A - Z One of the following special characters (ASCII 0x5b – 0x60): [ \ ] ^ _ ` A lower case English letter (ASCII 0x61 – 0x7a): a - z One of the following special characters (ASCII 0x7b – 0x7e): { | } ~ #> # The number of characters to select from each character set. [Int32[]]$CharacterSetCount = (@(1) * $CharacterSet.Count) ) begin { $bytes = [Byte[]]::new(4) $rng = [System.Security.Cryptography.RandomNumberGenerator]::Create() $rng.GetBytes($bytes) $seed = [System.BitConverter]::ToInt32($bytes, 0) $rnd = [Random]::new($seed) if ($CharacterSet.Count -ne $CharacterSetCount.Count) { throw "The number of items in -CharacterSet needs to match the number of items in -CharacterSetCount" } $allCharacterSets = [String]::Concat($CharacterSet) } process { try { $requiredCharLength = 0 foreach ($i in $CharacterSetCount) { $requiredCharLength += $i } if ($requiredCharLength -gt $Length) { throw "The sum of characters specified by CharacterSetCount is higher than the desired password length" } $password = [Char[]]::new($Length) $index = 0 for ($i = 0; $i -lt $CharacterSet.Count; $i++) { for ($j = 0; $j -lt $CharacterSetCount[$i]; $j++) { $password[$index++] = $CharacterSet[$i][$rnd.Next($CharacterSet[$i].Length)] } } for ($i = $index; $i -lt $Length; $i++) { $password[$index++] = $allCharacterSets[$rnd.Next($allCharacterSets.Length)] } # Fisher-Yates shuffle for ($i = $Length; $i -gt 0; $i--) { $n = $i - 1 $m = $rnd.Next($i) $j = $password[$m] $password[$m] = $password[$n] $password[$n] = $j } [String]::new($password) } catch { Write-Error -ErrorRecord $_ } } } # this function is from https://stackoverflow.com/questions/5648931/test-if-registry-value-exists function Test-RegistryValue { param ( [parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()]$Path, [parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()]$Value ) try { Get-ItemProperty -Path $Path | Select-Object -ExpandProperty $Value -ErrorAction Stop | Out-Null return $true } catch { return $false } } #Variable not for change $PWset = Get-CimInstance -Namespace root\dcim\sysman -ClassName dcim_BIOSPassword -Filter "AttributeName='AdminPwd'" | select -ExpandProperty isSet $PWstatus = "" $DeviceName = Get-CimInstance -ClassName win32_computersystem | select -ExpandProperty Name $serviceTag = Get-CimInstance -ClassName win32_bios | select -ExpandProperty SerialNumber $AdminPw = "" $Date = Get-Date -Format yyyy-MM-dd $DateExpire = "" $RegKeyexist = Test-Path 'HKLM:\SOFTWARE\Dell\BIOS' $PWKeyOld = "" $serviceTagOld = "" $AdminPwOld = "" $DateTransfer = (Get-Date).AddDays($PWTime) $BIOSVersion = Get-CimInstance -ClassName win32_bios | select -ExpandProperty SMBIOSBIOSVersion #check if c:\temp exist if (!(Test-Path $PATH)) {New-Item -Path $PATH -ItemType Directory} #Logging device data Write-Output $env:COMPUTERNAME | out-file "$Path\BIOS_Profile.txt" -Append Write-Output "ServiceTag: $serviceTag" | out-file "$Path\BIOS_Profile.txt" -Append Write-Output "Profile install at: $Date" | out-file "$Path\BIOS_Profile.txt" -Append #Checking RegistryKey availbility if ($RegKeyexist -eq "True") { Write-Output "RegKey exist" | out-file "$Path\BIOS_Profile.txt" -Append $RegKeyCheckUpdate = Test-RegistryValue -Path HKLM:\SOFTWARE\Dell\BIOS -Value Update If ($RegKeyCheckUpdate -eq $false) { New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Update" -value $Date -type string -Force Write-Output "RegKey Update generated" | out-file "$Path\BIOS_Profile.txt" -Append } else { Write-Output "Field Update exist" | out-file "$Path\BIOS_Profile.txt" -Append } } Else { New-Item -path "hklm:\software\Dell\BIOS" -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "BIOS" -value $BIOSVersion -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "ServiceTag" -value "" -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Date" -value "" -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Status" -value "" -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Hash" -value "" -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Update" -value $Date -type string -Force Write-Output "RegKey is set" | out-file "$Path\BIOS_Profile.txt" -Append } #check if BIOS password older that 180 days $DateExpire = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Dell\BIOS\' -Name Update | select -ExpandProperty Update if ((Get-Date -Format yyyyMMdd) -ge (Get-Date $DateExpire -Format yyyyMMdd)) { $AdminPw = New-Password -Length $PWLength # only for security need to delete if script is working stable Write-Output "Password: $AdminPW" | out-file "$Path\BIOS_Profile.txt" -Append #Checking AdminPW is not set on the machine If ($PWset -eq $false) { $PWstatus = Get-CimInstance -Namespace root\dcim\sysman -ClassName DCIM_BIOSService | Invoke-CimMethod -MethodName SetBIOSAttributes -Arguments @{AttributeName=@("AdminPwd");AttributeValue=@($AdminPw)} | select -ExpandProperty Setresult #Setting of AdminPW was successful If ($PWstatus -eq 0) { #$DateTransfer = (Get-Date).AddDays($PWTime) New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "BIOS" -value $BIOSVersion -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "ServiceTag" -value $serviceTag -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Date" -value $Date -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Status" -value "Ready" -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Hash" -value $AdminPw -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Update" -value (Get-Date $DateTransfer -Format yyyy-MM-dd) -type string -Force Write-Output "Password is set successful for first time" | out-file "$Path\BIOS_Profile.txt" -Append } #Setting of AdminPW was unsuccessful else { New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Status" -value "Error" -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Hash" -value $AdminPw -type string -Force Write-Output "Error Passwort could not set" | out-file "$Path\BIOS_Profile.txt" -Append } } #Checking AdminPW is exsting on the machine else { #Compare old and new AdminPW are equal $AdminPwOld = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Dell\BIOS\' -Name Hash | select -ExpandProperty Hash If ($AdminPw -eq $AdminPwOld) { Write-Output "Password no change" | out-file "$Path\BIOS_Profile.txt" -Append } #Old and new AdminPW are different make AdminPW change else { $PWstatus = Get-CimInstance -Namespace root\dcim\sysman -ClassName DCIM_BIOSService | Invoke-CimMethod -MethodName SetBIOSAttributes -Arguments @{AttributeName=@("AdminPwd");AttributeValue=@($AdminPw);AuthorizationToken=$AdminPwOld} | select -ExpandProperty Setresult #Checking if change was successful If($PWstatus -eq 0) { New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Status" -value "Ready" -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "BIOS" -value $BIOSVersion -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Hash" -value $AdminPw -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Date" -value $Date -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Update" -value (Get-Date $DateTransfer -Format yyyy-MM-dd) -type string -Force Write-Output "Password is change successful" | out-file "$Path\BIOS_Profile.txt" -Append } #Checking if change was unsuccessful. Most reason is there is a AdminPW is set by user or admin before the profile is enrolled else { New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Status" -value "Unknown" -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Date" -value $Date -type string -Force Write-Output "Unknown password on machine. This need to delete first" | out-file "$Path\BIOS_Profile.txt" -Append } } } } else { Write-Output "Password is not older than 180 Days. No Password Change" | out-file "$Path\BIOS_Profile.txt" -Append }
The process to encode and making a custom profile is the same as before. You will need a uninstall script as well. We are using now a other Registry field as before to the script need a little bit tuning.
######################################### # Name: Powershell Script for BIOS AdminPW random delete on Dell Devices # # Description: Powershell using Dell Command | Monitor for deleting AdminPW on the machine. The script checking if any PW is exist and can delete known PW on the machine. # # Author: Sven Riebe Twitter: @SvenRiebe # Version: 1.0.1 # Status: Test <# 1.0.1 reset RegKey Update to date to day #> #Variable not for change $PWset = Get-CimInstance -Namespace root\dcim\sysman -ClassName dcim_BIOSPassword -Filter "AttributeName='AdminPwd'" | select -ExpandProperty isSet $BIOSVersion = Get-CimInstance -ClassName win32_bios | select -ExpandProperty SMBIOSBIOSVersion $PWstatus = "" $DeviceName = Get-CimInstance -ClassName win32_computersystem | select -ExpandProperty Name $serviceTag = Get-CimInstance -ClassName win32_bios | select -ExpandProperty SerialNumber $AdminPw = "$serviceTag$PWKey" $Date = Get-Date $RegKeyexist = Test-Path 'HKLM:\SOFTWARE\Dell\BIOS' $PWKeyOld = "" $serviceTagOld = "" $AdminPwOld = "" #Logging device data Write-Output $env:COMPUTERNAME | out-file "c:\temp\BIOS_Profile.txt" -Append Write-Output "ServiceTag: $serviceTag" | out-file "c:\temp\BIOS_Profile.txt" -Append Write-Output "Profile install at: $Date" | out-file "c:\temp\BIOS_Profile.txt" -Append #Generate exiting PW from Registry $AdminPwOld = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Dell\BIOS\' -Name Hash | select -ExpandProperty Hash #Checking AdminPW is not set on the machine If ($PWset -eq $false) { Write-Output "No password is set on machine" | out-file "c:\temp\BIOS_Profile.txt" -Append } else { $PWstatus = Get-CimInstance -Namespace root\dcim\sysman -ClassName DCIM_BIOSService | Invoke-CimMethod -MethodName SetBIOSAttributes -Arguments @{AttributeName=@("AdminPwd");AttributeValue=@("");AuthorizationToken=$AdminPwOld} | select -ExpandProperty Setresult #Checking if change was successful If($PWstatus -eq 0) { Write-Output "Password is delete from the machine" | out-file "c:\temp\BIOS_Profile.txt" -Append New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "BIOS" -value $BIOSVersion -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "ServiceTag" -value $serviceTag -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Date" -value $Date -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Hash" -value "" -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Status" -value "Delete" -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Update" -value (Get-Date -Format yyyy-MM-dd) -type string -Force } #Checking if change was unsuccessful. Most reason is there is a AdminPW is set by user or admin before the profile is enrolled else { New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Date" -value $Date -type string -Force New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Status" -value "Unknown" -type string -Force Write-Output "Unknown password on machine. This need to delete first" | out-file "c:\temp\BIOS_Profile.txt" -Append } }
But if you have other great ideas, please share this with me. Thx 😊
On my list are building the same function in Microsoft Intune and encrypt the password before it will be stored in the registry and using Microsoft Key Vault to store the information´s for more security, but any way a BIOS Password is not a Windows Password you need physical access.
A notice:
At the time of this writing, I was employed by Dell Technologies. However, Dell has no control over the creation or content of this article or has directly endorsed this article. The only indirect support is that I may have used one of my existing Dell test devices for this article.