Update-DellBios.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
<#
    .SYNOPSIS
        Updates Dell Bios
    .DESCRIPTION
        Automatically updates the BIOS using Dell Update Catalog
    .NOTES
        Name: Update-DellBios.ps1
        Author: David Segura
  Version: 18.05.30
    .PARAMETER Silent
        Silently update the BIOS and exit
    .PARAMETER Restart
        Silently update the BIOS and restart the computer
    .EXAMPLE
  Update-DellBios
  Launches the BIOS Upgrade with Prompts
    .EXAMPLE
  Update-DellBios -Silent
  Silently update the BIOS and exit
    .EXAMPLE
  Update-DellBios -Restart
  Silently update the BIOS and restart the computer
#>


[CmdletBinding()]
Param(
    [switch]$Restart,
    [switch]$Silent
)

Write-Host "Update-DellBios.ps1 PowerShell Script" -ForegroundColor Green

#Run Elevated
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
    Write-Host "Checking User Account Control settings ..." -ForegroundColor Green
    if ((Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System).EnableLUA -eq 0) {
        #UAC Disabled
        Write-Host "User Account Control is Disabled ... " -ForegroundColor Green
        Write-Host "You will need to correct your UAC Settings ..." -ForegroundColor Green
        Write-Host "Try running this script in an Elevated PowerShell session ... Exiting" -ForegroundColor Green
        Start-Sleep -s 10
        Return
    } else {
        #UAC Enabled
        Write-Host "UAC is Enabled" -ForegroundColor Green
        Start-Sleep -s 3
        if ($Silent) {
            Write-Host "This script will relaunch with Elevated Permissions (Silent) ..." -ForegroundColor Green
            Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`" -Silent" -Verb RunAs -Wait
        } elseif($Restart) {
            Write-Host "This script will relaunch with Elevated Permissions (Restart) ..." -ForegroundColor Green
            Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`" -Restart" -Verb RunAs -Wait
        } else {
            Write-Host "This script will relaunch with Elevated Permissions ..." -ForegroundColor Green
            Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs -Wait
        }
        Exit 0
    }
} else {
Write-Host "Running with Elevated Permissions ..." -ForegroundColor Green
Write-Host ""
}

Start-Transcript -path (Join-Path $env:Temp BiosUpdate.log)


#Check if this is a Dell System
if ( ! ($((Get-CimInstance -ClassName Win32_ComputerSystem).Manufacturer).Trim() -like "*Dell*")) {
    Write-Host "This script will only run on Dell Systems. Exiting . . ." -ForegroundColor Green
    Start-Sleep -s 5
    Stop-Transcript
    Exit 0
}

    #======================================================================================
    #System Information
    $Manufacturer = $((Get-CimInstance -ClassName Win32_ComputerSystem).Manufacturer).Trim()
    $Model = $((Get-CimInstance -ClassName Win32_ComputerSystem).Model).Trim()

    #Try to get the SystemSKU from WMI
    try {$SystemSKU = $((Get-CimInstance -ClassName Win32_ComputerSystem).SystemSKUNumber).Trim()}
    catch {
        Write-Host "SystemSKU not in WMI" -ForegroundColor Red
        $SystemSKU = "Unknown"
    }

    If ($SystemSKU -eq "Unknown") {
        #Try to get the SystemSKU from the Registry
        try {$SystemSKU = $((Get-ItemProperty -Path HKLM:\HARDWARE\DESCRIPTION\System\BIOS).SystemSKU).Trim()}
        catch {
            Write-Host "SystemSKU not in Registry" -ForegroundColor Red
            $SystemSKU = "Unknown"
        }
    }

    $SerialNumber = $((Get-CimInstance -ClassName Win32_BIOS).SerialNumber).Trim()
    $BIOSVersion = $((Get-CimInstance -ClassName Win32_BIOS).SMBIOSBIOSVersion).Trim()
    $RunningOS = $((Get-CimInstance -ClassName Win32_OperatingSystem).Caption).Trim()
    $OSArchitecture = $((Get-CimInstance -ClassName Win32_OperatingSystem).OSArchitecture).Trim()
    
    Write-Host "Manufacturer: $Manufacturer" -ForegroundColor Cyan
    Write-Host "Model: $Model" -ForegroundColor Cyan
    Write-Host "SystemSKU: $SystemSKU" -ForegroundColor Cyan
    Write-Host "SerialNumber: $SerialNumber" -ForegroundColor Cyan
    Write-Host "BIOS Version: $BIOSVersion" -ForegroundColor Cyan
    Write-Host "Running OS: $RunningOS" -ForegroundColor Cyan
    Write-Host "OS Architecture: $OSArchitecture" -ForegroundColor Cyan
    if ($env:SystemDrive -eq "X:") {Write-Host "System is running in WinPE" -ForegroundColor Green}
    Write-Host ""
    #======================================================================================

    $DellBiosRoot = $PSScriptRoot
    $DellBiosUpdateXml = Join-Path $DellBiosRoot "DellBios.xml"
    $DellFlash64wExe = Join-Path $DellBiosRoot "Flash64W.exe"
    
    Write-Host "Dell Bios Update Root: $DellBiosRoot" -ForegroundColor Cyan
    Write-Host "Dell Bios Update Xml: $DellBiosUpdateXml" -ForegroundColor Cyan
    Write-Host "Dell Flash64 Exe: $DellFlash64wExe" -ForegroundColor Cyan
    Write-Host ""

    if ( ! ( test-path $DellBiosUpdateXml ) ) { 
        Write-Host "Could not locate $DellBiosUpdateXml ... Exiting" -ForegroundColor Red
        Start-Sleep -s 5
        Stop-Transcript
        Exit 0
    }
    
    if ( ! ( test-path $DellFlash64wExe ) ) { 
        Write-Host "Could not locate $DellFlash64wExe ... Exiting" -ForegroundColor Red
        Start-Sleep -s 5
        Stop-Transcript
        Exit 0
    }

    Write-Host ""
    Write-Host "Reading $DellBiosUpdateXml ..." -ForegroundColor Green
    $DellBiosUpdateList = Import-CliXml $DellBiosUpdateXml
    Write-Host "Success!"

    Write-Host ""
    If ($SystemSKU.Length -eq 4) {
        Write-Host "Filtering XML for items compatible with SystemSKU $SystemSKU ..." -ForegroundColor Green
        $DellBiosUpdateList = $DellBiosUpdateList | Where-Object {$_.SupportedSystemID -Contains $SystemSKU}
        Write-Host "Success!"
    } else {
        Write-Host "Filtering XML for items compatible with $Model ..." -ForegroundColor Green
        $DellBiosUpdateList = $DellBiosUpdateList | Where-Object {$_.SupportedDevices -Contains $Model}
        Write-Host "Success!"
    }

    if ($DellBiosUpdateList.PackageID.Count -eq '1') {
        $DellBiosUpdateList
    } else {
        Write-Host "Could not locate a compatible BIOS Update ... Exiting" -ForegroundColor Green
        Start-Sleep -s 5
        Stop-Transcript
        Exit 0
    }

    $BiosUpdate = @(Get-ChildItem -Path $DellBiosRoot -Include $DellBiosUpdateList.FileName -Recurse -File)

    if ($BiosUpdate.Count -eq '1') {
        Write-Host "Local Bios Update" -ForegroundColor Green
        $BiosUpdate
    } else {
        Write-Host "Could not locate a downloaded BIOS Update ... Exiting" -ForegroundColor Green
        Start-Sleep -s 5
        Stop-Transcript
        Exit 0
    }

    $DownloadedBiosVersion = $DellBiosUpdateList.DellVersion

    if ($BIOSVersion -like "A*") {
        $BIOSVersion = $BIOSVersion -replace "A",""
        $DownloadedBiosVersion = $DownloadedBiosVersion -replace "A",""
    } elseif ($BIOSVersion -like "*.*") {
        $BIOSVersion = [Version]$BIOSVersion
        $DownloadedBiosVersion = [Version]$DownloadedBiosVersion
    }

    if ($BIOSVersion -eq $DownloadedBiosVersion) {
        Write-Host "You are running the current BIOS Version ... Exiting" -ForegroundColor Cyan
        Start-Sleep -s 5
        Stop-Transcript
        Exit 0
    }

    if ($BIOSVersion -gt $DownloadedBiosVersion) {
        Write-Host "You are running a newer BIOS Version ... Exiting" -ForegroundColor Cyan
        Start-Sleep -s 5
        Stop-Transcript
        Exit 0
    }

    Write-Host "Bios Update will be applied" -ForegroundColor Green
    Write-Host "Starting Dell Bios Update ..." -ForegroundColor Green
    
    #Registry Restart Computer Key
    $registryPath = "HKLM:\Software\BiosUpdate"
    $registryName = "RebootPending"
    $registryValue = "0"

    if (!(Test-Path $registryPath)) {
        New-Item -Path $registryPath -Force | Out-Null
        New-ItemProperty -Path $registryPath -Name $registryName -Value $registryValue -PropertyType String -Force | Out-Null
    }

    if ($env:SystemDrive -eq "X:") {
        if ($OSArchitecture -like "*64*") {
            if ($Silent) {
            Write-Host "Executing (Silent): $DellFlash64wExe /b=`"$BiosUpdate`"" -ForegroundColor Green
            Start-Process -FilePath $DellFlash64wExe -ArgumentList "/b=`"$BiosUpdate`"","/s" -Wait
            New-ItemProperty -Path $registryPath -Name $registryName -Value "1" -PropertyType String -Force | Out-Null
            Stop-Transcript
            [System.Environment]::Exit(0)
            } elseif ($Restart) {
            Write-Host "System will restart automatically" -ForegroundColor Green
            Write-Host "Executing (Restart): $DellFlash64wExe /b=`"$BiosUpdate`"" -ForegroundColor Green
            Stop-Transcript
            Start-Process -FilePath $DellFlash64wExe -ArgumentList "/b=`"$BiosUpdate`"","/s","/r" -Wait
            [System.Environment]::Exit(0)
            } else {
            Write-Host "System will restart automatically" -ForegroundColor Green
            Write-Host "Executing: $DellFlash64wExe /b=`"$BiosUpdate`"" -ForegroundColor Green
            Start-Process -FilePath $DellFlash64wExe -ArgumentList "/b=`"$BiosUpdate`"" -Wait
            Stop-Transcript
            [System.Environment]::Exit(0)
            }
        }
    }

    if ($RunningOS -Like "*Windows 10*") {
        Write-Host "Checking Bitlocker ..." -ForegroundColor Green
        #http://www.dptechjournal.net/2017/01/powershell-script-to-deploy-dell.html
        #https://github.com/dptechjournal/Dell-Firmware-Updates/blob/master/Install_Dell_Bios_upgrade.ps1
        $drive = Get-BitLockerVolume | where { $_.ProtectionStatus -eq "On" -and $_.VolumeType -eq "OperatingSystem" }
        if ($drive) {
            Write-Host "Suspending Bitlocker ..." -ForegroundColor Green
            Suspend-BitLocker -Mountpoint $drive -RebootCount 1
            if (Get-BitLockerVolume -MountPoint $drive | where ProtectionStatus -eq "On") {
                Write-Host "Suspending Bitlocker Failed ... Exiting" -ForegroundColor Green
                Stop-Transcript
                Exit 0
            }
        }
    }
        
    if ($Silent) {
        Write-Host "Executing (Silent): $BiosUpdate" -ForegroundColor Green
        Start-Process ($BiosUpdate.FullName) -ArgumentList "/s" -Wait
        New-ItemProperty -Path $registryPath -Name $registryName -Value "1" -PropertyType String -Force | Out-Null
        Stop-Transcript
        [System.Environment]::Exit(0)
    } elseif ($Restart) {
        Write-Host "System will restart automatically" -ForegroundColor Green
        Write-Host "Executing (Restart): $BiosUpdate" -ForegroundColor Green
        Stop-Transcript
        Start-Process ($BiosUpdate.FullName) -ArgumentList "/s","/r" -Wait
        [System.Environment]::Exit(0)
    } else {
        Write-Host "System will restart automatically" -ForegroundColor Green
        Write-Host "Executing: $BiosUpdate" -ForegroundColor Green
        Start-Process ($BiosUpdate.FullName) -Wait
        Stop-Transcript
        [System.Environment]::Exit(0)
    }
Start-Process PowerShell_ISE.exe -Wait
Read-Host -Prompt "Press Enter to Continue"