03 May 2016

Install Dell Command Update and Flash BIOS in WinPE

I have wanted to get the process of flashing the BIOS into the WinPE environment for quite a while. With the help of Sapien's PowerShell Studio, I finally wrote the script to make this possible. The purpose is that it can flash it much quicker in the WinPE environment and it also gives two opportunities for he BIOS to be flashed during the build process. On some Dell machines, if the BIOS version is too far behind, there is an intermediary BIOS update that must be applied before the latest update can be. This gives the build the opportunity to get past that intermediary and apply the latest update before the build is completed.

To use this script, you will need to first install the Dell Command | Update on a system. If you are using the x86 version of WinPE, then install it on an x86 PC. The same on an x64 machine. Copy all of the contents of the %PROGRAMFILES%\Dell\CommandUpdate folder to a folder on a network share. Next, copy the msi.dll file from the %WINDIR%\System32 folder to the same folder share.

I created a task sequence folder and then put three task sequences underneath it.

Now it's time to create the Run Command Line task sequence. The first is to map to the folder share where you copied the CommandUpdate folder to. I used T: as my drive letter and used the following command: net use t: \\<NetworkShareFolder> /USER:<domain>\<username> <Password>. This is not recorded in any of the logs, so you don't risk the password being seen by unwanted eyes so long as they cannot access the task sequence.

The second task sequence is to install and update the Dell BIOS. This is also a Run Command Line sequence. The command line I use is: powershell.exe -executionpolicy bypass -file t:\install.ps1.

The final task sequence is unmapping the network drive via a Run Command Line sequence. The command line for this is net use t: /delete

I have also included in the script the ability to apply an XML file to the dcu-cli.exe. The XML file specifies what driver types to apply to the system. It looks for the XML file in the same directory as the PowerShell script. I found that if I execute the dcu-cli.exe with no switches, it does try to install one driver update to the WinPE environment, but it fails and continues to install the BIOS update with no issues.

Here is a video of the tool in action during the initial phase of the build process:

You can download the script from here.


1:  <#  
2:       .SYNOPSIS  
3:            Install Dell Command | Update and Update the BIOS  
5:       .DESCRIPTION  
6:            Copy over the Dell Command | Update and install the BIOS  
8:       .PARAMETER Source  
9:            Source folder containing the Dell Command | Update files  
11:       .PARAMETER Destination  
12:            Location to copy the Dell Command | Update files to  
14:       .PARAMETER XMLFile  
15:            XML file that limits the Dell Command | Update to only scan for a BIOS update  
17:       .NOTES  
18:            ===========================================================================  
19:            Created with:     SAPIEN Technologies, Inc., PowerShell Studio 2016 v5.2.120  
20:            Created on:       4/27/2016 10:17 AM  
21:            Created by:       Mick Pletcher  
22:            Organization:  
23:            Filename:         UpdateBIOSWinPE.ps1  
24:            ===========================================================================  
25:  #>  
26:  [CmdletBinding()]  
27:  param  
28:  (  
29:            [string]$Source = 't:\',  
30:            [string]$Destination = 'x:\DCU',  
31:            [string]$XMLFile  
32:  )  
34:  function Copy-Folder {  
35:  <#  
36:       .SYNOPSIS  
37:            Copy Folder  
39:       .DESCRIPTION  
40:            Copy folder to destination  
42:       .PARAMETER SourceFolder  
43:            Folder to copy contents from  
45:       .PARAMETER DestinationFolder  
46:            Folder to copy contents to  
48:       .PARAMETER Subfolders  
49:            Include all subfolders  
51:       .PARAMETER Mirror  
52:            Mirror the destination folder with the source folder. Contents that exist in the destination folder, but not in the source folder, will be deleted.  
54:       .EXAMPLE  
55:            PS C:\> Copy-Folder -SourceFolder 'Value1' -DestinationFolder 'Value2'  
57:       .NOTES  
58:            Additional information about the function.  
59:  #>  
61:       [CmdletBinding()]  
62:       param  
63:       (  
64:                 [string]$SourceFolder,  
65:                 [string]$DestinationFolder,  
66:                 [ValidateSet($true, $false)][boolean]$Subfolders = $false,  
67:                 [ValidateSet($true, $false)][boolean]$Mirror = $false  
68:       )  
70:       $Executable = $env:windir + "\system32\Robocopy.exe"  
71:       $Switches = $SourceFolder + [char]32 + $DestinationFolder + [char]32 + "/eta"  
72:       If ($Subfolders -eq $true) {  
73:            $Switches = $Switches + [char]32 + "/e"  
74:       }  
75:       If ($Mirror -eq $true) {  
76:            $Switches = $Switches + [char]32 + "/mir"  
77:       }  
78:       Write-Host "Copying "$SourceFolder"....." -NoNewline  
79:       $ErrCode = (Start-Process -FilePath $Executable -ArgumentList $Switches -Wait -Passthru).ExitCode  
80:       If (($ErrCode -eq 0) -or ($ErrCode -eq 1)) {  
81:            Write-Host "Success" -ForegroundColor Yellow  
82:       } else {  
83:            Write-Host "Failed with error code"$ErrCode -ForegroundColor Red  
84:       }  
85:  }  
87:  function Update-BIOS {  
88:  <#  
89:       .SYNOPSIS  
90:            Update to the latest BIOS Version  
92:       .DESCRIPTION  
93:            Execute the DCU-CLI.exe to query Dell for the latest BIOS version  
95:       .NOTES  
96:            Additional information about the function.  
97:  #>  
99:       [CmdletBinding()]  
100:       param ()  
102:       $Executable = $Destination + "\dcu-cli.exe"  
103:       If ($XMLFile -eq "") {  
104:            $Switches = " "  
105:       } else {  
106:            $XMLFile = $Destination + "\" + $XMLFile  
107:            $Switches = "/policy" + [char]32 + $XMLFile  
108:       }  
109:       #$Switches = " "  
110:       Write-Host "Updating BIOS....." -NoNewline  
111:       $ErrCode = (Start-Process -FilePath $Executable -ArgumentList $Switches -Wait -Passthru).ExitCode  
112:       If ($ErrCode -eq 0) {  
113:            Write-Host "Success" -ForegroundColor Yellow  
114:       } else {  
115:            Write-Host "Failed with error code"$ErrCode -ForegroundColor Red  
116:       }  
117:  }  
119:  #Copy contents of the Dell Command | Update folder to the WinPE directory  
120:  Copy-Folder -SourceFolder $Source -DestinationFolder $Destination -Subfolders $true -Mirror $true  
121:  #Copy msi.dll to the WinPE system32 folder to make msiexec.exe functional  
122:  Copy-Item -Path $Destination"\msi.dll" -Destination "x:\windows\system32" -Force  
123:  #Execute the dcu-cli.exe to update the BIOS  
124:  Update-BIOS  


  1. Hello Mick,

    I ran the script on my Latitude E5430, but I received the following error:
    Failed with error code 2
    Please advise.

    Thank you!

    1. That is a fatal error from the DCU-CLI.exe. Do you have the correct msi.dll copied over? It must come from the same architecture as the WinPE is. I am using 32-bit WinPE 5.0, therefor I pulled the msi.dll from a windows 8.1 32-bit machine.

  2. Hi Mick,
    I tried doing this in WinPE 10 using DCU 2.1.1 and I always seem to receive an error 3 when doing this on an OptiPlex 3020 with A02 BIOS installed. I ran a log and it is tracing to Dell's FTP site OK, despite the fact that I'm booting into WinPE 10 using a USB key as PoC before I bring down my production boot.wim and use DISM to inject the PowerShell modules into it. I'm not certain why that would make a difference, but maybe it does.

  3. I am not sure what I might be doing wrong. It fails every time. I want to be able to use a specific BIOS update and only have the one install. I believe i need to use the config xml, but not sure what to do exactly.

    1. I never could get the .XML file to work correctly. The best I could do was to just execute the dcu-cli.exe with no parameters.