Skip to content

Commit 06f9282

Browse files
committed
d
1 parent fe7b626 commit 06f9282

7 files changed

Lines changed: 1603 additions & 0 deletions

File tree

Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
1+
<#
2+
.SYNOPSIS
3+
BIOS Control detection script for MSEndpointMgr Intune MBM
4+
.DESCRIPTION
5+
This proactive remediation script is part of the Intune version of Modern BIOS management. More information can be found at https://msendpointmgr.com
6+
NB: Only edit variables in the Declarations region of the script.
7+
The following variables MUST be set:
8+
1. DATUri - Url path to BIOSPackages.xml
9+
.EXAMPLE
10+
Invoke-IntuneBIOSUpdateDetect.ps1 - Run as SYSTEM
11+
.NOTES
12+
Version: 1.0
13+
Author: Maurice Daly / Jan Ketil Skanke @ Cloudway
14+
Contact: @JankeSkanke @Modaly_IT
15+
Creation Date: 01.10.2021
16+
Purpose/Change: Initial script development
17+
Created: 2021-14-11
18+
Updated:
19+
Version history:
20+
1.0.0 - (2021.14.11) Script created
21+
#>
22+
#Region Initialisations
23+
# Set Error Action to Silently Continue
24+
$Script:ErrorActionPreference = "SilentlyContinue"
25+
# Enable TLS 1.2
26+
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
27+
$Script:ExitCode = 0
28+
#Endregion Initialisations
29+
30+
#Region Decalarations
31+
# Create and define Eventlog for logging - edit with caution
32+
$Script:EventLogName = 'MSEndpointMgr'
33+
$Script:EventLogSource = 'MSEndpointMgrBIOSMgmt'
34+
New-EventLog -LogName $EventLogName -Source $EventLogSource -ErrorAction SilentlyContinue
35+
36+
# Define path to DAT provisioned XML
37+
$Script:DATUri = "<TO BE SET>"
38+
39+
# Get manufacturer
40+
$Script:Manufacturer = (Get-WmiObject -Class "Win32_ComputerSystem" | Select-Object -ExpandProperty Manufacturer).Trim()
41+
42+
# Registry path for status messages - Edit with caution
43+
$Script:RegPath = 'HKLM:\SOFTWARE\MSEndpointMgr\BIOSUpdateManagemement'
44+
45+
# Defining BIOSUpdate Status Variables - Do not edit
46+
$Script:BIOSUpdateInprogress = $null
47+
$Script:BIOSUpdateAttempts = $null
48+
$Script:BIOSUpdateTime = $null
49+
$Script:BIOSDeployedVersion = $null
50+
#EndRegion Declarations
51+
#Region Functions
52+
53+
function Test-BIOSVersionHP{
54+
param (
55+
[parameter(Mandatory = $true)]
56+
[ValidateNotNullOrEmpty()]
57+
[version]$BIOSApprovedVersion,
58+
[parameter(Mandatory = $true)]
59+
[ValidateNotNullOrEmpty()]
60+
[string]$SystemID
61+
)
62+
$Output = @{}
63+
# Import HP Module
64+
Import-Module HP.ClientManagement
65+
66+
# Obtain current BIOS verison
67+
[version]$CurrentBIOSVersion = Get-HPBIOSVersion
68+
69+
# Inform current BIOS deployment state
70+
if ($BIOSApprovedVersion -gt $CurrentBIOSVersion){
71+
$OutputMessage = "BIOS needs an update. Current version is $CurrentBIOSVersion, available version is $BIOSApprovedVersion"
72+
$ExitCode = 1
73+
}
74+
elseif ($BIOSApprovedVersion -eq $CurrentBIOSVersion) {
75+
$OutputMessage = "BIOS is current on version $CurrentBIOSVersion"
76+
$ExitCode = 0
77+
}
78+
elseif ($BIOSApprovedVersion -lt $CurrentBIOSVersion) {
79+
$OutputMessage = "BIOS is on a higher version than approved $CurrentBIOSVersion. Approved version $BIOSApprovedVersion"
80+
$ExitCode = 0
81+
}
82+
83+
$Output = @{
84+
"Message" = $OutputMessage
85+
"ExitCode" = $ExitCode
86+
}
87+
88+
Return $Output
89+
}#endfunction
90+
function Test-BiosVersionDell{
91+
param (
92+
[parameter(Mandatory = $true)]
93+
[ValidateNotNullOrEmpty()]
94+
[array]$BIOSPackageDetails
95+
)
96+
$OutputMessage = "Dell Not implemented"
97+
$ExitCode = 0
98+
$Output = @{
99+
"Message" = $OutputMessage
100+
"ExitCode" = $ExitCode
101+
}
102+
Return $Output
103+
}#endfunction
104+
function Test-BiosVersionLenovo{
105+
param (
106+
[parameter(Mandatory = $true)]
107+
[ValidateNotNullOrEmpty()]
108+
[array]$BIOSPackageDetails
109+
)
110+
$OutputMessage = "Dell Not implemented"
111+
$ExitCode = 0
112+
$Output = @{
113+
"Message" = $OutputMessage
114+
"ExitCode" = $ExitCode
115+
}
116+
Return $Output
117+
}#endfunction
118+
119+
#endregion Functions
120+
121+
#region Script
122+
# Read in DAT XML
123+
[xml]$BIOSPackages = Invoke-WebRequest -Uri $DATUri -UseBasicParsing
124+
125+
# Sort BIOS Packages into variable
126+
$BIOSPackageDetails = $BIOSPackages.ArrayOfCMPackage.CMPackage
127+
128+
# Validate applicability
129+
switch -Wildcard ($Manufacturer) {
130+
{($PSItem -match "HP") -or ($PSItem -match "Hewlett-Packard")}{
131+
Write-EventLog -LogName $EventLogName -EntryType Information -EventId 8001 -Source $EventLogSource -Message "Validated HP hardware check"
132+
$HPPreReq = [boolean](Get-InstalledModule | Where-Object {$_.Name -match "HPCMSL"} -ErrorAction SilentlyContinue -Verbose:$false)
133+
if ($HPPreReq){
134+
# Import module
135+
Import-Module HP.ClientManagement
136+
# Get matching identifier from baseboard
137+
$SystemID = Get-HPDeviceProductID
138+
$SupportedModel = $BIOSPackageDetails | Where-Object {$_.Description -match $SystemID}
139+
if (-not ([string]::IsNullOrEmpty($SupportedModel))) {
140+
[version]$BIOSApprovedVersion = ($BIOSPackageDetails | Where-Object {$_.Description -match $SystemID} | Sort-Object Version -Descending | Select-Object -First 1 -Unique -ExpandProperty Version).Split(" ")[0]
141+
$OEM = "HP"
142+
Write-EventLog -LogName $EventLogName -EntryType Information -EventId 8001 -Source $EventLogSource -Message "$($SupportedModel.Description) succesfully matched on SKU $($SystemID)"
143+
}
144+
else {
145+
Write-EventLog -LogName $EventLogName -EntryType Warning -EventId 8002 -Source $EventLogSource -Message "Model with SKU value $($SystemID) not found in XML source. Exiting script"
146+
Write-Output "Model with SKU value $($SystemID) not found in XML source. Exiting script"
147+
Exit 0
148+
}
149+
}
150+
else {
151+
# HP Prereq is missing. Exit script
152+
Write-EventLog -LogName $EventLogName -EntryType Warning -EventId 8002 -Source $EventLogSource -Message "HP CMSL Powershell Module is missing. Remediation not possible."
153+
Write-Output "HP Prereq missing. HPCMSL Powershell Module is missing. Remediation not possible."
154+
Exit 0
155+
}
156+
}
157+
{($PSItem -match "Lenovo")}{
158+
Write-EventLog -LogName $EventLogName -EntryType Information -EventId 8001 -Source $EventLogSource -Message "Validated Lenovo hardware check"
159+
$LenovoPreReq = $false
160+
if ($LenovoPreReq){
161+
# Get matching identifier from baseboard
162+
$SystemID = "Something"
163+
$SupportedModel = $BIOSPackageDetails | Where-Object {$_.Description -match $SystemID}
164+
if (-not ([string]::IsNullOrEmpty($SupportedModel))) {
165+
[version]$BIOSApprovedVersion = ($BIOSPackageDetails | Where-Object {$_.Description -match $SystemID} | Sort-Object Version -Descending | Select-Object -First 1 -Unique -ExpandProperty Version).Split(" ")[0]
166+
$OEM = "Lenovo"
167+
}
168+
else {
169+
Write-EventLog -LogName $EventLogName -EntryType Information -EventId 8001 -Source $EventLogSource -Message "Model $ComputerModel with SKU value $SystemSKU not found in XML source"
170+
}
171+
}
172+
else {
173+
Write-EventLog -LogName $EventLogName -EntryType Warning -EventId 8002 -Source $EventLogSource -Message "$($Manufacturer) not implemented"
174+
Write-output "$($Manufacturer) not implemented"
175+
Exit 0
176+
}
177+
}
178+
{($PSItem -match "Dell")}{
179+
Write-EventLog -LogName $EventLogName -EntryType Information -EventId 8001 -Source $EventLogSource -Message "Validated Dell hardware check"
180+
$DellPreReq = $false
181+
if ($DellPreReq){
182+
# Get matching identifier from baseboard
183+
$SystemID = "Something"
184+
$SupportedModel = $BIOSPackageDetails | Where-Object {$_.Description -match $SystemID}
185+
if (-not ([string]::IsNullOrEmpty($SupportedModel))) {
186+
[version]$BIOSApprovedVersion = ($BIOSPackageDetails | Where-Object {$_.Description -match $SystemID} | Sort-Object Version -Descending | Select-Object -First 1 -Unique -ExpandProperty Version).Split(" ")[0]
187+
$OEM = "Dell"
188+
}
189+
else {
190+
Write-EventLog -LogName $EventLogName -EntryType Warning -EventId 8002 -Source $EventLogSource -Message "Model with SKU value $($SystemID) not found in XML source. Exiting script"
191+
Write-Output "Model with SKU value $($SystemID) not found in XML source. Exiting script"
192+
Exit 0
193+
}
194+
}
195+
else {
196+
Write-EventLog -LogName $EventLogName -EntryType Warning -EventId 8002 -Source $EventLogSource -Message "$($Manufacturer) not implemented"
197+
Write-output "$($Manufacturer) not implemented"
198+
Exit 0
199+
}
200+
201+
}
202+
default {
203+
Write-EventLog -LogName $EventLogName -EntryType Information -EventId 8001 -Source $EventLogSource -Message "Incompatible Hardware. $($Manufacturer) not supported"
204+
Write-output "Incompatible Hardware. $($Manufacturer) not supported"
205+
Exit 0
206+
}
207+
}
208+
209+
# Checking if registry entries for BIOS Update management exits and set to 0 if they don't exists
210+
if (-NOT(Test-Path -Path "$RegPath\")) {
211+
New-Item -Path "$RegPath" -Force | Out-Null
212+
New-ItemProperty -Path "$RegPath" -Name 'BIOSUpdateInprogress' -Value 0 -PropertyType 'DWORD' -Force | Out-Null
213+
New-ItemProperty -Path "$RegPath" -Name 'BIOSUpdateAttempts' -Value 0 -PropertyType 'DWORD' -Force | Out-Null
214+
New-ItemProperty -Path "$RegPath" -Name 'BIOSUpdateTime' -Value "" -PropertyType 'String' -Force | Out-Null
215+
New-ItemProperty -Path "$RegPath" -Name 'BIOSDeployedVersion' -Value "" -PropertyType 'String' -Force | Out-Null
216+
}
217+
218+
# Check if BIOS Update is in Progress
219+
$BiosUpdateinProgress = Get-ItemPropertyValue -Path "$($RegPath)\" -Name BIOSUpdateInprogress
220+
if ($BiosUpdateinProgress -ne 0){
221+
Write-EventLog -LogName $EventLogName -EntryType Information -EventId 8001 -Source $EventLogSource -Message "BIOS Update is in Progress"
222+
# Check if computer has restarted since last try
223+
[DateTime]$BIOSUpdateTime = Get-ItemPropertyValue -Path "$RegPath" -Name 'BIOSUpdateTime'
224+
$LastBootime = Get-Date (Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object -ExpandProperty LastBootUpTime)
225+
if ($BIOSUpdateTime -gt $LastBootime){
226+
# Computer not restarted - Invoke remediation to notify user to reboot
227+
Write-EventLog -LogName $EventLogName -EntryType Information -EventId 8001 -Source $EventLogSource -Message "BIOSUpdateTime is newer than last reboot, pending first reboot"
228+
Exit 1
229+
}
230+
else {
231+
# Step 4 Computer restarted - Check BIOS Version
232+
Write-EventLog -LogName $EventLogName -EntryType Information -EventId 8001 -Source $EventLogSource -Message "Computer has restarted - validate bios version"
233+
$TestBiosCommand = "Test-BIOSVersion$($OEM) -BIOSApprovedVersion $($BIOSApprovedVersion) -SystemID $($SystemID)"
234+
$BIOSCheck = Invoke-Expression $TestBiosCommand
235+
236+
if ($BIOSCheck.ExitCode -eq 0){
237+
Write-EventLog -LogName $EventLogName -EntryType Information -EventId 8001 -Source $EventLogSource -Message "Update Complete - Clean up in registry"
238+
Set-ItemProperty -Path "$RegPath" -Name 'BIOSUpdateInprogress' -Value 0
239+
Set-ItemProperty -Path "$RegPath" -Name 'BIOSUpdateAttempts' -Value 0
240+
Set-ItemProperty -Path "$RegPath" -Name 'BIOSUpdateTime' -Value ""
241+
Set-ItemProperty -Path "$RegPath" -Name 'BIOSDeployedVersion' -Value ""
242+
Write-EventLog -LogName $EventLogName -EntryType Information -EventId 8001 -Source $EventLogSource -Message "$($BIOSCheck.Message)"
243+
Write-Output "$($BIOSCheck.Message)"
244+
Exit 0
245+
}
246+
else {
247+
#Step 5 Computer restarted - BIOS not updated - Invoke remediation if threshold not met
248+
[int]$Attempts = Get-ItemPropertyValue -Path $RegPath -Name 'BIOSUpdateAttempts'
249+
if ($Attempts -gt 3){
250+
Write-EventLog -LogName $EventLogName -EntryType Warning -EventId 8002 -Source $EventLogSource -Message "Update not completed after reboot - giving up after $($Attempts) attempts"
251+
Write-Output "Update not completed after reboot - giving up after $($Attempts) attempts"
252+
Exit 0
253+
} else {
254+
Set-ItemProperty -Path $RegPath -Name 'BIOSUpdateAttempts' -Value $Attempts
255+
Write-EventLog -LogName $EventLogName -EntryType Information -EventId 8001 -Source $EventLogSource -Message "Update not completed after reboot - Attempts: $($Attempts) - Call remediation script"
256+
Write-Output "$($BIOSCheck.Message)"
257+
#$Attempts++
258+
Exit 1
259+
}
260+
}
261+
}
262+
} else {
263+
# Step 6 BIOS Update not in progress - Check BIOS Version
264+
Write-EventLog -LogName $EventLogName -EntryType Information -EventId 8001 -Source $EventLogSource -Message "Validate bios version"
265+
$TestBiosCommand = "Test-BIOSVersion$($OEM) -BIOSApprovedVersion $($BIOSApprovedVersion) -SystemID $($SystemID)"
266+
$BIOSCheck = Invoke-Expression $TestBiosCommand
267+
268+
if ($BIOSCheck.ExitCode -eq 1){
269+
Write-EventLog -LogName $EventLogName -EntryType Information -EventId 8001 -Source $EventLogSource -Message "$($BIOSCheck.Message)"
270+
Write-Output "$($BIOSCheck.Message)"
271+
Exit 1
272+
}
273+
else {
274+
Write-EventLog -LogName $EventLogName -EntryType Information -EventId 8001 -Source $EventLogSource -Message "$($BIOSCheck.Message)"
275+
Write-Output "$($BIOSCheck.Message)"
276+
Exit 0
277+
}
278+
}
279+
280+
#endregion script
281+
282+
283+
284+
285+
286+
287+
288+
289+
290+
291+
292+

0 commit comments

Comments
 (0)