Deployment

Step-by-Step: Upgrading BIOS during LiteTouch Deployment, for Dell, Hewlett-Packard and Lenovo

Ok, so here is the short( not really sure this is going to be short by the way, well nothing is perfect) story, once again a customer (Thank you Bill for letting me test fun stuff in your environment!) asked me for a feature that I have done multiple times before, so the task was easy, just upgrade the BIOS when we deploy the machine, so I told them that
–Hey, this is the way to do it and the reply was.
–Sorry, It cannot be done as far as we know, since we have Lenovo and Lenovo does not allow you to run the BIOS firmware update in WinPE.
So it was time to start some thinking. We need to figure out how to create a solid solution and we to do an “all-night-long”. I did not just wanted to fix this customers issue, I want some kind of universal solution that will work on any hardware, client, type, vendor and so on. So I fired up my idea-engine and bang, there it was. I had a plan and a solution that would work, should only take a couple of minutes, kind of. At least that was the idea
(Just a quick note: I did not have the capability to test the Dell part of the script since I don’t have a Dell computer (For some reason most vendors are very polite and give me things to play with, but Dell obviously have an other agenda and I cannot afford to buy a Dell computer just to be able to write blog posts. Anyone has a used Dell that you are willing to give away for scientific experiments by the way? However, it should work, if it doesn’t, ping me)

Here is what we need:

  • It should work with any vendor in the same way
  • It should work with both servers and clients
  • It should do some serious logging
  • I should be able reuse some part of the code in other scenarios
  • It should work in WinPE

…Six hours later, Non-Stop “NCIS” at the hotel room, numerous reboots and massive amount of Coke and the solution was done and here is how it works.

We need information to make decisions!

We really need some variables to work with and it would be possible to use just one simple script to solve the problem, but then I started to think a bit, and.. It would be nice to do this  just a bit “Michael Niehaus / Keith Garner style”.

That way I could use these variables for other purposes then just this and I would in the long run have a nice UserExit Script that will collect all kinds of variables to make the deployment even more dynamically then it already is (Why?, Because I can of course…). Now it would be nice if all vendors use the same location in WMI to store information for the same thing, but that’s not going to happen, trust me, the British Empire will shift over to driving on the right side of the road and the US will start using the metric system before that happens, not very likely in other words. So we need to collect the following so that we later on can use BIOS information to determine what version we have and if it should be upgraded or not

  • From WIN32_BIOS we need SMBIOSBIOSVersion (this will be captured as SMBIOSBIOSVersion)
  • From WIN32_BIOS we need Version (this will be captured as BIOSVersion)
  • From Win32_ComputerSystemProduct we need Version (this will be captured as ProductVersion)

This way, we can use different ´properties and variables for different systems and that is pretty nice.

How will we use the different variables?

Well, by combing them differently we will be able to use them in different combinations to get what we need, here is how we will use them

  • Dell = SMBIOSBIOSVersion + Make + Model
  • Hewlett-Packard = BIOSVersion + Make + Model
  • LENOVO = SMBIOSBIOSVersion + Make + ProductVersion

Now, we can use these properties for this purpose, but you can also use these for other purposes, like driver handling, rules for applications and much more. There is also possible to combine this with the ModelAlias userexit script if you feel for it.

Using a user exit script is the solution to get this data

A user exit script is just a simple piece of VB script that runs as a part of the gather process when MDT reads the customsettings.ini file. So we need to create the ZTITheUserExit.vbs script and put that in the Scripts folder and then we need to update the CustomSettings.ini file so that it is used. You can put the execution of the user exit script basically anywhere in the priority, but I prefer to have a separate section called [Init] where I run everything instead of using default, since default in a production environment seems to be ending up as the last priority, time to stop writing and show you how it should look like:

[Settings]
Priority=Init, Default
Properties=BIOSVersion, SMBIOSBIOSVersion, ProductVersion

[Init]
SMBIOSBIOSVersion=#SetSMBIOSBIOSVersion()#
BIOSVersion=#SetBIOSVersion()#
ProductVersion=#SetProductVersion()#
UserExit=ZTITheUserExit.vbs

[Default]
OSInstall=Y

As you can see, the first thing that will happen when MDT starts reading the customsettings.ini file it finds the section init and it the jumps to that section in the file where it will discover that it needs to run ZTITheUserExit.vbs and that it will be three functions in the script that should return the values into BIOSVersion, SMBBIOSBIOSVersion and ProductVersion. After this has been executed you can now use for example  %BIOSVersion% in the same way as other properties such as %Make%, %Model% if you like. My guess right now is that you now would like to see the script, right? So, here it is, just copy the content and save as ZTITheUserExit.vbs in the scripts folder

ZTITheUserExit.vbs


Function UserExit(sType, sWhen, sDetail, bSkip)
    oLogging.CreateEntry “UserExit: Running Script: ” & sType & ” ” & sWhen & ” ” & sDetail, LogTypeInfo
    UserExit = Success
End Function

Function SetSMBIOSBIOSVersion()
    oLogging.CreateEntry “UserExit: Running Function SetSMBIOSBIOSVersion : ” & sType & ” ” & sWhen & ” ” & sDetail, LogTypeInfo
    Dim objWMI
    Dim objResults
    Dim objInstance
    Dim SMBIOSBIOSVersion
   
    Set objWMI = GetObject(“winmgmts:”)
    Set objResults = objWMI.ExecQuery(“SELECT * FROM Win32_BIOS”)
        If Err then
        oLogging.CreateEntry “Error querying Win32_BIOS: ” & Err.Description & ” (” & Err.Number & “)”, LogTypeError
    Else
        For each objInstance in objResults
            If Not IsNull(objInstance.SMBIOSBIOSVersion) Then
                    SMBIOSBIOSVersion = Trim(objInstance.SMBIOSBIOSVersion)
            End If
        Next
    End If
    SetSMBIOSBIOSVersion = SMBIOSBIOSVersion
    oLogging.CreateEntry “UserExit: Result: ” & SetSMBIOSBIOSVersion, LogTypeInfo
End Function

Function SetBIOSVersion()
    oLogging.CreateEntry “UserExit: Running Function SetBIOSVersion : ” & sType & ” ” & sWhen & ” ” & sDetail, LogTypeInfo
    Dim objWMI
    Dim objResults
    Dim objInstance
    Dim BIOSVersion
   
    Set objWMI = GetObject(“winmgmts:”)
    Set objResults = objWMI.ExecQuery(“SELECT * FROM Win32_BIOS”)
        If Err then
        oLogging.CreateEntry “Error querying Win32_BIOS: ” & Err.Description & ” (” & Err.Number & “)”, LogTypeError
    Else
        For each objInstance in objResults
            If Not IsNull(objInstance.Version) Then
                    BIOSVersion = Trim(objInstance.Version)
            End If
        Next
    End If
    SetBIOSVersion = BIOSVersion
    oLogging.CreateEntry “UserExit: Result: ” & SetBIOSVersion, LogTypeInfo
End Function

Function SetProductVersion()
    oLogging.CreateEntry “UserExit: Running Function SetProductVersion : ” & sType & ” ” & sWhen & ” ” & sDetail, LogTypeInfo
    Dim objWMI
    Dim objResults
    Dim objInstance
    Dim ProductVersion
   
    Set objWMI = GetObject(“winmgmts:”)
    Set objResults = objWMI.ExecQuery(“SELECT * FROM Win32_ComputerSystemProduct”)
        If Err then
        oLogging.CreateEntry “Error querying Win32_BIOS: ” & Err.Description & ” (” & Err.Number & “)”, LogTypeError
    Else
        For each objInstance in objResults
            If Not IsNull(objInstance.Version) Then
                    ProductVersion = Trim(objInstance.Version)
            End If
        Next
    End If
    SetProductVersion = ProductVersion
    oLogging.CreateEntry “UserExit: Result: ” & SetProductVersion, LogTypeInfo
End Function


If we run this script as a part of ZTIgather you should get something similar. So lets just look at the output that the userexit script will generate so that you have some kind of reference:

Determining the INI file to use.
Using COMMAND LINE ARG: Ini file = ..\Control\CustomSettings.ini
Finished determining the INI file to use.
Added new custom property MYCUSTOMPROPERTY
Added new custom property REFTYPE
Added new custom property BIOSVERSION
Added new custom property SMBIOSBIOSVERSION
Added new custom property PRODUCTVERSION
Using from [Settings]: Rule Priority = INIT, TASKSEQUENCEID, DEFAULT
—— Processing the [INIT] section ——
USEREXIT: Running Script: SECTION BEFORE INIT
User exit “C:\MDTLab\Scripts\ZTITheUserExit.vbs” called successfully, skip = False.
USEREXIT: Running Function SetBIOSVersion :
USEREXIT: Result: HPQOEM – f
Property BIOSVERSION is now = HPQOEM – f
Using from [INIT]: BIOSVERSION = HPQOEM – f
USEREXIT: Running Function SetSMBIOSBIOSVersion :
USEREXIT: Result: 68CVD Ver. F.0A
Property SMBIOSBIOSVERSION is now = 68CVD Ver. F.0A
Using from [INIT]: SMBIOSBIOSVERSION = 68CVD Ver. F.0A
USEREXIT: Running Function SetProductVersion :
USEREXIT: Result:
Property PRODUCTVERSION is now =
Using from [INIT]: PRODUCTVERSION =
USEREXIT: Running Script: SECTION AFTER INIT
User exit “C:\MDTLab\Scripts\ZTITheUserExit.vbs” called successfully, skip = False.

Now, lets take a quick look, these are the property values we will get in return on a HP Compaq 8540w (My portable datacenter)

Property BIOSVERSION is now = HPQOEM – f
Property SMBIOSBIOSVERSION is now = 68CVD Ver. F.0A
Property PRODUCTVERSION is now =

Seems to be working. Some explanations before we continue, one thing to notice is that the PRODUCTVERSION is blank and that BIOSVERSION does not give use anything useful, on HP Compaq it is the SMBIOSBIOSVERSION that is the real version of the BIOS, on LENOVO it is BIOSVERSION (You can use SMBIOSBIOSVERSION to, but it also contain “rubbish”. The only reason to use PRODUCTVERSION is that on Lenovo machines that will be the model name, not that nasty number that is extremely unique (so, on a LENOVO T410 it would give you “LENOVO T410” as result

Next step, create a script that can use these variables and then determine if the BIOS has the correct version or if it should be upgraded.

And that is a walk in the park, just create script file called ZTIBIOSUpgrade.wsf, save it the Scripts folder:
The format of the file is somewhat of a school example in the way that it contains extensive logging and contain routines for bailing out if things go bad (script has a certain habit of doing exactly that for some reason. It also have one really strange thing, it has a section for Microsoft Hardware which is Hyper-V, Virtual PC and Virtual Server and now, I’m not insane. I did create that section to verify that it works, since it is some much faster to do snapshots and flip back and forward without re-deploying a physical machine.


<job id=”ZTIBIOSUpgrade”>
<script language=”VBScript” src=”ZTIUtility.vbs”/>
<script language=”VBScript”>

‘//—————————————————————————-
‘// Solution: BIOS Upgrade
‘//
‘// The following values must be populated in the CustomSettings.ini
‘// using a userexit script (ZTITheUserExit.vbs
‘//         – BIOSVersion
‘//         – SMBIOSBIOSVersion
‘//         – ProductVersion
‘// To get these values you also need to execute a userexit script
‘// NOTE: The Section for “Microsoft” is only intended as a test/demo/play,
‘// since the BIOS cannot be updated from within the VM itself.
‘//
‘// Usage: cscript ZTIBIOSUpgrade.wsf[/debug:true]
‘// Version: 1.0 – 4 May 2011 – Mikael Nystrom
‘//
‘// This script is provided “AS IS” with no warranties, confers no rights and
‘// is not supported by the authors
‘//
‘//—————————————————————————-

‘//—————————————————————————-
‘// Global constant and variable declarations
‘//—————————————————————————-

‘//—————————————————————————-
‘//
‘// Global constant and variable declarations
‘//
‘//—————————————————————————-

Option Explicit

Dim iRetVal

‘//—————————————————————————-
‘// End declarations
‘//—————————————————————————-

‘//—————————————————————————-
‘// Main routine
‘//—————————————————————————-

‘On Error Resume Next
iRetVal = ZTIProcess
ProcessResults iRetVal
On Error Goto 0

‘//—————————————————————————
‘//
‘// Function: ZTIProcess()
‘//
‘// Input: None
‘//
‘// Return: Success – 0
‘// Failure – non-zero
‘//
‘// Purpose: Perform main ZTI processing
‘//
‘//—————————————————————————
Function ZTIProcess()

    Dim sMake
    Dim sModel
    Dim sSMBIOSBIOSVersion
    Dim sBIOSVersion
    Dim sExeToRun
    Dim sRefBiosVersion
    Dim sProduct
    Dim sProductVersion
    Dim sOSVersion
    Dim sDeployDrive
    Dim sDeployRoot
    Dim sExecuteCommand
   
    iRetVal = Success
    ZTIProcess = iRetval
   
    sMake = oEnvironment.Item(“Make”)
    sModel = oEnvironment.Item(“Model”)
    sSMBIOSBIOSVersion  = oEnvironment.Item(“SMBIOSBIOSVersion “)
    sBIOSVersion = oEnvironment.Item(“BIOSVersion”)
    sProduct = oEnvironment.Item(“Product”)
    sProductVersion = oEnvironment.Item(“ProductVersion”)
    sOSVersion = oEnvironment.Item(“OSVersion”)
    sDeployDrive = oEnvironment.Item(“DeployDrive”)
    sDeployRoot = oEnvironment.Item(“DeployRoot”)
   
   
    oLogging.CreateEntry “———————————————-“, LogTypeInfo
    oLogging.CreateEntry “Config-BIOSUpgrade – Runninng BIOS Upgrade:   “, LogTypeInfo
    oLogging.CreateEntry “Config-BIOSUpgrade – Make is:                 ” & sMake, LogTypeInfo
    oLogging.CreateEntry “Config-BIOSUpgrade – Model is:                ” & sModel, LogTypeInfo
    oLogging.CreateEntry “Config-BIOSUpgrade – Product is:              ” & sProduct, LogTypeInfo
    oLogging.CreateEntry “Config-BIOSUpgrade – ProductVersion is:       ” & sProductVersion, LogTypeInfo
    oLogging.CreateEntry “Config-BIOSUpgrade – SMBIOSBIOSVersion is:    ” & sSMBIOSBIOSVersion, LogTypeInfo
    oLogging.CreateEntry “Config-BIOSUpgrade – BIOSVersion is:          ” & sBIOSVersion, LogTypeInfo
    oLogging.CreateEntry “Config-BIOSUpgrade – OSVersion is:            ” & sOSVersion, LogTypeInfo
    oLogging.CreateEntry “Config-BIOSUpgrade – DeployDrive:             ” & sDeployDrive, LogTypeInfo
    oLogging.CreateEntry “Config-BIOSUpgrade – DeployRoot:              ” & sDeployRoot, LogTypeInfo
    oLogging.CreateEntry “———————————————-“, LogTypeInfo

    If sOSVersion = “WinPE” Then
    oLogging.CreateEntry “Config-BIOSUpgrade – Running WinPE…”, LogTypeInfo
    oLogging.CreateEntry “Config-BIOSUpgrade – Loading battery monitor…”, LogTypeInfo
    oUtility.RunWithHeartbeat(“drvload \Windows\inf\battery.inf”)
    oLogging.CreateEntry “Config-BIOSUpgrade – Loading battery monitor…Done”, LogTypeInfo’
    Else
    oLogging.CreateEntry “Config-BIOSUpgrade – Not running WinPE…”, LogTypeInfo
    oLogging.CreateEntry “Config-BIOSUpgrade – Not loading battery monitor …”, LogTypeInfo
    End If
   
    Select Case sMake
        Case “Dell Computer Corporation”, “Dell Inc.”, “Dell Computer Corp.”
            oLogging.CreateEntry “Config-BIOSUpgrade – ” & sMake & ” is selected”, LogTypeInfo
            oLogging.CreateEntry “Config-BIOSUpgrade – …searching for BIOS upgrades”, LogTypeInfo
            Select Case sModel
                Case “Latitude D420” : sExeToRun = “LatitudeD420.cmd ” : sRefBiosVersion=”A06″
                Case Else : sExeToRun = “NA”
            End Select
                If sExeToRun = “NA” Then
                    oLogging.CreateEntry “Config-BIOSUpgrade – No support for ” & sModel, LogTypeInfo
                Elseif sSMBIOSBIOSVersion = sRefBiosVersion Then
                    oLogging.CreateEntry “Config-BIOSUpgrade – No upgrade needed”, LogTypeInfo
                Else
                    oLogging.CreateEntry “Config-BIOSUpgrade – Correct version should be ” & sRefBiosVersion, LogTypeInfo
                    oLogging.CreateEntry “Config-BIOSUpgrade – Upgrading ” & sModel & ” from ” & sSMBIOSBIOSVersion & ” to ” & sRefBiosVersion, LogTypeInfo

                    sExecuteCommand = sDeployDrive & “\BIOSUpgrade\Dell\” & sExeToRun & sDeployDrive
                    oLogging.CreateEntry “Config-BIOSUpgrade – Command to execute ” & sExecuteCommand, LogTypeInfo

                    iRetVal = oUtility.RunWithHeartbeat(sExecuteCommand)
                    if (iRetVal = 0) or (iRetVal = 3010) then
                        ZTIProcess = Success
                    Else
                        ZTIProcess = Failure
                    End If
                End If
 
        Case “Microsoft Corporation”
            oLogging.CreateEntry “Config-BIOSUpgrade – ” & sMake & ” is selected”, LogTypeInfo
            oLogging.CreateEntry “Config-BIOSUpgrade – …searching for BIOS upgrades”, LogTypeInfo
            Select Case sModel
                Case “Virtual Machine” : sExeToRun = “VirtualMachine.cmd ” : sRefBiosVersion=”VRTUAL – 3000920″
                Case Else : sExeToRun = “NA”
            End Select
                If sExeToRun = “NA” Then
                    oLogging.CreateEntry “Config-BIOSUpgrade – No support for ” & sModel, LogTypeInfo
                Elseif sBIOSVersion = sRefBiosVersion Then
                    oLogging.CreateEntry “Config-BIOSUpgrade – No upgrade needed”, LogTypeInfo
                Else
                    oLogging.CreateEntry “Config-BIOSUpgrade – Correct version should be ” & sRefBiosVersion, LogTypeInfo
                    oLogging.CreateEntry “Config-BIOSUpgrade – Upgrading (Well, not really, but what the heck, lets try that…” & sModel & ” from ” & sSMBIOSBIOSVersion & ” to ” & sRefBiosVersion, LogTypeInfo

                    sExecuteCommand = sDeployDrive & “\BIOSUpgrade\Microsoft\” & sExeToRun & sDeployDrive
                    oLogging.CreateEntry “Config-BIOSUpgrade – Command to execute ” & sExecuteCommand, LogTypeInfo

                    iRetVal = oUtility.RunWithHeartbeat(sExecuteCommand)
                    if (iRetVal = 0) or (iRetVal = 3010) then
                        ZTIProcess = Success
                    Else
                        ZTIProcess = Failure
                    End If
                End If

        Case “IBM”, “LENOVO”
            oLogging.CreateEntry “Config-BIOSUpgrade – ” & sMake & ” is selected”, LogTypeInfo
            oLogging.CreateEntry “Config-BIOSUpgrade – …searching for BIOS upgrades”, LogTypeInfo
            Select Case sProductVersion
                Case “ThinkPad T410” : sExeToRun = “ThinkPadT410.cmd ” : sRefBiosVersion = “LENOVO – 1360”
                Case Else : sExeToRun = “NA”
            End Select
                If sExeToRun = “NA” Then
                    oLogging.CreateEntry “Config-BIOSUpgrade – No support for ” & sProductVersion, LogTypeInfo
                Elseif sBIOSVersion = sRefBiosVersion Then
                    oLogging.CreateEntry “Config-BIOSUpgrade – No upgrade needed”, LogTypeInfo
                Else
                    oLogging.CreateEntry “Config-BIOSUpgrade – Correct version for ” & sProductVersion & ” should be ” & sRefBiosVersion, LogTypeInfo
                    oLogging.CreateEntry “Config-BIOSUpgrade – Upgrading ” & sProductVersion & ” from ” & sBIOSVersion & ” to ” & sRefBiosVersion, LogTypeInfo

                    sExecuteCommand = sDeployDrive & “\BIOSUpgrade\Lenovo\” & sExeToRun & sDeployDrive
                    oLogging.CreateEntry “Config-BIOSUpgrade – Command to execute ” & sExecuteCommand, LogTypeInfo

                    iRetVal = oUtility.RunWithHeartbeat(sExecuteCommand)
                    if (iRetVal = 0) or (iRetVal = 1) or (iRetVal = 3010) then
                        ZTIProcess = Success
                    Else
                        ZTIProcess = Failure
                    End If
                End If
       
        Case “Hewlett-Packard”
            oLogging.CreateEntry “Config-BIOSUpgrade – ” & sMake & ” is selected”, LogTypeInfo
            oLogging.CreateEntry “Config-BIOSUpgrade – …searching for BIOS upgrades”, LogTypeInfo
            Select Case sModel
                Case “HP EliteBook 8540w” : sExeToRun = “HPEliteBook8540w.cmd ” : sRefBiosVersion = “68CVD Ver. F.0A”
                Case Else : sExeToRun = “NA”
            End Select
                If sExeToRun = “NA” Then
                    oLogging.CreateEntry “Config-BIOSUpgrade – No support for ” & sModel, LogTypeInfo
                Elseif sSMBIOSBIOSVersion = sRefBiosVersion Then
                    oLogging.CreateEntry “Config-BIOSUpgrade – No upgrade needed”, LogTypeInfo
                Else
                    oLogging.CreateEntry “Config-BIOSUpgrade – Correct version should be ” & sRefBiosVersion, LogTypeInfo
                    oLogging.CreateEntry “Config-BIOSUpgrade – Upgrading ” & sModel & ” from ” & sSMBIOSBIOSVersion & ” to ” & sRefBiosVersion, LogTypeInfo

                    sExecuteCommand = sDeployDrive & “\BIOSUpgrade\Hewlett-Packard\” & sExeToRun & sDeployDrive
                    oLogging.CreateEntry “Config-BIOSUpgrade – Command to execute ” & sExecuteCommand, LogTypeInfo

                    iRetVal = oUtility.RunWithHeartbeat(sExecuteCommand)
                    if (iRetVal = 0) or (iRetVal = 3010) then
                        ZTIProcess = Success
                    Else
                        ZTIProcess = Failure
                    End If
                End If
        Case Else
            oLogging.CreateEntry “Config-BIOSUpgrade – ” & sMake & ” Hey, that’s a brand I have never herd of, interesting…”, LogTypeInfo
    End Select
    oLogging.CreateEntry “———————————————-“, LogTypeInfo
End Function
</script>
</job>


So, now when we have the script created maybe I should try to explain what it actually is doing, I mean you might want to do some modification to it and then it is kind of nice to know where to poke around, So here is the short story.

  • First we make a bunch of Dim’s and the reason is simple and it is called “Option Explicit”. That is set globally in MDT and that means that it will blow up if you try to use a variable that is NOT declared (you might have seen a Error 500: Variable is undefined in MDT.
  • Next I dump all these variables to the bdd.log file, this is mainly need when you trouble shoot things and when you like to look at log files
  • Next up is, well here is the trick to make Lenovo machines run firmware updates in WinPE. The reason they does not work is because the utility looks at the state of power. They do that for one reason, to verify that the machine are running with the power cord connect to a power source and not running on battery (make sense). The secret source is to run this command:
  • oUtility.RunWithHeartbeat(“drvload \Windows\inf\battery.inf”)
  • The oUtility.RunWithHeartbeat is part of a function that gets loaded when we load up the library that is called ZTIUtlity.VBS which is a part of MDT and here is a tip for you, you should always base your script in MDT on a template that will leverage the use of ZTIUtility.vbs. I also set one condition here and that is to only load the driver when we are running WinPE, there is no point in loading it when we run the full-blown OS, it will be loaded in that case.
  • The rest is kind of easy, what will happen is that we will use the %Make% variable in MDT to see in what section we should continue, then when we we find the correct one we will get the %model% in all cases besides when it is a LENOVO, in that case we will use ProductVersion instead and if we find something that is a match when the compare the RefBios value with the version of the BIOS in the machine, it it is the same we just bail out and we are done, otherwise we will find the command to run. My first attempt of creating this had a small “flaw” and it took a couple of “angry-management seconds) to find out why and how to fix it, and the trick is that I need to run many of these firmware updates utilities on a drive letter, some of the work using UNC, but far from all and this must work in all situations, so I need a drive letter, but I cannot trust on MDT to always use Z:, so by using a built in variable called  DeployDrive to deliver that to me and that is why we will build the command to execute based on a bunch of variables
  • So, what does this means, well. In the scripts folder you will have to create a folder structure called BiosUpgrade and in the folder you then create Subfolders for each and every Vendor you have and those folders you the create one folder for each and every model and in those folders you put the firmware. It also means that you need to update this script whenever you have new versions of vendors, models and new versions of BIOS and firmware (well, I could have spent yet one night more to make it one step more dynamically, but hey I need to sleep sometime)

The Batch file…

Now as you can see in the script I have one batch file for each model,

(Looks like this in the VB)
Case “ThinkPad T410” : sExeToRun = “ThinkPadT410.cmd ” :

that batch file need a header to work, the header will make sure that you will be “in” the folder where the executable is located, that will not be needed every time, but most likely it will be needed most of the time and that batch file should look like this

%1
CD %0\..\
REM *** For testing only *** DIR > list.txt
REM Run your silent command here that will update the BIOS
REM Note: It MUST be silent and it should NOT restart the machine when it is done

Now, since you are (mots likely) a bit curios you will notice that the first line is a %1 and the reason behind that is kind of simple, %1 is the first parameter after the batch file it self, but hey, where did that variable come from??? Well, take a look at the line of execution, if you look really close you will see that we end that that line with a space in the end and the we use the DeployDrive variable and that will result in one thing. When the batch file runs it will first make sure it sets the working drive to the drive where the firmware updates are located and then we run the really old-school command

CD %0\..\

If %1 is the first parameter after the batch file, what the heck is the %0, well here is the fun thing. It’s the batch file name it self (you can test this by creating a batch file with just one line it it “Echo %0” and you will see that the result will be the name of the batch file name itself, the we just use \..\ which sets the working directory to the same location where the script is located and that is exactly what we need. Problem solved (using the MacGyver method)

The Folder Structure

Here is the folder structure that I have in the Scripts folder. In this folder structure I will store all the “Upgrades” plus the batch file. It should look like this to match the script.

image

So, in the scripts folder you will create Dell, Hewlett-Packard, LENOVO and so on, in the next level you create one folder for each model and that folder you store the upgrades,

Last step

The last thing you need to do is pretty easy. Open up your task sequence and add a Run Command that runs the ZTIBiosUpgrade.wsf. The run command should look like this:

cscript.exe “%SCRIPTROOT%\ZTIBiosUpgrade.wsf”

You can put the Run Command in the first section if you want to, there is were we did put it in the customer solution, something like this.

image

(Hey, if you ever wonder when I have time to write many of my postings it’s right now, somewhere over the Atlantic ocean flying at 10.000 feet or more with the headset filled with old-school rock, the flight attended just went pass me asking for more to drink and yes, she gave me a bunch of coke can’s. Thank you Swiss.)

A short note, this will of course work with servers too, just need to do some small adjustments

/Mike

54 replies »

  1. First of all, nice work!!
    Just got one question as to what would happen if you get a PC from the vendor with the latest and greates BIOS version, let’s say A07 for a Dell, but the script is still configured to update to A06 (sRefBiosVersion=”A06″).
    Would it downgrade the BIOS?

    • Thank you.
      Regarding “downgrade”, it is simple it depends on the commandline switches you run for the firmware upgrade utility, so for none of them will not downgrade unless you use “force”, meaning -Force or something like that. However, it will return an other return code, if you pick that up, you can add logic to the script to generate information in the bdd.log file.

  2. Mike, awesome! I found something on the Dell TechCenter but yours is integrated to support other platforms. As soon as I get a chance, I will report back on how it all works on a Dell.

    • Thank you, the stuff on Dell, weel I saw that some years ago some one line of VB i did get from that script. I just added “some” more :-)
      And, please report back on Dells

      • Apologies for the delay. I was hoping to provide additional information but for now this will have to do. I, like Kevin, am running WinPE 64-bit and deploying Windows 7 64-bit. I get an error when running (I’ll post the error later). I started troubleshooting but have had to focus on a higher priority issue (and more keep coming up).. Anyway, the cmd script works great in the OS. I don’t think I have an issue with the vbscript but I need to investigate that further. I believe I have the directory structure created properly, modified CustomSettings.ini properly and created the task to call the vbscript properly. I will try to post later today my error message while I attempt to confirm everything else.

  3. This looks great stuff!

    I am looking to use this for:
    1. Updating Dell BIOS
    2. Update BIOS settings package

    To my knowledge, both of these does not work on WINPE

    I am more interested in the BIOS setting package where I need to set SATA mode to IRRT and if I task it after OS installation, computer blue screens due to change in SATA mode after reboot.

    So some how my setting package is required to run during WinPE.

    Suggestions are highly appreciated.

    • Not really sure, as far as I know biosupgrade works in PE, but still, I have no Dell machine, otherwise I would have been able to test it for them….

      • Actually, I will open a support call to verify this. If I recall, you had to use the Dell Client Configuration Toolkit (CCTK) in WinPE. The CCTK was something else I was investigating before I had to focus on other things.

      • It’s been awhile since I looked at this and now I remember why. The CCTK allows you to configure the BIOS in Windows PE. At this time, there is no utility that can be run in Windows PE 64-bit to upgrade the BIOS assuming this link is correct: http://www.delltechcenter.com/thread/4605840/Ability+To+Update+BIOS+via+WinPE+3.0+64bit

        I booted from USB to start the MDT process and opened a command prompt (F8). I attempted to run the BIOS utility and then received the following:
        “The subsystem needed to support the image type is not present.”

      • Yes, the Dell utility does not work in 64 bit PE, I will repost this blog next week with instrcutions on how to run this from within Windows instead, then it will work. It will also work with the next version om MDT2012, since that will allow you to install 64 bit images using a 32 bit boot image

  4. Good work.

    I am testing the Dell BIOS upgrade and it seems that it’s not able to upgraded from WinPE 3.0 64bit. I am able to run the EXE from a command prompt without a problem with a 32 bit version of WinPE but it’s a no-go on the 64bit…but that has nothing to do with your script.

    One thing i am seeing and maybe it’s just me… the ZTIBIOSUpgrade.wsf script doesn’t process the path to the BAT file correctly. Instead of, Ex.. “z:\scripts\BIOSUpgrade\Dell\Latitude E6520\LatitudeE6520.cmd” the script is trying the run the BAT file from “Z:\BIOSUpdate\Dell\LatitudeE6520.cmd”. Other than that everything works great.

    • The 32/64 bit is pretty easy to fix (if I just had a Dell, grrrr) by adding logic for Architecture. But the other Issue is not an issue, it should access from Z:\BiosUpgrade. If I have specified something else, it is wring the BiosUpgrae folder is upposed to be located directly in the root folder of the deployment share.

      • I tested this today at work and my conclusion is that for the script to work under 64-bit (on Dell OptiPlex 755,760,780), the syswow64 subsystem has to be loaded, which it isn’t in WinPEx64. So for it to work you must call it when in full os.

        The workaround is of course to only deploy os from 32-bit WinPE by using a 32-bit osinstaller with your x64 images. But I’m not sure that is supported – and how about 2008R2?

      • So I have also confirmed Johan’s findings with respect to WinPE 64-bit. I guess for Dell (the only vendor I am currently investigating) you would have to perform a custom task to upgrade the BIOS. I’ll have to postpone further investigations until I have time.

        I am curious if others are using WinPE 32-bit to deploy both Windows 7 32-bit/64-bit. I am also wondering if this is officially supported.

      • Using MDT2010 it is not supported to deply 64bit OS using 32 bit boot media, but that is about to change in the upcoming version of MDT2012

  5. I don’t see the two scripts I and the directory structure (Bios) I have created when WINPE is started (F8). Is there something that I forget?

      • That’s correct. My question is how do I get the bios updated when I run a Lite Touch deployment in combination with WDS?

      • That is the scenario I have tested it in, so you dont need to do anthing special to make it work. The scripts are located on the server and when litetouch fires up it will connect to the share and use the that as the script root.

  6. By the way, the workaround you mention for updating a Lenovo from PE applies to the Dell bios updates too. That is, “drvload battery.inf”
    After that it works fine with the correct command line parameters (-forceit -nopause)

  7. For Dell’s if you change the script ZTIBIOSUpgrade.wsf, you can have it working where if the machine’s bios is the same or greater than the ref, it will not upgrade.
    From:
    Elseif sSMBIOSBIOSVersion = sRefBiosVersion Then

    To:
    Elseif Cint(Right(sSMBIOSBIOSVersion, Len(sSMBIOSBIOSVersion) – 1)) >= Cint(Right(sRefBiosVersion, Len(sRefBiosVersion) – 1)) Then

    (note: thats all one line, word wrapped)

  8. I keep meaning to update you with the changes and modifications that I had to make along the way to production…I’ll try to do that soon. Some Lenovo Models (older ?6?) just don’t react well to the PE environment and lockup (I mean feeze solid, no mouse no keyboard) the PE environment.

    • ok, thats bad, really bad. I have not seen that. But I’m working on another script that runs as a app during the deployment, it seems to work very nicely so far. I’ll send it to U when I’, done with so you can test it in your enviroment.
      /mike

  9. Hi,

    I’m a bit noob in scripting. I tried to apply all the steps but there are two things I’m not sure to have understood:
    first is: where to put the BIOSUpgrade folder? in the DeployDrive root? or under the Scripts folder?
    If I understand, we need to put it in the Scripts folder but in the ZTIBIOSUpgrade.wsf script the path is: sDeployDrive & “\BIOSUpgrade\Lenovo\” so that means in the DeployDrive root, so?

    Second, where to put the script that will run the flash like ThinkCentreM90.cmd? in the flash folder or in the manufacturor folder? In my case I have:
    BIOSUpgrade\Lenovo\M90

    Finaly, I tried to run the process but it doesn’t work because it seems that the Lenovo flash tool needs to be run under a local drive (C:\). If try to run it manually under the Z:\ (DeploymentShare folder) it says:
    Lenovo Fireware Update Utility 4.2.1
    StartService Error: 3
    CreateFile Error: 2
    Unable to get bios driver handle.

    any idea?

  10. I’m a bit noob in scripting. I tried to apply all the steps but there are two things I’m not sure to have understood.

    Firstly: where did you pirst is: where to put the BIOSUpgrade folder? in the DeployDrive root? or under the Scripts folder?

    Second, where to put the script that will run the flash like ThinkCentreM90.cmd? in the flash folder or in the manufacturor folder? In my case I have:
    BIOSUpgrade\Lenovo\M90

    Finaly, I tried to run the process but it doesn’t work because it seems that the Lenovo flash tool needs to be run under a local drive (C:\). If try to run it manually under the Z:\ (DeploymentShare folder) it says:
    Lenovo Fireware Update Utility 4.2.1
    StartService Error: 3
    CreateFile Error: 2
    Unable to get bios driver handle.

    any idea?

  11. Thanks for the post… this was very helpful. I have modified the code as follows:
    1) removed logging code – so script could be tested outside LiteTouch
    2) removed references to LiteTouch variables – so script could be tested outside LiteTouch
    3) placed all function calls within the ZTIBIOSUPGRADE.WSF – so one script file does all (no need to edit INI files)

    Remaining issue… not sure how best to handle machines that need a previous bios update before updating to the newest bios version (see Latitude e6410 and e6420)

    Watch out for funky double quotes…

    Option Explicit

    Dim iRetVal
    Dim debugCode

    debugCode = false
    iRetVal = ZTIProcess
    ProcessResults iRetVal
    On Error Goto 0

    Function ZTIProcess()
    Dim oFSO, sCurrentDirectory, sMake, sModel, sBiosVersion, sExeToRun, sExecuteCommand

    Set oFSO= CreateObject(“Scripting.FileSystemObject”)
    sCurrentDirectory = oFSO.GetParentFolderName(Wscript.ScriptFullName)

    sMake = GetMakeName()
    Select Case UCase(sMake)
    Case “LENOVO” : sModel = GetProductVersion()
    Case Else : sModel = GetModelName()
    End Select
    Select Case UCase(sMake)
    Case “HP” : sBiosVersion = GetBIOSVersion()
    Case Else : sBiosVersion = GetSMBIOSBIOSVersion()
    End Select

    sExeToRun = NULL

    Select Case UCase(sMake)
    Case “DELL” :
    Select Case Ucase(sModel)
    Case “OPTIPLEX 745” : sModel = “OptiPlex745″
    If StrComp(UCase(sBiosVersion),”2.6.4”) = -1 Then
    sExeToRun = “O745-264.exe”
    End If
    Case “OPTIPLEX 755” : sModel = “OptiPlex755″
    If StrComp(UCase(sBiosVersion),”A21”) = -1 Then
    sExeToRun = “O755-A21.exe”
    End If
    Case “OPTIPLEX 980” : sModel = “OptiPlex980″
    If StrComp(UCase(sBiosVersion),”A10”) = -1 Then
    sExeToRun = “O980-A10.exe”
    End If
    Case “LATITUDE D630” : sModel = “LatitudeD630″
    If StrComp(UCase(sBiosVersion),”A18”) = -1 Then
    sExeToRun = “D630_A18.exe”
    End If
    Case “LATITUDE E6410” : sModel = “LatitudeE6410”
    Select Case UCase(sBiosVersion)
    Case “A01” : sExeToRun = “E6410A09.exe”
    Case “A02” : sExeToRun = “E6410A09.exe”
    Case “A03” : sExeToRun = “E6410A09.exe”
    Case “A04” : sExeToRun = “E6410A09.exe”
    Case “A05” : sExeToRun = “E6410A09.exe”
    Case “A06” : sExeToRun = “E6410A09.exe”
    Case “A07” : sExeToRun = “E6410A09.exe”
    Case “A08” : sExeToRun = “E6410A09.exe”
    Case “A09” : sExeToRun = “E6410A11.exe”
    Case “A10” : sExeToRun = “E6410A11.exe”
    Case Else :
    End Select
    Case “LATITUDE E6420” : sModel = “LatitudeE6420”
    Select Case UCase(sBiosVersion)
    Case “A01” : sExeToRun = “E6420A05.exe”
    Case “A02” : sExeToRun = “E6420A05.exe”
    Case “A03” : sExeToRun = “E6420A05.exe”
    Case “A04” : sExeToRun = “E6420A05.exe”
    Case “A05” : sExeToRun = “E6420A08.exe”
    Case “A06” : sExeToRun = “E6420A08.exe”
    Case “A07” : sExeToRun = “E6420A08.exe”
    Case “A08” : sExeToRun = “E6420A08.exe”
    Case Else :
    End Select
    Case Else : sModel = “Unknown”
    End Select
    Case “HP” :
    Select Case Ucase(sModel)
    Case “HP ELITEBOOK 8540W” : sModel = “EliteBook8540W”
    If StrComp(UCase(sBiosVersion),”68CVD VER. F.20″) = -1 Then
    sExeToRun = “sp54599.exe”
    End If
    Case Else : sModel = “Unknown”
    End Select
    Case “LENOVO” :
    Select Case Ucase(sModel)
    Case Else : sModel = “Unknown”
    End Select
    Case Else : sMake = “Unknown”
    End Select

    If debugCode Then
    MsgBox(“Make=” & sMake & chr(13) & “Model=” & sModel & chr(13) & “BiosVersion=” & sBiosVersion & chr(13) & “Exe=” & sExeToRun)
    End If

    If Not IsNull(sExeToRun) Then
    sExecuteCommand = sCurrentDirectory & “\Bios\” & sMake & “\” & sModel & “\” & sExeToRun & ” -NOPAUSE -NOREBOOT”
    If debugCode Then
    MsgBox(sExecuteCommand)
    Else
    iRetVal = oUtility.RunWithHeartbeat(sExecuteCommand )
    If (iRetVal = 0) or (iRetVal = 3010) then
    ZTIProcess = Success
    Else
    ZTIProcess = Failure
    End If
    End If
    Else
    If StrComp(UCase(sMake),”UNKNOWN”) = 0 Then
    MsgBox(“ERROR: Make is Unknown!” & chr(13) & “Make=” & sMake & chr(13) & “Model=” & sModel & chr(13) & “BiosVersion=” & sBiosVersion)
    ElseIf StrComp(UCase(sModel),”UNKNOWN”) = 0 Then
    MsgBox(“ERROR: Model is Not Supported!” & chr(13) & “Make=” & sMake & chr(13) & “Model=” & sModel & chr(13) & “BiosVersion=” & sBiosVersion)
    Else
    MsgBox(“No BIOS update performed!” & chr(13) & “Make=” & sMake & chr(13) & “Model=” & sModel & chr(13) & “BiosVersion=” & sBiosVersion)
    End If
    End If
    End Function

    Function GetMakeName()
    Dim objWMI, objResults, objInstance, sMakeName
    Set objWMI = GetObject(“winmgmts:”)
    Set objResults = objWMI.ExecQuery(“SELECT * FROM Win32_ComputerSystem”)
    If Err then
    MsgBox(“Unable to query Win32_Bios” & chr(13) & “Error Number: ” & Err.Number & chr(13) & “Description: ” & Err.Description)
    Else
    For each objInstance in objResults
    If Not IsNull(objInstance.Manufacturer) Then
    ‘Wscript.Echo objInstance.Manufacturer
    sMakeName = Trim(objInstance.Manufacturer)
    End If
    Next
    End If
    Select Case sMakeName
    Case “Dell Computer Corporation”, “Dell Inc.”, “Dell Computer Corp.”, “Dell” : sMakeName = “DELL”
    Case “Hewlett-Packard” : sMakeName = “HP”
    Case “IBM”, “LENOVO” : sMakeName = “LENOVO”
    Case Else : sMakeName = “Unknown”
    End Select
    GetMakeName = sMakeName
    End Function

    Function GetModelName()
    Dim objWMI, objResults, objInstance, sModelName
    Set objWMI = GetObject(“winmgmts:”)
    Set objResults = objWMI.ExecQuery(“SELECT * FROM Win32_ComputerSystem”)
    If Err then
    MsgBox(“Unable to query Win32_Bios” & chr(13) & “Error Number: ” & Err.Number & chr(13) & “Description: ” & Err.Description)
    Else
    For each objInstance in objResults
    If Not IsNull(objInstance.Model) Then
    ‘Wscript.Echo objInstance.Model
    sModelName = Trim(objInstance.Model)
    End If
    Next
    End If
    GetModelName = sModelName
    End Function

    Function GetSMBIOSBIOSVersion()
    Dim objWMI, objResults, objInstance, sSMBIOSBIOSVersion
    Set objWMI = GetObject(“winmgmts:”)
    Set objResults = objWMI.ExecQuery(“SELECT * FROM Win32_BIOS”)
    If Err then
    MsgBox(“Unable to query Win32_Bios” & chr(13) & “Error Number: ” & Err.Number & chr(13) & “Description: ” & Err.Description)
    Else
    For each objInstance in objResults
    If Not IsNull(objInstance.SMBIOSBIOSVersion) Then
    sSMBIOSBIOSVersion = Trim(objInstance.SMBIOSBIOSVersion)
    End If
    Next
    End If
    GetSMBIOSBIOSVersion = sSMBIOSBIOSVersion
    End Function

    Function GetBIOSVersion()
    Dim objWMI, objResults, objInstance, sBIOSVersion
    Set objWMI = GetObject(“winmgmts:”)
    Set objResults = objWMI.ExecQuery(“SELECT * FROM Win32_BIOS”)
    If Err then
    MsgBox(“Unable to query Win32_Bios” & chr(13) & “Error Number: ” & Err.Number & chr(13) & “Description: ” & Err.Description)
    Else
    For each objInstance in objResults
    If Not IsNull(objInstance.Version) Then
    sBIOSVersion = Trim(objInstance.Version)
    End If
    Next
    End If
    GetBIOSVersion = sBIOSVersion
    End Function

    Function GetProductVersion()
    Dim objWMI, objResults, objInstance, sProductVersion
    Set objWMI = GetObject(“winmgmts:”)
    Set objResults = objWMI.ExecQuery(“SELECT * FROM Win32_ComputerSystemProduct”)
    If Err then
    MsgBox(“Unable to query Win32_ComputerSystemProduct” & chr(13) & “Error Number: ” & Err.Number & chr(13) & “Description: ” & Err.Description)
    Else
    For each objInstance in objResults
    If Not IsNull(objInstance.Version) Then
    sProductVersion = Trim(objInstance.Version)
    End If
    Next
    End If
    GetProductVersion = sProductVersion
    End Function

    • Hi Jon,

      Thank you for your script, it works pretty much. I try to use it on LENOVO machines but I get an error when I try to flash the BIOS.

      In the sExeToRun variable I call a batch with the command line: wflash2.exe IMAGE9h.ROM /clr /ign. So in the script file, I have this:
      *********************************************
      Case “LENOVO” :
      Select Case sModel
      Case “ThinkCentre M91p” : sExeToRun = “Flash.cmd”
      *********************************************

      And I get:
      *********************************************
      Return code from command = 1
      ZTI ERROR – Non-zero return code by ZTIBIOSUpgrade, rc = 1
      *********************************************
      I have no idea what’s wrong.

      Any help will be useful,

      • I think I know why this error occur. I need to work on the flashbios directory and not just launch the command line from somewhere. Do you know what can I add on the script to work?

      • I put the bios files in the Scripts directory on the Deployment Share which is what the ‘sCurrentDirectory’ variable is for – so its likely to be ‘Z:\ServerName\DeploymentShare\Scripts’ to which I add ‘\Bios\’ & sMake & ‘\’ & sModel & ‘\’ & sExeToRun. I am a Dell shop and use only their provided bios EXE – so I cant test your scenario for you.
        1) For LENOVO machines – set the sExeToRun to the ROM file needed …. sExeToRun = “IMAGE9h.ROM”
        2) Put the flash utility at the LENOVO base directory …. ‘Z:\ServerName\DeploymentShare\Scripts\Bios\Lenovo\wflash2.exe’
        3) Add a ‘Select Case’ on the creation of the sExecuteCommand for Lenovo’s if you are going to use a flashing tool with a ROM file…..
        Select Case UCase(sMake)
        Case “LENOVO” :
        sExecuteCommand = sCurrentDirectory & “\Bios\” & sMake & “\” & sModel & “\” & sExeToRun & ” -NOPAUSE -NOREBOOT”
        Case Else :
        sExecuteCommand = sCurrentDirectory & “\Bios\” & sMake & “\wflash2.exe” & ” ” &
        sCurrentDirectory & “\Bios\” & sMake & “\” & sExeToRun & ” /clr /ign”
        End Select

        Also… becuase I took out all LiteTouch specific code and references… you can test the script… without waiting for it to fail with some wierd error code
        1) Change the variable debugCode from false to true to get a MSGBOX prompt…
        2) Launch the WinPE LiteTouch boot process
        3) BEFORE you select a Task Sequence press F8 to bring up a command prompt
        4) type (without quotes) ‘z:’ then ‘cd Scripts’
        5) type (without quotes) cscript ZTIBiosUpgrade

      • Sorry… switch that Select Case around…. I put the LENOVO sExecuteCommand in the wrong place

      • I also forgot to add & “\” & sModel to the sExecuteCommand … I need another cup of coffeee!

      • Hi Jon,

        OK, I followed all the points and here are the outputs:

        My sExeToRun is:
        Case “ThinkCentre M91p” : sExeToRun = “IMAGE9h.ROM”

        My sExecuteCommand:

        sExecuteCommand = sCurrentDirectory & “\BIOSUpgrade\” & sMake & “\” & sModel & “\” & “wflash2.exe” & ” ” & sCurrentDirectory & “\BIOSUpgrade\” & sMake & “\” & sModel & “\” & sExeToRun & ” /clr /ign”

        With debugCode = true, I got: “ZTIBIOSUpgrade processing completed successfully.” But in reality, it did nothing at all. The bios is still the same.
        With debugCode = false, I got something else: “About to run command……(1902, 4) WshShell.Exec : The subsystem needed to support the image type is not present.”

        Any idea?

      • Hi again,

        My sModel is “ThinkCentre M91p” so I have a space btw “ThinkCentre” and “M91p”. How can I put all the path in brackets?

        To avoid the “space” problem for a moment I moved the files one level up and changed the script removing the sModel reference but it still doesn’t work either through the LTI command line (F8) nor under Windows which I have the following message:
        *********************************************
        Return code from command = 3
        ZTI ERROR – Non-zero return code by ZTIBIOSUpgrade, rc = 1
        *********************************************

      • Hi,

        It seems that the Lenovo Bios Upgrade command line utility doesn’t allow me to run the process from a share network. I must run it from the C:\.

        So it should be like:
        1. Extract the installer with the command: xxxxxx.exe /S
        2. Run the flash command line from: C:\SWTOOLS\FLASH\xxxxxx
        3. Remove the folder SWTOOLS

        What do you think?

      • I dont have any lenovo’s but thats sounds doable… the deployment share scripts folder is on Z: – my litetouch installation is always X:… but depending on when you launch the bios upgrade… there may be NO C: drive. So your script will need to copy all files to X: and run from there. Be sure to use full paths… the %CD% variable will be useful there… and double qoutes around any paths in case there is ever a SPACE in the path …
        so you can change the levovo section back to the original code which specifies the model specific script to launch….

        I took out the SPACES in model names in my dells to avoid having to deal with spaces in the path… but double quotes should take care of that issue if you choose not to do so…

        REM ThinkCentreM91p.cmd
        @echo off
        echo extracting bios files…
        “%CD%\xxxxx.exe” /S
        echo copying bios files to X drive…
        copy “%CD%\xxxxx” “X:\Bios”
        echo running bios upgrade from X drive…
        “X:\Bios\wflash2.exe” “”X:\Bios\IMAGE9h.ROM” /clr /ign

  12. I’m in a situation where I want to update the BIOS of clients having their OS rebuilt, but Dell are recommending that we upgrade the BIOS sequentially so if a client is on A02 I can’t go straight to A10. Any ideas on this? Brill post and keep up the good work!

  13. I’m having an issue where the INIT section of the customsettings.ini file is skipping certain settings I placed down in the DEFAULT section.

    Should I simply combine everything under DEFAULT, or is there another option available to me?

    Thanks!

    • No, the sections have a purpose, if you look on top of the customsettings.ini you will se Priority= and that will explain for the ZTIGather script what sections that should beexecuted and also in what order all the variables should be applied, as a general rule of thumb is First Writer Wins

      • I have quite a bit of info in my DEFAULT section to control the initial stages of the build process. Is there another method for doing this outside the customsettings.ini file, or can I run the Default section befor the INIT section and have it still work?

  14. Not even a case of being not supported now. More and more of Dells BIOS updates have a prerequisite of a certain BIOS level before the latest can be installed.

    On the Latitude E6410;
    If you’re on A01, you first install P02 before and installing a later rev.
    If you’re on A03-A08 you have to install A09 before moving on to a later rev (currently A11).

    This type of thing is making it harder for admins to manage client BIOS updates.
    Keep up the great work.
    S

  15. Hi,
    i tried ths script and it works fine, really :) except die BIOS Upgrade of HP 6200 Pro, which needs to be updated either wirth DOS FLASH, BIOS USB Flash or HPQFlash (this is intended for unattend / silent install). HPQflash doesn’t run under WinPE 3.0 or 4.0, the subsystem needed to support the image type is not present. first i thought it was a missing .NET oder DAC Feature, but it isn’t.
    i have no idea, but it seems that you guys are very successful using HP BIOS Upgrade within WinPE?

    Kind Regards

    Chris

  16. Important thing about migrating Dell BIOS.
    The executable package downloaded from Dell’s site is a Win32 application that need x32 complient OS,
    If you are using a WinPE x64 OS this will not work because 32-bits applications are not handle, the SysWOW32 folder is not present..
    You need then to use the WinPE x32 boot image to be able to upgrade Dell BIOS.
    – MDT 2010, can generate x86 and x64 boot image, but the OS deployed must be deployed by the corresponding arch. boot image (WinPE x86 for x86 OS, WinPE x64 for an x64 OS)
    – MDT 2012, is architecture independant, you can use x86 or x64 WinPE boot image to deploy Windows x86 or x64 OS)

  17. Hello! nice post, does this work from a SCCM 2012 TS? I have tried to update HP bios but seems like HPQFlash.exe doesnt run in WinPE?

  18. Hello Mikael,

    I found this old post about upgrade a bios during deployment. I used the scripts in the latest mdt but I. Running the scripts from a windows PE command promt looks good. But if a deployment starts. I always failes on the biosupgrade. With the Following Errors

    Litetouch deployment failed, Return Code = -2147467259 0x80004005
    failed to run the action: BiosUpgrade.
    Incorrect function. (Error: 00000001; Source: Windows)
    the Execution of the group (initialization) has failed and the execution has been Aborted. An Action failed.
    Operation aborted (Error: 80004004; Source: Windows)

    Can you help me with this ?

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.