none
BIOS Update and Making MDT wait BIOSUpdate.exe process to complete before restarting

    Question

  • Good afternoon all,

    I am trying to update the BIOS during the State Restore Phase, right after the Tattoo step and I am having some fun trying to work that out. Below, I have the script that I would like to use. Script works great if I pause deployment, run the script, and then resume deployment. It also works great post deployment. Of course, I make sure to map my MDT deployment share to drive Z:\ before running the script.

    Function Invoke-Exe{
        [CmdletBinding(SupportsShouldProcess=$true)]

        param(
            [parameter(mandatory=$true,position=0)]
            [ValidateNotNullOrEmpty()]
            [string]
            $Executable,
            [parameter(mandatory=$true,position=1)]
            [ValidateNotNullOrEmpty()]
            [string]
            $Arguments,
            [parameter(mandatory=$false,position=2)]
            [ValidateNotNullOrEmpty()]
            [int]
            $SuccessfulReturnCode = 0
        )
        Write-Verbose "Running $ReturnFromEXE = Start-Process -FilePath $Executable -ArgumentList $Arguments -NoNewWindow -Wait -Passthru"
        $ReturnFromEXE = Start-Process -FilePath $Executable -ArgumentList $Arguments -NoNewWindow -Wait -Passthru
        Write-Verbose "Returncode is $($ReturnFromEXE.ExitCode)"
        #if(!($ReturnFromEXE.ExitCode -eq $SuccessfulReturnCode)) {
        #    throw "$Executable failed with exit code $($ReturnFromEXE.ExitCode)"
        #}
    }
    # Collect data
    $ScriptRoot = "Z:\Scripts\custom\PS\"
    $exe = "BIOSUpdate.exe"
    $make = (Get-WmiObject WIN32_COMPUTERSYSTEM).Manufacturer
    $model = (Get-WmiObject WIN32_COMPUTERSYSTEM).Model
    $BIOSFilePath = $ScriptRoot + "BIOSUpdates\" + $make + "\" + $model + "\"
    $command = $BIOSFilePath + $exe
    $arguments = "/s /f"
    $CompBIOSVersion = (Get-WmiObject WIN32_BIOS).SMBIOSBIOSVersion
    $CurrBIOSVersion = Get-Content "$BIOSFilePath\version.txt"
    # Debugging
    #Write-Output $ScriptRoot
    #Write-Output $BIOSFilePath
    #Write-Output $CompBIOSVersion
    #Write-Output $CurrBIOSVersion

    If ($CompBIOSVersion -ne $CurrBIOSVersion)
    {
     # Update BIOS
        Invoke-Exe $command $arguments
    }

    I think that what I need is for MDT to pause for a few seconds and let the BIOSUpdate.exe command run. I've tried several things such as using -Wait as part of Start-Process. I've assigned the start process to a variable, i.e., $process = Start-Process … and then using the $process.WaitToExit() method. My latest attempt is trying to use a batch file called wait.bat.

    It's contents are simply:

    @echo off
    title Waiting %1 Seconds...
    timeout %1

    Syntax is wait n, where n is the number of seconds to wait.

    So, in my task sequence, I set up a Run a PowerShell script task. I run %SCRIPTROOT%\custom\PS\UpdateBIOSPE.ps1.

    Then, I try a run a command line statement:

    Command line: cmd /c wait 30

    Start in: %SCRIPTROOT%\custom\batch

    MDT appears to run the command line statement and quickly moves on to the next item in the task list, not giving BIOSUpdate.exe enough time to finish.

    I appreciate any thoughts on this matter. I am definitely interested in a timeout command, PowerShell script, or application because there are several applications that I would like to install where I would like MDT to wait until they are completed before moving on.

    Thank you,

    Matt Trammell


    Friday, September 7, 2018 9:47 PM

Answers

  • Good morning!

    I answered my own question. I had the filename wrong in my Run Powershell Script line. I was trying to get the BIOS update to work in the Windows PE boot environment and had PE tacked on to the file name. After failing there, I decided to go ahead and stick with the State Restore step. So, I took the PE off the file name, but I did not update the task sequence.  That's what I get for trying to work quickly and solve a problem on Friday afternoon before heading out for the weekend. I did make a slight change to the Invoke-Exe function. I changed it to run an exe without any arguments. So, the following powershell code seems to work for a BIOS update:

    Function Invoke-Exe{
        [CmdletBinding(SupportsShouldProcess=$true)]
        param(
            [parameter(mandatory=$true,position=0)]
            [ValidateNotNullOrEmpty()]
            [string]
            $Executable,
            [parameter(mandatory=$false,position=1)]
            [string]
            $Arguments,
            [parameter(mandatory=$false,position=2)]
            [ValidateNotNullOrEmpty()]
            [int]
            $SuccessfulReturnCode = 0
        )
     If (!($Arguments.Equals("")))
        {
            Write-Verbose "Running $ReturnFromEXE = Start-Process -FilePath $Executable -ArgumentList $Arguments -NoNewWindow -Wait -Passthru"
            $ReturnFromEXE = Start-Process -FilePath $Executable -ArgumentList $Arguments -NoNewWindow -Wait -Passthru
        }
        Else
        {
            Write-Verbose "Running $ReturnFromEXE = Start-Process -FilePath $Executable -NoNewWindow -Wait -Passthru"
            $ReturnFromEXE = Start-Process -FilePath $Executable -NoNewWindow -Wait -Passthru
        }
        Write-Verbose "Returncode is $($ReturnFromEXE.ExitCode)"
        #if(!($ReturnFromEXE.ExitCode -eq $SuccessfulReturnCode)) {
        #    throw "$Executable failed with exit code $($ReturnFromEXE.ExitCode)"
        #}
    }
    # Collect data
    $ScriptRoot = "Z:\Scripts\custom\PS\"
    $exe = "BIOSUpdate.exe"
    $make = (Get-WmiObject WIN32_COMPUTERSYSTEM).Manufacturer
    $model = (Get-WmiObject WIN32_COMPUTERSYSTEM).Model
    $BIOSFilePath = $ScriptRoot + "BIOSUpdates\" + $make + "\" + $model + "\"
    $command = $BIOSFilePath + $exe
    $arguments = "/s /f"
    $CompBIOSVersion = (Get-WmiObject WIN32_BIOS).SMBIOSBIOSVersion
    $CurrBIOSVersion = Get-Content "$BIOSFilePath\version.txt"
    # Debugging
    #Write-Output $ScriptRoot
    #Write-Output $BIOSFilePath
    #Write-Output $CompBIOSVersion
    #Write-Output $CurrBIOSVersion

    If ($CompBIOSVersion -ne $CurrBIOSVersion)
    {
     # Update BIOS
        Invoke-Exe $command $arguments
    }

    -Matt

    • Marked as answer by MTram18 Monday, September 10, 2018 4:46 PM
    Monday, September 10, 2018 4:46 PM