Advertisement
marcd2k20

OSD Dell BIOS Updater

Mar 27th, 2025 (edited)
235
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PowerShell 11.64 KB | Source Code | 0 0
  1. #Initialize Task Sequence Environment
  2. $TSEnv=New-Object -COMObject Microsoft.SMS.TSEnvironment
  3. $SMSTSLogPath=$TSEnv.Value("_SMSTSLogPath")
  4. $OSDTargetSystemDrive=$TSEnv.Value("OSDTargetSystemDrive")
  5.  
  6. #Disable Progress bars to speed up Invoke-WebRequest
  7. $ProgressPreference = 'SilentlyContinue'
  8.  
  9. #Define Log file path
  10. $Script:Logfile="$($SMSTSLogPath)\Update-BIOS.log"
  11.  
  12. #Function to write a log entry, with handling for file locks
  13. Function Write-LogEntry
  14. {
  15.     Param($Value)
  16.     $Tries=0
  17.     $Success=$False
  18.     Do {
  19.         Try{
  20.             if ($Value-ne " "){
  21.                 $Timestamp="[$((Get-Date).ToString())] "
  22.             } else {
  23.                 $Timestamp=""
  24.             }
  25.             Add-Content -Value "$($Timestamp)$($Value)" -Path $Script:LogFile -Force -ErrorAction Stop
  26.             $Success=$True
  27.         }
  28.         Catch{
  29.             $Success=$False
  30.             $Tries++
  31.             Start-Sleep -Seconds 1
  32.         }  
  33.     }
  34.     Until ($Success -eq $True -or $Tries -ge 5)
  35. }
  36.  
  37. #Function to delete files created by the script
  38. Function Cleanup-Temp
  39. {
  40.     Write-LogEntry -Value " "
  41.     Write-LogEntry -Value "Cleaning up Temp files"
  42.     Try{
  43.         Remove-Item "$($TempFolder)" -Recurse -Force -ErrorAction Stop
  44.         Write-LogEntry -Value "Successfully cleaned up Temp files"
  45.     }
  46.     Catch {
  47.         Write-LogEntry -Value "Failed to clean up Temp files, you will need to manually remove $($TempFolder)"
  48.     }
  49. }
  50.  
  51. #Function to clean up and provide exit code before exiting script
  52. Function Exit-Script
  53. {
  54.     Param($ExitCode)
  55.     Cleanup-Temp
  56.     Write-LogEntry -Value " "
  57.     Write-LogEntry -Value "Script Completed with exit code $($ExitCode)"
  58.     Exit $ExitCode
  59. }
  60.  
  61. #Create Log File
  62. If (Test-Path $LogFile){
  63.     Remove-Item $LogFile -Force
  64. }
  65.  
  66. Write-LogEntry -Value "Started BIOS Upgrade Script"
  67.  
  68. #Create Temp Folder
  69. Write-LogEntry -Value " "
  70. Write-LogEntry -Value "Creating BIOS folder in Temp"
  71. $TempFolder="$($env:TEMP)\BIOS"
  72. If (!(Test-Path $TempFolder)){
  73.     Try{
  74.         New-Item -Path "$($env:Temp)" -Name "BIOS" -ItemType Directory -Force -ErrorAction Stop
  75.         Write-LogEntry -Value "Successfully created $($TempFolder) folder"
  76.     }
  77.     Catch{
  78.         Write-LogEntry -Value "Failed to create $($TempFolder) folder"
  79.         Exit-Script -ExitCode 100
  80.     }
  81. } else {
  82.     Write-LogEntry -Value "$($TempFolder) folder already exists"
  83. }
  84.  
  85. #Get System SKU
  86. Write-LogEntry -Value " "
  87. Write-LogEntry -Value "Getting System SKU value from WMI"
  88. Try {
  89.     $Script:SystemSku="$((Get-WMIObject -Namespace root\WMI -Class MS_SystemInformation -ErrorAction Stop).SystemSku)"
  90.     Write-LogEntry -Value "Retrieved System SKU value: $($Script:SystemSku)"
  91. }
  92. Catch{
  93.     Write-LogEntry -Value "Failed to retrieve System SKU value"
  94.     Exit-Script -ExitCode 101
  95. }
  96.  
  97. #Get System BIOS Version and convert to Version string
  98. Write-LogEntry -Value " "
  99. Write-LogEntry -Value "Getting BIOS version"
  100. $Script:BIOSVersion=(Get-WMIObject -Class win32_bios -Property smbiosbiosversion).smbiosbiosversion
  101. [string]$Script:BIOSPaddedVersion=$Script:BIOSVersion -replace "[^0-9.]", "" -replace "^0", ""
  102. $Script:BIOSPaddedVersion += ".0" * (4 - $Script:BIOSPaddedVersion.Split('.').Count)
  103. [version]$Script:BIOSPaddedVersion=$Script:BIOSPaddedVersion
  104. Write-LogEntry -Value "Retrieved BIOS Version: $($Script:BIOSVersion)"
  105. Write-LogEntry -Value "Converted BIOS Version: $([string]$Script:BIOSPaddedVersion)"
  106.  
  107. #Download BIOS Flash Tool
  108. Write-LogEntry -Value " "
  109. Write-LogEntry -Value "Downloading BIOS Flash Tool"
  110. Try{
  111.     $Script:FlashToolZIP="FlashVer3.3.28.zip"
  112.     Invoke-WebRequest -Uri "https://downloads.dell.com/FOLDER12288556M/1/$($Script:FlashToolZIP)" -OutFile "$($TempFolder)\$($Script:FlashToolZIP)" -ErrorAction Stop
  113.     Write-LogEntry -Value "Successfully downloaded https://downloads.dell.com/FOLDER12288556M/1/$($Script:FlashToolZIP)"
  114. }
  115. Catch{
  116.     Write-LogEntry -Value "Failed to download https://downloads.dell.com/FOLDER12288556M/1/$($Script:FlashToolZIP)"
  117.     Exit-Script -ExitCode 102
  118. }
  119.  
  120. #Download Model Catalog XML
  121. Write-LogEntry -Value " "
  122. Write-LogEntry -Value "Downloading Model Catalog XML"
  123. Try{
  124.     $Script:CatalogCABName="CatalogIndexPC.cab"
  125.     Invoke-WebRequest -Uri "https://downloads.dell.com/catalog/$Script:CatalogCABName" -OutFile "$($TempFolder)\$Script:CatalogCABName" -ErrorAction Stop
  126.     Write-LogEntry -Value "Successfully downloaded https://downloads.dell.com/catalog/$Script:CatalogCABName"
  127. }
  128. Catch{
  129.     Write-LogEntry -Value "Failed to download https://downloads.dell.com/catalog/$Script:CatalogCABName"
  130.     Exit-Script -ExitCode 103
  131. }
  132.      
  133. #Extract BIOS Flash Tool
  134. Write-LogEntry -Value " "
  135. Write-LogEntry -Value "Extracting BIOS Flash Tool"
  136. Try{
  137.     Expand-Archive -Path "$($TempFolder)\$($Script:FlashToolZIP)" -DestinationPath "$($TempFolder)" -Force -ErrorAction Stop
  138.     $Flash64W=(Get-ChildItem -Path $($TempFolder) -Recurse -ErrorAction Stop | Where-Object {$_.Name -eq "Flash64W.exe"}).FullName
  139.     Move-Item -Path $Flash64W -Destination $($TempFolder) -Force -ErrorAction Stop
  140.     Write-LogEntry -Value "Successfully extracted Flash64W.exe from $($Script:FlashToolZIP)"
  141. }
  142. Catch{
  143.     Write-LogEntry -Value "Failed to extract Flash64W.exe from $($Script:FlashToolZIP)"
  144.     Exit-Script -ExitCode 104
  145. }
  146.  
  147. #Extract Catalog XML
  148. Write-LogEntry -Value " "
  149. Write-LogEntry -Value "Extracting Model Catalog XML"
  150. Try{
  151.     $Script:CatalogXMLName = $Script:CatalogCABName -Replace "cab","xml"
  152.     Start-Process "$($env:windir)\system32\expand.exe" -WindowStyle Hidden -ArgumentList "`"$($TempFolder)\$($Script:CatalogCABName)`" `"$($TempFolder)\$($Script:CatalogXMLName)`"" -Wait -ErrorAction Stop
  153.     Write-LogEntry -Value "Successfully extracted $($Script:CatalogXMLName) from $($Script:CatalogCABName)"
  154. }
  155. Catch{
  156.     Write-LogEntry -Value "Failed to extract $($Script:CatalogXMLName) from $($Script:CatalogCABName)"
  157.     Exit-Script -ExitCode 105    
  158. }
  159.  
  160. #Get Model URL from Catalog XML
  161. Write-LogEntry -Value " "
  162. Write-LogEntry -Value "Get Model URL from Catalog XML"
  163. Try{
  164.     [xml]$Script:ModelCatalog = Get-Content "$($TempFolder)\CatalogIndexPC.xml" -ErrorAction Stop
  165.     $Script:ModelURL="https://$($ModelCatalog.ManifestIndex.baseLocation)/$(($Script:ModelCatalog.ManifestIndex.GroupManifest | Where-Object {$_.supportedsystems.brand.model.systemID -eq $Script:SystemSKU}).manifestinformation.path)"
  166.     Write-LogEntry -Value "Successfully retrieved Model URL: $($Script:ModelURL)"
  167. }
  168. Catch{
  169.     Write-LogEntry -Value "Failed to retrieve Model URL"
  170.     Exit-Script -ExitCode 106    
  171. }
  172.  
  173. #Download Model XML
  174. Write-LogEntry -Value " "
  175. Write-LogEntry -Value "Downloading Model Catalog XML"
  176. Try{
  177.     $Script:BIOSCABName = Split-Path -Path $Script:ModelURL -Leaf
  178.     Invoke-WebRequest -Uri $Script:ModelURL -OutFile "$($TempFolder)\$($Script:BIOSCABName)" -ErrorAction Stop
  179.     Write-LogEntry -Value "Successfully downloaded $($Script:ModelURL)"
  180. }
  181. Catch{
  182.     Write-LogEntry -Value "Failed to download $($Script:ModelURL)"
  183.     Exit-Script -ExitCode 107
  184. }
  185.  
  186. #Extract Model XML
  187. Write-LogEntry -Value " "
  188. Write-LogEntry -Value "Extracting Model XML"
  189. Try{
  190.     $Script:BIOSXMLName=$Script:BIOSCABName -Replace "cab","xml"
  191.     Start-Process "$($env:windir)\system32\expand.exe" -WindowStyle Hidden -ArgumentList "`"$($TempFolder)\$($Script:BIOSCABName)`" `"$($TempFolder)\$($Script:BIOSXMLName)`"" -Wait -ErrorAction Stop
  192.     Write-LogEntry -Value "Successfully extracted $Script:BIOSXMLName from $Script:BIOSCABName"
  193. }
  194. Catch{
  195.     Write-LogEntry -Value "Failed to extract $Script:BIOSXMLName from $Script:BIOSCABName"
  196.     Exit-Script -ExitCode 108    
  197. }
  198.  
  199. #Get Highest BIOS Version from XML
  200. Write-LogEntry -Value " "
  201. Write-LogEntry -Value "Finding Latest BIOS Version"
  202. Try{
  203.     [xml]$Script:ModelXML = Get-Content "$($TempFolder)\$($Script:BIOSXMLName)" -ErrorAction Stop
  204.     $Script:BIOSPacks=@($Script:ModelXML.Manifest.SoftwareComponent | Where-Object {$_.ComponentType.Value -eq "BIOS"})
  205.     $Script:BIOSPacks = $Script:BIOSPacks | ForEach-Object {
  206.         [PSCustomObject]@{
  207.             Version = $_.vendorVersion
  208.             PaddedVersion=[version]$(
  209.                 $Padded=$_.vendorVersion -replace "[^0-9.]", "" -replace "^0", ""
  210.                 $Padded += ".0" * (4 - $Padded.Split('.').Count)
  211.                 $Padded
  212.             )
  213.             DownloadPath = "https://$($Script:ModelXML.Manifest.baselocation)/$($_.path)"
  214.         }
  215.     }
  216.     $Script:BIOSPack = $Script:BIOSPacks| Sort-Object -Property PaddedVersion -Descending | Select-Object -First 1
  217.     Write-LogEntry -Value "Successfully retrieved BIOS version: $($Script:BIOSPack.Version)"
  218. } Catch{
  219.     Write-LogEntry -Value "Failed to retrieve latest BIOS version"
  220.     Exit-Script -ExitCode 109
  221. }
  222.  
  223. #Compare Latest BIOS to System BIOS
  224. Write-LogEntry -Value " "
  225. Write-LogEntry -Value "Checking if BIOS update is required"
  226. $Script:UpgradeRequired=$False
  227. If ($Script:BIOSPack.PaddedVersion -gt $Script:BIOSPaddedVersion){
  228.     Write-LogEntry -Value "Latest BIOS, version $($Script:BIOSPack.Version) is greater than System BIOS, version $($Script:BIOSVersion)"
  229.     Write-Logentry -Value "BIOS update required"
  230.     $Script:UpgradeRequired=$True
  231. } elseif ($Script:BIOSPack.PaddedVersion -eq $Script:BIOSPaddedVersion) {
  232.     Write-LogEntry -Value "Latest BIOS, version $($Script:BIOSPack.Version) is the same as System BIOS, version $($Script:BIOSVersion)"
  233. } else {
  234.     Write-LogEntry -Value "Latest BIOS, version $($Script:BIOSPack.Version) is older than System BIOS, version $($Script:BIOSVersion)"
  235. }
  236.  
  237. If ($Script:UpgradeRequired -eq $True){
  238.     #Download BIOS Package
  239.     Write-LogEntry -Value " "
  240.     Write-LogEntry -Value "Downloading BIOS Package"
  241.     Try{
  242.         $Script:BIOSEXEName = Split-Path -Path $Script:BIOSPack.DownloadPath -Leaf
  243.         Invoke-WebRequest -Uri $Script:BIOSPack.DownloadPath -OutFile "$($TempFolder)\$($Script:BIOSEXEName)" -ErrorAction Stop
  244.         Write-LogEntry -Value "Successfully downloaded $($Script:BIOSPack.DownloadPath)"
  245.     }
  246.     Catch{
  247.         Write-LogEntry -Value "Failed to download $($Script:BIOSPack.DownloadPath)"
  248.         Exit-Script -ExitCode 110
  249.     }
  250.  
  251.     #Install BIOS Package
  252.     Write-LogEntry -Value " "
  253.     Write-LogEntry -Value "Installing BIOS Package"
  254.     Try {
  255.         $BIOS=Start-Process "$($TempFolder)\Flash64W.exe" -ArgumentList "/b=$($TempFolder)\$($Script:BIOSEXEName) /s" -Wait -PassThru
  256.         $Script:BIOSExitCode=$BIOS.ExitCode
  257.         Switch ($BIOSExitCode){
  258.             0{
  259.                 Write-LogEntry -Value "Successfully installed $($TempFolder)\$($Script:BIOSEXEName)"
  260.                 Exit-Script -ExitCode $BIOSExitCode
  261.                 break
  262.             }
  263.             2{
  264.                 Write-LogEntry -Value "Successfully installed $($TempFolder)\$($Script:BIOSEXEName) - Reboot Required"
  265.                 Exit-Script -ExitCode $BIOSExitCode
  266.                 break
  267.             }
  268.             3{
  269.                 Write-LogEntry -Value "Same version is already installed"
  270.                 Exit-Script -ExitCode $BIOSExitCode
  271.                 break
  272.             }
  273.             8{
  274.                 Write-LogEntry -Value "Newer version is already installed"
  275.                 Exit-Script -ExitCode $BIOSExitCode
  276.                 break
  277.             }
  278.             default {throw $BIOSExitCode}
  279.         }
  280.        
  281.     }
  282.     Catch {
  283.         Switch ($_){
  284.             10{
  285.                 Write-LogEntry -Value "Failed to install $($TempFolder)\$($Script:BIOSEXEName) because the battery level is too low"
  286.                 Exit-Script -ExitCode $BIOSExitCode
  287.                 break
  288.             }
  289.             default {
  290.                 Write-LogEntry -Value "Failed to install $($TempFolder)\$($Script:BIOSEXEName) with exit code $($_)"
  291.                 Exit-Script -ExitCode $BIOSExitCode
  292.             }
  293.         }
  294.        
  295.     }
  296.  
  297. } else {
  298.     Write-Logentry -Value "BIOS update not required"
  299.     Exit-Script -ExitCode 3
  300. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement