Automate Dell BIOS Updates
Table of Contents
INTRO
You can automate Dell BIOS updates with PowerShell and RMM. While it has been some time since my last IT related post. Whether you were crawling down the rabbit holes of missing people, Mandela Effects, and my personal life’s downfalls and challenges, whether self-inflicted or not, you’ve probably wondered if I was ever going to come back to binary world. Well, today I have a script to share and that’s automating the BIOS updates of Dell systems.
In my nearly a decade of IT experience, working with Lenovo, HP, and Dell mostly, Dell has been the best in terms of quality and management. In Dell’s BIOS updates, the Intel ME firmware updates are included thus reducing another thing to manage and update. Also, Dell’s firmware updates for their Server line are not behind a paywall.
WHAT THE SCRIPT WILL DO
This script will:
- First uninstall any version of Dell Command Update currently installed using the proper uninstall string from the registry.
- Install Dell Command Update v4.3.0.
- Update the BIOS for “Compatible Systems”.
Each version of Dell Command Update supports different platforms and models so there is no 1-fits-all package. You will need to research which versions support the models of Dell you need to support, and you do that by expanding “Compatible Systems” under “Additional Details” for the download of Dell Command Update you’re going to use.
So, in this example, we’re using v4.3.0 located here.
In Datto RMM, create a new script component and upload the installer of Dell Command Update, “Dell-Command-Update-Application-for-Windows-10_GRVPK_WIN_4.3.0_A00_03.EXE”
Set your script type to PowerShell and place the following code in it. When running, the systems will reboot if there is an update, and after requesting device audits in Datto, you will see the BIOS revision has been updated for outdated models.
POWERSHELL SCRIPT
$remove = @('*Dell Command*')
function Get-InstalledApps {
param (
[Parameter(ValueFromPipeline=$true)]
[string[]]$ComputerName = $env:COMPUTERNAME,
[string]$NameRegex = ''
)
foreach ($comp in $ComputerName) {
$keys = '','\Wow6432Node'
foreach ($key in $keys) {
try {
$apps = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine',$comp).OpenSubKey("SOFTWARE$key\Microsoft\Windows\CurrentVersion\Uninstall").GetSubKeyNames()
} catch {
continue
}
foreach ($app in $apps) {
$program = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine',$comp).OpenSubKey("SOFTWARE$key\Microsoft\Windows\CurrentVersion\Uninstall\$app")
$name = $program.GetValue('DisplayName')
if ($name -and $name -match $NameRegex) {
[pscustomobject]@{
ComputerName = $comp
DisplayName = $name
DisplayVersion = $program.GetValue('DisplayVersion')
Publisher = $program.GetValue('Publisher')
InstallDate = $program.GetValue('InstallDate')
UninstallString = $program.GetValue('UninstallString')
Bits = $(if ($key -eq '\Wow6432Node') {'64'} else {'32'})
Path = $program.name
}
}
}
}
}
}
$array = Foreach ($r in $remove){
Get-InstalledApps | Where-Object {$_.DisplayName -like $r } | Select-Object -ExpandProperty UninstallString
}
ForEach ($a in $array) {
& "$env:ComSpec" /c $a /quiet
}
$ExecutingScriptDirectory = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
Start-Process "$ExecutingScriptDirectory\Dell-Command-Update-Application-for-Windows-10_GRVPK_WIN_4.3.0_A00_03.EXE" -ArgumentList '/s' -Verbose -Wait
Start-Process -FilePath "C:\Program Files (x86)\Dell\CommandUpdate\DellCommandUpdate.exe" -ArgumentList "/s" -Verbose -Wait
Set-Service -Name 'DellClientManagementService' -StartupType Manual
Start-Process -FilePath "C:\Program Files (x86)\Dell\CommandUpdate\dcu-cli.exe" -ArgumentList "/Scan -Report=C:\TEMP" -Wait
$XMLReport = Get-Content "C:\TEMP\DCUApplicableUpdates.xml"
#We now remove the item, because we don't need it anymore, and it sometimes fails to overwrite.
Remove-Item "C:\TEMP\DCUApplicableUpdates.xml" -Force
$AvailableUpdates = $XMLReport.updates.update
$BIOSUpdates = ($XMLReport.updates.update | Where-Object { $_.type -eq "BIOS" }).name.Count
$ApplicationUpdates = ($XMLReport.updates.update | Where-Object { $_.type -eq "Application" }).name.Count
$DriverUpdates = ($XMLReport.updates.update | Where-Object { $_.type -eq "Driver" }).name.Count
$FirmwareUpdates = ($XMLReport.updates.update | Where-Object { $_.type -eq "Firmware" }).name.Count
$OtherUpdates = ($XMLReport.updates.update | Where-Object { $_.type -eq "Other" }).name.Count
$PatchUpdates = ($XMLReport.updates.update | Where-Object { $_.type -eq "Patch" }).name.Count
$UtilityUpdates = ($XMLReport.updates.update | Where-Object { $_.type -eq "Utility" }).name.Count
$UrgentUpdates = ($XMLReport.updates.update | Where-Object { $_.Urgency -eq "Urgent" }).name.Count
Start-Process -FilePath "C:\Program Files (x86)\Dell\CommandUpdate\dcu-cli.exe" -ArgumentList "/applyUpdates -autoSuspendBitLocker=enable -reboot=enable -updateType=bios" -Wait
BIOS UPDATES ARE IMPORTANT
Taking a Dell OptiPlex 7040 for example, there are 24 revisions of BIOS updates, each with 1 or more enhancements or fixes. I have seen BIOS updates resolve issues that also aren’t listed in revision notes, like certain SSD drives not being detected.
Do you want to troubleshoot an issue you think is Windows, software, or hardware related for hours only to discover it a was a BIOS issue/bug on the OEM’s part? No. So just do the dang updates and don’t be so afraid. I think I have had only 2 bad BIOS flashes in my past and one of them I was able to recover so I myself never get worried doing them.
CONCLUSION
Well, there you go. Now if you run this and brick 50 systems remotely, I can’t help you there, but praying to Jesus Christ may be the next step, and we have plenty of posts here on how to connect with Him more if that happens.
I have run this multiple times without issues, and it has saved me a lot of time. Stay safe out there, and don’t take anything experimental that can cause heart problems, blood clots, and has a past of manufacturing and contamination issues.
My name is Dex Sandel, author at WinReflection, a blog which aims to help others on various IT and Christian related subjects. DON’T TREAD ON ME! The best is yet to come, and nothing can stop what’s coming!
You all have a greater destiny in Christ, should you choose to ‘follow’ Him, not just believe. Many of you feel lost, without drive, and lack a greater purpose in your life causing depression, sadness, anxiety, and loneliness. Working your 9-5 job isn’t your primary purpose. So, then what is? That’s for you to discover, but hopefully I can provide some new unlocks along your path.
What will ‘you’ do, and what will your destiny be?
John 3:16: For God so loved the world that he gave his one and only Son, that whoever believes in him shall not perish but have eternal life.
Thank you for sharing this script. Love the trust in Jesus part :-). Where are you calling list of computers?
Hey Sal! You’re very welcome! I am glad you liked the Jesus part :). No calling list needed as I deploy it with an RMM solution (Datto RMM). I just select the computers I want in the web-based portal and the agents on each endpoint download the script and run with SYSTEM permissions. No bricks yet, attempted on like 12 endpoints at one time, worked well. I actually have a script for HP computers also, but still working out a bug. Have a great rest of your day/night, wherever you are.
– Dex