The other day I was discussing with my colleagues about how we were going to deliver Dell BIOS updates to clients during our SCCM OSD deployments. Several solutions were brought up including using SCUP 2011, a standard software package or just saying forget it and let the desktop support technicians handle it.
We don’t yet have SCUP 2011 implemented in our environment and really don’t have the time to learn it and setup the proper processes (development, testing, release) so I set out to develop a script that would allow us to install it on all of our Dell hardware with ease.
There were 2 main criterion required of this script.
- It must “stage” the BIOS update but not force a reboot (OSD must handle that piece)
- It must be easy to update the package (even for non-scripters) to support new models or update BIOS versions
That being said, the script described below does just that. But before we get to the script, lets take a look at the folder structure. The main folder of the package contains the Invoke-DellBIOSUpdate.ps1 PowerShell script and a bunch of folders all corresponding to the model of a Dell system. Inside each folder is a *SINGLE* BIOS Update File (You’ll see why I bolded the word single in a bit).
Ok, now that we got the directory structure piece out of the way, lets get to the script. In this first section, we simply gather the current directory, current system model and current installed BIOS version.
*NOTE: I’m referencing the new namespace for Dell OMCI 8.x. Change this if you are using an older version of Dell OMCI*
$ScriptFolder = Split-Path -Parent $MyInvocation.MyCommand.Definition $Model = $((Get-WmiObject -Class Win32_ComputerSystem).Model).Trim() $BIOSVersion = (Get-WmiObject -Namespace root\DCIM\SYSMAN -Class DCIM_BIOSElement).Version
Well that was pretty easy wasn’t it? But the work isn’t done yet. The next few steps include:
- Verifying there is an available BIOS Update for the current system model
- Identify the version number of the BIOS Update File
- Verify that a BIOS Update is needed by the system
- Execute the BIOS Update itself
$ScriptFolder = Split-Path -Parent $MyInvocation.MyCommand.Definition $Model = $((Get-WmiObject -Class Win32_ComputerSystem).Model).Trim() $BIOSVersion = (Get-WmiObject -Namespace root\DCIM\SYSMAN -Class DCIM_BIOSElement).Version if(Test-Path -Path $ScriptFolder\$model) { $BIOSUpdateFile = Get-ChildItem -Path $ScriptFolder\$Model $BIOSUpdateFileVersion = $BIOSUpdateFile.ToString() -replace ($BIOSUpdateFile.Extension,"") $BIOSUpdateFileVersion = $BIOSUpdateFileVersion.Substring($BIOSUpdateFileVersion.Length -3) if($BIOSVersion.CompareTo($BIOSUpdateFileVersion) -eq 0) { Write-Output "BIOS Version is up to date" } else{ Try{ Write-Output "BIOS Update Needed. Attempting BIOS Flash Operation..." #Invoke-Expression $ScriptFolder\$Model\$BIOSUpdateFile " /quiet" $objStartInfo = New-Object System.Diagnostics.ProcessStartInfo $objStartInfo.FileName = "$ScriptFolder\$Model\$BIOSUpdateFile" $objStartInfo.Arguments = "-noreboot -nopause -forceit" $objStartInfo.CreateNoWindow = $true [System.Diagnostics.Process]::Start($objStartInfo) | Out-Null } Catch{[Exception] Write-Output "Failed: $_" } } Write-Output "End Dell BIOS Update Operation" } else { Write-Output "Model Not Supported" }
OK, now for the explanation of all that nonsense above. The first thing we are doing in the “if” statement is checking to see if there is a folder with the current system model available. That will tell us if the package repository is setup to support the current model. Once we are actually inside the if-loop we create a couple more variables for use. $BIOSUpdateFile simply gets the BIOS Update File (the .exe) and stores all it’s properties/methods into this variable. This is now an Object!
The next variable is $BIOSUpdateFileVersion. This variable stores the actual file version of the BIOS Update File by first stripping off the extension of the file name, then by using the Substring() method to capture only the last three characters. As you can see from the picture above, the Dell BIOS Update file uses the A## indicator for their BIOS version.
Once we’ve gathered this information, we can then use the .CompareTo() method to compare the installed BIOS Version ($BIOSUpdateFileVersion) and the BIOS Update File Version ($BIOSUpdateFileVersion). If they are a match, we need not proceed further and can quit. Otherwise, we need to execute the BIOS Update File silently and without reboot. We do this by invoking the [System.Diagnostics.Process]. Here we can set the necessary arguments, window style (CreateNoWindow for OSD) and actually Start the process.
The magic of this script is that you don’t actually have to update the script when adding new models or updating the BIOS version. Simply add a new folder with the appropriate name, or replace the existing BIOS update file with a new one and the script will handle the rest.
Tags: BIOS, Dell, OMCI, PowerShell
September 2, 2011 at 12:16 PM |
Wonderful – I’m still scripting in the VB world (had made a similar process using VBS) and have been wanting to move to Powershell for a while… now I’ve got to find a way to pay-it-forward for the work you shared saving me the time. Kudos again!
May 17, 2012 at 2:11 PM |
Humm! This is great but it does not appear to work for the model 745. The BIOS is listed in five characters vice three.
May 17, 2012 at 2:30 PM |
Hi TLW,
You are correct. This script is designed for the “normal” naming convention that Dell uses for BIOS updates. The 745 was one where they tried a different naming convention however with the 755 they switched it back.