Dell BIOS Updates with PowerShell

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.

  1. It must “stage” the BIOS update but not force a reboot (OSD must handle that piece)
  2. 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).

imageimage

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
Doesn’t sound so hard now does it?  Here is the code to do it:
$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.

Advertisements

Author: dhedges

I'm a Senior Client Systems Engineer specializing in OS Deployments and Automation using VBScript, PowerShell, MDT and SCCM. I enjoy working with technology and bending it to my will.

16 thoughts on “Dell BIOS Updates with PowerShell”

  1. 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!

  2. Awesome. I was struggling with what I’m sure was some syntax issue trying to get the Dell vbs script working with -nopause, so turned to Powershell and found this first thing.

    I changed the part for getting BIOS version to non Dell OMCI method, which worked well on the Latitude E6500 I tested:

    $BIOSVersion = ((Get-WMIObject -Class Win32_BIOS).SMBIOSBIOSVersion)

  3. Hi, thanks for your script it seems really helpful.
    I have 1 question though.
    How can you do this when the BIOS has a Password?
    Thanks

    1. Hi poli,

      For this you would want to run a tool such as Dell Client Configuration Toolkit (CCTK) to remove the BIOS Password temporarily, then run the BIOS Update and use CCTK again to reset the BIOS password. I don’t believe there is a “bypass” option for that.

  4. Humm! This is great but it does not appear to work for the model 745. The BIOS is listed in five characters vice three.

    1. 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.

      1. The other models we have, 740, PE1950, PER200, PER300, and the PER610 uses the same BIOS naming convention as the 745. I am glad they reverted back to the original naming convention. As duly noted, it presents other issues when trying to update via scripts. I will try this out.

    2. I realize this thread is old, but in case anyone is looking you should be able to modify the script code on Line 9, changing the “…Length -3)” to “…Length -5)” to read in the last five characters instead of the last three.

  5. I am fairly new to powershell, so with that said I setup the folder structure and created the ps1 file and copied all the bios upgrade files but I am getting an error in the powershell script.

    Get-WmiObject : Invalid namespace
    at c:\bios\invoke-DellBIOSUpdate.ps1:3 char 30
    etc……

    and

    You cannot call a method on a null-vauled expression.
    At C:\bios\Invoke-DellBIOSUpdate.ps1:11 char 27
    etc….

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s