479 lines
17 KiB
PowerShell
479 lines
17 KiB
PowerShell
$CustomerId = "" # Log Analytics Workspace ID
|
|
$SharedKey = '' # Log Analytics Workspace Primary Key
|
|
$LogType = "DellBIOSUpdate" # Custom log to create in lo Analytics
|
|
$TimeStampField = "" # let to blank
|
|
#*******************************************************************************
|
|
|
|
# Log analytics functions
|
|
# More info there: https://docs.microsoft.com/en-us/azure/azure-monitor/logs/data-collector-api
|
|
Function Build-Signature ($customerId, $sharedKey, $date, $contentLength, $method, $contentType, $resource)
|
|
{
|
|
$xHeaders = "x-ms-date:" + $date
|
|
$stringToHash = $method + "`n" + $contentLength + "`n" + $contentType + "`n" + $xHeaders + "`n" + $resource
|
|
|
|
$bytesToHash = [Text.Encoding]::UTF8.GetBytes($stringToHash)
|
|
$keyBytes = [Convert]::FromBase64String($sharedKey)
|
|
|
|
$sha256 = New-Object System.Security.Cryptography.HMACSHA256
|
|
$sha256.Key = $keyBytes
|
|
$calculatedHash = $sha256.ComputeHash($bytesToHash)
|
|
$encodedHash = [Convert]::ToBase64String($calculatedHash)
|
|
$authorization = 'SharedKey {0}:{1}' -f $customerId,$encodedHash
|
|
return $authorization
|
|
}
|
|
|
|
# Create the function to create and post the request
|
|
# More info there: https://docs.microsoft.com/en-us/azure/azure-monitor/logs/data-collector-api
|
|
Function Post-LogAnalyticsData($customerId, $sharedKey, $body, $logType)
|
|
{
|
|
$method = "POST"
|
|
$contentType = "application/json"
|
|
$resource = "/api/logs"
|
|
$rfc1123date = [DateTime]::UtcNow.ToString("r")
|
|
$contentLength = $body.Length
|
|
$signature = Build-Signature `
|
|
-customerId $customerId `
|
|
-sharedKey $sharedKey `
|
|
-date $rfc1123date `
|
|
-contentLength $contentLength `
|
|
-method $method `
|
|
-contentType $contentType `
|
|
-resource $resource
|
|
$uri = "https://" + $customerId + ".ods.opinsights.azure.com" + $resource + "?api-version=2016-04-01"
|
|
|
|
$headers = @{
|
|
"Authorization" = $signature;
|
|
"Log-Type" = $logType;
|
|
"x-ms-date" = $rfc1123date;
|
|
"time-generated-field" = $TimeStampField;
|
|
}
|
|
|
|
$response = Invoke-WebRequest -Uri $uri -Method $method -ContentType $contentType -Headers $headers -Body $body -UseBasicParsing
|
|
return $response.StatusCode
|
|
}
|
|
|
|
|
|
$WMI_computersystem = gwmi win32_computersystem
|
|
$Manufacturer = $WMI_computersystem.manufacturer
|
|
If($Manufacturer -notlike "*dell*")
|
|
{
|
|
write-output "Poste non Dell"
|
|
EXIT 0
|
|
}
|
|
|
|
|
|
$ddlCategoryWeb =[xml]@'
|
|
<select id="ddl-category" class="w-100 form-control custom-select drivers-select">
|
|
<option value="BI"> BIOS </option>
|
|
</select>
|
|
'@
|
|
|
|
$Script:dictionaryCategory = @{}
|
|
$ddlCategoryWeb.select.option | Foreach {$Script:dictionaryCategory[$_.value] = $_.'#text'.Trim()}
|
|
|
|
$Script:ddlCategoryWeb =[xml]@'
|
|
<select id="operating-system" class="w-100 form-control custom-select drivers-select">
|
|
<option value="BIOSA">BIOS</option>
|
|
</select>
|
|
'@
|
|
|
|
|
|
Class Dell
|
|
{
|
|
|
|
|
|
Static hidden [String]$_vendorName = "Dell"
|
|
hidden [Object[]] $_deviceCatalog
|
|
hidden [Object[]] $_deviceImgCatalog
|
|
|
|
# Contructor
|
|
Dell()
|
|
{
|
|
$this._deviceCatalog = [Dell]::GetDevicesCatalog()
|
|
}
|
|
|
|
#####################################################################
|
|
# Get all Data from DELL (Gz format)
|
|
#####################################################################
|
|
# https://www.dell.com/support/components/eula/en-us/eula/api
|
|
|
|
Static hidden [Object[]]GetDevicesCatalog()
|
|
{
|
|
$result = Invoke-WebRequest -Uri "https://www.dell.com/support/home/en-us/api/catalog/autosuggest" -UseBasicParsing -Headers @{
|
|
"method"="GET"
|
|
"authority"="www.dell.com"
|
|
"scheme"="https"
|
|
"cache-control"="max-age=0"
|
|
"upgrade-insecure-requests"="1"
|
|
"accept"="text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
|
|
"sec-fetch-site"="none"
|
|
"sec-fetch-mode"="navigate"
|
|
"sec-fetch-user"="?1"
|
|
"sec-fetch-dest"="document"
|
|
"accept-encoding"="gzip, deflate, br"
|
|
"accept-language"="en-US,en;q=0.9"
|
|
}
|
|
|
|
$jsonObject = $($result.Content | ConvertFrom-Json) | Select-Object -Property "PN","PC"
|
|
return $jsonObject
|
|
|
|
}
|
|
|
|
#########################################################################
|
|
# Find Model Based on User input
|
|
#########################################################################
|
|
|
|
[Object[]]FindModel($userInputModel)
|
|
{
|
|
$SearchResultFormatted = @()
|
|
$userSearchResult = $this._deviceCatalog.Where({$_.PN -eq $userInputModel})
|
|
|
|
foreach($obj in $userSearchResult){
|
|
|
|
$SearchResultFormatted += [PSCustomObject]@{
|
|
Name=$obj.PN;
|
|
Guid=$obj.PC;
|
|
Path="/product/$($obj.PC)";
|
|
Image= $(
|
|
$obj = $this._deviceImgCatalog.Where({$_.Id -eq $obj.PC})
|
|
if($obj.Image){
|
|
"https:$($obj.Image)"
|
|
}else{
|
|
'https://i.dell.com/is/image/DellContent/content/dam/global-site-design/product_images/esupport/icons/esupport-blank-space-v2.png'
|
|
}
|
|
)
|
|
}
|
|
}
|
|
return $SearchResultFormatted
|
|
}
|
|
|
|
#########################################################################
|
|
# Get Json Data for a Dell Device form its GUID
|
|
#########################################################################
|
|
|
|
hidden [Object[]] GetModelWebResponse($modelGUID)
|
|
{
|
|
|
|
# ==== For Download =======
|
|
$modelGzURL = "https://downloads.dell.com/published/data/drivers/$($ModelGUID).gz"
|
|
$gzContent = Invoke-WebRequest -Uri $modelGzURL -UseBasicParsing -Headers @{
|
|
"method"="GET"
|
|
"authority"="www.dell.com"
|
|
"scheme"="https"
|
|
"cache-control"="max-age=0"
|
|
"upgrade-insecure-requests"="1"
|
|
"accept"="text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
|
|
"sec-fetch-site"="none"
|
|
"sec-fetch-mode"="navigate"
|
|
"sec-fetch-user"="?1"
|
|
"sec-fetch-dest"="document"
|
|
"accept-language"="en-US,en;q=0.9"
|
|
}
|
|
|
|
# === Convert Stream Data to viewable Content =====
|
|
$data = $gzContent.Content
|
|
|
|
$memoryStream = [System.IO.MemoryStream]::new()
|
|
$memoryStream.Write($data, 0, $data.Length)
|
|
$memoryStream.Seek(0,0) | Out-Null
|
|
|
|
$gZipStream = [System.IO.Compression.GZipStream]::new($memoryStream, [System.IO.Compression.CompressionMode]::Decompress)
|
|
$streamReader = [System.IO.StreamReader]::new($gZipStream)
|
|
$xmlModelInputRaw = $streamReader.readtoend()
|
|
|
|
# === Parse content =======================
|
|
$xmlModelInput = New-Object -TypeName System.Xml.XmlDocument
|
|
$xmlModelInput.LoadXml($xmlModelInputRaw)
|
|
|
|
return $xmlModelInput
|
|
}
|
|
#########################################################################
|
|
# Load All Drivers to exploitable format
|
|
#########################################################################
|
|
|
|
hidden [Object[]]LoadDriversFromWebResponse($webresponse)
|
|
{
|
|
$DownloadItemsObj = [Collections.ArrayList]@()
|
|
|
|
if($webresponse.Product.Drivers){
|
|
|
|
$DownloadItemsRaw = $webresponse.Product.Drivers.Driver | Sort-Object -Property Title
|
|
$DownloadItemsRawGrouped = $DownloadItemsRaw | Group-Object -Property Title
|
|
|
|
ForEach ($Itemgroup in $DownloadItemsRawGrouped){
|
|
$item = $Itemgroup.group | Sort-Object -Property LastUpdateDate | Select-Object -Last 1
|
|
|
|
[Array]$ExeFiles = $item.File
|
|
$current = [PSCustomObject]@{
|
|
Title =$item.Title;
|
|
Category=$Script:dictionaryCategory[$item.Category];
|
|
Class=$item.Type;
|
|
OperatingSystemKeys=$item.OS.Split(",");
|
|
|
|
Files= [Array]($ExeFiles | ForEach-Object {
|
|
if($_){
|
|
[PSCustomObject]@{
|
|
IsSelected=$false;
|
|
ID=$item.ID;
|
|
Name=$_.FileName.Split('/')[-1];
|
|
Size="$([Math]::Round($_.Size/1MB, 2)) MB";
|
|
Type=$item.Type;
|
|
Version=$item.VendorVersion
|
|
URL="https://dl.dell.com/$($_.FileName)";
|
|
Priority=$item.Importance ;
|
|
Date=$item.LastUpdateDate
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
$DownloadItemsObj.Add($current) | Out-Null
|
|
}
|
|
|
|
# ForEach ($Itemgroup in $DownloadItemsRawGrouped){
|
|
# $item = $null
|
|
# if($Itemgroup.Group.Count -ge 2){
|
|
# $maximum = 0
|
|
# foreach($vendorVer in $Itemgroup.Group){
|
|
|
|
# if($vendorVer.VendorVersion -gt $maximum){
|
|
# $maximum = $vendorVer.VendorVersion
|
|
# $item = $vendorVer
|
|
# }
|
|
# }
|
|
# }else{
|
|
# $item = $Itemgroup.Group
|
|
|
|
# }
|
|
|
|
# [Array]$ExeFiles = $item.File
|
|
# $current = [PSCustomObject]@{
|
|
# Title =$item.Title;
|
|
# Category=$Script:dictionaryCategory[$item.Category];
|
|
# Class=$item.Type;
|
|
# OperatingSystemKeys=$item.OS.Split(",");
|
|
|
|
# Files= [Array]($ExeFiles | ForEach-Object {
|
|
# if($_){
|
|
# [PSCustomObject]@{
|
|
# IsSelected=$false;
|
|
# ID=$item.ID;
|
|
# Name=$_.FileName.Split('/')[-1];
|
|
# Size="$([Math]::Round($_.Size/1MB, 2)) MB";
|
|
# Type=$item.Type;
|
|
# Version=$item.VendorVersion
|
|
# URL="https://dl.dell.com/$($_.FileName)";
|
|
# Priority=$item.Importance ;
|
|
# Date=$item.LastUpdateDate
|
|
# }
|
|
# }
|
|
# })
|
|
# }
|
|
|
|
# $DownloadItemsObj.Add($current) | Out-Null
|
|
# }
|
|
}
|
|
|
|
return $DownloadItemsObj
|
|
}
|
|
}
|
|
|
|
$SerialNumber = $((Get-WmiObject -Class Win32_BIOS).SerialNumber).Trim()
|
|
$CurrentOS = (gwmi Win32_OperatingSystem).Version
|
|
|
|
Try
|
|
{
|
|
$System_SKU = $((Get-WmiObject -Class Win32_ComputerSystem).SystemSKUNumber).Trim()
|
|
}
|
|
catch
|
|
{
|
|
Try
|
|
{
|
|
$System_SKU = $((Get-ItemProperty -Path HKLM:\HARDWARE\DESCRIPTION\System\BIOS).SystemSKU).Trim()
|
|
}
|
|
catch
|
|
{
|
|
$System_SKU = "Unknown"
|
|
}
|
|
}
|
|
|
|
|
|
|
|
$Current_User_Profile = Get-ChildItem Registry::\HKEY_USERS -ea silentlycontinue | Where-Object { Test-Path "$($_.pspath)\Volatile Environment" } | ForEach-Object { (Get-ItemProperty "$($_.pspath)\Volatile Environment").USERPROFILE }
|
|
$Username = $Current_User_Profile.split("\")[2]
|
|
|
|
$Chassis = (Get-CimInstance -ClassName Win32_SystemEnclosure).ChassisTypes
|
|
$Device_Chassis = [string]$chassis
|
|
If($Chassis -eq 9 -or $Chassis -eq 10 -or $Chassis -eq 14 -or $Chassis -eq 8 -or $Chassis -eq 11 -or $Chassis -eq 12 -or $Chassis -eq 18 -or $Chassis -eq 21 -or $Chassis -eq 31 -or $Chassis -eq 32)
|
|
{
|
|
$Chassis_Type = "Laptop"
|
|
}
|
|
else
|
|
{
|
|
$Chassis_Type = "Desktop"
|
|
}
|
|
|
|
$BIOS_Version = Get-ciminstance -class win32_bios
|
|
$Current_BIOS_Version = $BIOS_Version.SMBIOSBIOSVersion
|
|
$Current_BIOS_Version_ID = $Current_BIOS_Version.Split("(")[0]
|
|
|
|
$BIOS_release_date = (gwmi win32_bios | select *).ReleaseDate
|
|
$Format_BIOS_release_date = [DateTime]::new((([wmi]"").ConvertToDateTime($BIOS_release_date)).Ticks, 'Local').ToUniversalTime()
|
|
|
|
$Get_Current_Date = get-date
|
|
$Diff_CurrentBIOS_and_Today = $Get_Current_Date - $Format_BIOS_release_date
|
|
$Diff_Today_CurrentBIOS = $Diff_CurrentBIOS_and_Today.Days
|
|
|
|
$BIOS_Maj_Version = $BIOS_Version.SystemBiosMajorVersion
|
|
$BIOS_Min_Version = $BIOS_Version.SystemBiosMinorVersion
|
|
$Script:Get_Current_BIOS_Version = "$BIOS_Maj_Version.$BIOS_Min_Version"
|
|
$Get_Current_BIOS_Version = $Current_BIOS_Version
|
|
$Get_Current_BIOS_Version_Formated = [System.Version]$Current_BIOS_Version
|
|
|
|
|
|
$WMI_computersystem = gwmi win32_computersystem
|
|
$Get_Current_Model = (($WMI_computersystem).Model)
|
|
|
|
$BIOS_Ver_Model = "$Get_Current_BIOS_Version ($Get_Current_Model)"
|
|
|
|
# $Get_Current_Model = "Latitude E7270"
|
|
# $Get_Current_Model = "Latitude E5270"
|
|
# $Get_Current_Model = "XPS 13 9360"
|
|
# $Get_Current_Model = "Latitude 7390"
|
|
# $Get_Current_Model = "Latitude 5320"
|
|
# $Get_Current_Model = "Precision 5530"
|
|
# $Get_Current_Model = "Precision 5540"
|
|
|
|
|
|
$RunspaceScopeVendor = [Dell]::new()
|
|
$Search_Model = $RunspaceScopeVendor.FindModel("$Get_Current_Model")
|
|
If($Search_Model -ne $null)
|
|
{
|
|
$Get_GUID = $Search_Model.Guid
|
|
$wbrsp = $RunspaceScopeVendor.GetModelWebResponse("$Get_GUID")
|
|
$DriversModeldatas = $RunspaceScopeVendor.LoadDriversFromWebResponse($wbrsp)
|
|
$DriversModelDatasForOsType = [Array]($DriversModeldatas | Where-Object {($_.Title -like "*System BIOS*" )} )
|
|
$Get_BIOS_Update = $DriversModelDatasForOsType.files | Where {$_ -like "*EXE*"}
|
|
$Get_New_BIOS_Version = $Get_BIOS_Update.version
|
|
$Get_New_BIOS_Version_Formated = [System.Version]$Get_New_BIOS_Version
|
|
|
|
$Get_New_BIOS_Date = $Get_BIOS_Update.Date
|
|
$Get_New_BIOS_ID = $Get_BIOS_Update.ID
|
|
|
|
[int]$Get_New_BIOS_Date_Month = $Get_New_BIOS_Date.split("/")[0]
|
|
[int]$Get_New_BIOS_Date_Day = $Get_New_BIOS_Date.split("/")[1]
|
|
[int]$Get_New_BIOS_Date_Year = $Get_New_BIOS_Date.split("/")[2]
|
|
|
|
If($Get_New_BIOS_Date_month -lt 10)
|
|
{
|
|
$Get_Month = "0$Get_New_BIOS_Date_month"
|
|
}
|
|
Else
|
|
{
|
|
$Get_Month = "$Get_New_BIOS_Date_month"
|
|
}
|
|
|
|
If($Get_New_BIOS_Date_Day -lt 10)
|
|
{
|
|
$Get_Day = "0$Get_New_BIOS_Date_Day"
|
|
}
|
|
Else
|
|
{
|
|
$Get_Day = "$Get_New_BIOS_Date_Day"
|
|
}
|
|
|
|
$Get_New_BIOS_Date = "$Get_Month/$Get_Day/$Get_New_BIOS_Date_Year"
|
|
|
|
$Get_Converted_BIOS_Date = [Datetime]::ParseExact($Get_New_BIOS_Date, 'MM/dd/yyyy', $null)
|
|
# $Is_BIOS_NotUptoDate = ($Get_Current_BIOS_Version -lt $Get_New_BIOS_Version)
|
|
$Is_BIOS_NotUptoDate = ($Get_Current_BIOS_Version_Formated -lt $Get_New_BIOS_Version_Formated)
|
|
|
|
If($Is_BIOS_NotUptoDate -eq $null)
|
|
{
|
|
$Script:Script_Status = "Error"
|
|
$Script:BIOS_UpToDate = ""
|
|
$Script:BIOS_New_Version = $Get_New_BIOS_Version
|
|
$Script:BIOSDaysOld = 0
|
|
$Script:Exit_Status = 0
|
|
}
|
|
ElseIf($Is_BIOS_NotUptoDate -eq $True)
|
|
{
|
|
$BIOSDaysOld = ($Get_Converted_BIOS_Date - $Format_BIOS_release_date).Days
|
|
$Script:Script_Status = "Success"
|
|
$Script:BIOS_UpToDate = "No"
|
|
$Script:BIOS_New_Version = $Get_New_BIOS_Version
|
|
$Script:Exit_Status = 1
|
|
}
|
|
Else
|
|
{
|
|
$Script:Script_Status = "Success"
|
|
$Script:BIOS_UpToDate = "Yes"
|
|
$Script:BIOS_New_Version = $Get_New_BIOS_Version
|
|
$Script:Exit_Status = 0
|
|
}
|
|
|
|
If($BIOSDaysOld -ge 1 -and $BIOSDaysOld -lt 180)
|
|
{
|
|
$Diff_Delay = "1_180"
|
|
}
|
|
ElseIf($BIOSDaysOld -ge 180 -and $BIOSDaysOld -lt 365)
|
|
{
|
|
$Diff_Delay = "180_365"
|
|
}
|
|
ElseIf($BIOSDaysOld -ge 365 -and $BIOSDaysOld -lt 730)
|
|
{
|
|
$Diff_Delay = "365_730"
|
|
}
|
|
ElseIf($BIOSDaysOld -ge 730)
|
|
{
|
|
$Diff_Delay = "730_More"
|
|
}
|
|
}
|
|
|
|
|
|
# Creating the object to send to Log Analytics custom logs
|
|
$Properties = [Ordered] @{
|
|
"ScriptStatus" = $Script_Status
|
|
"BIOSUpToDate" = $BIOS_UpToDate
|
|
"ComputerName" = $env:computername
|
|
"UserName" = $username
|
|
"SerialNumber" = $SerialNumber
|
|
"CurrentOS" = $CurrentOS
|
|
"SystemSKU" = $System_SKU
|
|
"ModelFamilyName" = $Get_Current_Model
|
|
"BIOSCurrentVersion" = $Get_Current_BIOS_Version
|
|
"BIOSCurrentVersionFull" = $Current_BIOS_Version
|
|
"BIOSVersionModel" = $BIOS_Ver_Model
|
|
"CurrentBIOSDate" = $Format_BIOS_release_date
|
|
"BIOSNewVersion" = $BIOS_New_Version
|
|
"BIOSNewDate" = $Get_Converted_BIOS_Date
|
|
"GetNewBIOSID" = $Get_New_BIOS_ID
|
|
"NotUpdatedSince" = $BIOSDaysOld
|
|
"DateDiffDelay" = $Diff_Delay
|
|
"BIOSDaysOld" = $BIOSDaysOld
|
|
"DiffTodayCurrentBIOS" = $Diff_Today_CurrentBIOS
|
|
"ChassisDevice" = $Device_Chassis
|
|
"ChassisType" = $Chassis_Type
|
|
}
|
|
|
|
$BIOSUpdateResult = New-Object -TypeName "PSObject" -Property $Properties
|
|
# $BIOSUpdateResult
|
|
$BIOSUpdateResultJson = $BIOSUpdateResult | ConvertTo-Json
|
|
$params = @{
|
|
CustomerId = $customerId
|
|
SharedKey = $sharedKey
|
|
Body = ([System.Text.Encoding]::UTF8.GetBytes($BIOSUpdateResultJson))
|
|
LogType = $LogType
|
|
}
|
|
$LogResponse = Post-LogAnalyticsData @params
|
|
|
|
If($Exit_Status -eq 1)
|
|
{
|
|
EXIT 1
|
|
}
|
|
Else
|
|
{
|
|
EXIT 0
|
|
}
|
|
|