HPDrivers.psm1
function ShowHPDriversStatus ([Parameter(Mandatory = $false)] [string]$Status) { <# .SYNOPSIS Displays the status of an object with its Id, Name, and Version. .DESCRIPTION The ShowHPDriversStatus function creates a custom object with properties Id, Name, Version, and Status. It then selects and displays these properties. .PARAMETER Status An optional string parameter that specifies the status of the object. If not provided, the default value is $null. .EXAMPLE ShowHPDriversStatus -Status "Installed" This command will display the status as "Active" along with the Id, Name, and Version of the object. #> $Info = New-Object -Type PSObject -Property @{ 'Id' = $Number 'Name' = $Name 'Version' = $AvailableSpVersion 'Status' = $Status } $Info | Select-Object -Property Id, Name, Version, Status } function WriteToHPDriversLog ([Parameter(Mandatory = $false)] [string]$Status) { <# .SYNOPSIS Collect HPDrivers module logs. .DESCRIPTION 'WriteToHPDriversLog' collects log files regarding installations and errors. This function will be called multiple times in the script below. #> $TimeStamp = (Get-Date).ToString("[yyy-MM-dd HH:mm:sss]") $LogMessage = $TimeStamp + ' - ' + $Number + ' - ' + $Status + ' - ' + $AvailableSpVersion + ' - ' + $Name $LogMessage | Out-File -FilePath "C:\Temp\HPDrivers\InstalledHPDrivers.log" -Append # Collect occurred errors foreach ($Entry in $Error) { $ErrorMessage = $TimeStamp + ' - ' + $Entry $ErrorMessage | Out-File -FilePath "C:\Temp\HPDrivers\HPDriversError.log" -Append } $Error.Clear() } function Get-HPDrivers { <# .SYNOPSIS Update all HP device drivers with a single command - Get-HPDrivers. .DESCRIPTION The HPDrivers module downloads and installs softpaqs that match the operating system version and hardware configuration. .PARAMETER NoPrompt Download and install all drivers. .PARAMETER OsVersion Specify the operating system version (e.g. 22H2, 23H2). .PARAMETER ShowSoftware Show additional HP software in the driver list. .PARAMETER Overwrite Install the drivers even if the current driver version is the same. .PARAMETER BIOS Update the BIOS to the latest version. .PARAMETER DeleteInstallationFiles Delete the HP SoftPaq installation files stored in C:\Temp\HPDrivers. .PARAMETER SuspendBL Suspend BitLocker protection for one restart. .LINK https://github.com/UsefulScripts01/HPDrivers .LINK https://www.powershellgallery.com/packages/HPDrivers .EXAMPLE Get-HPDrivers -NoPrompt Simple, just download and install all drivers. .EXAMPLE Get-HPDrivers -ShowSoftware -DeleteInstallationFiles -SuspendBL Show a list of available drivers and additional software. The selected drivers will be installed automatically. Do not keep installation files. Suspend the BitLocker pin on next reboot. .EXAMPLE Get-HPDrivers -NoPrompt -BIOS -Overwrite Download and install all drivers and BIOS, even if the current driver version is the same. .EXAMPLE Get-HPDrivers -OsVersion '22H2' Show a list of available drivers that match the current platform and Windows 22H2. The selected drivers will be installed automatically. #> [CmdletBinding()] param( [Parameter(Mandatory = $false)] [switch]$NoPrompt, [Parameter(Mandatory = $false)] [string]$OsVersion, [Parameter(Mandatory = $false)] [switch]$ShowSoftware, [Parameter(Mandatory = $false)] [switch]$Overwrite, [Parameter(Mandatory = $false)] [switch]$BIOS, [Parameter(Mandatory = $false)] [switch]$DeleteInstallationFiles, [Parameter(Mandatory = $false)] [switch]$SuspendBL ) $ProgressPreference = 'Continue' $Error.Clear() [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 # Classes and informations needed for further use # collect information about the current machine $ComputerSystem = Get-CimInstance -ClassName Win32_ComputerSystem $OperatingSystem = Get-CimInstance -ClassName Win32_OperatingSystem $BaseBoard = Get-CimInstance -ClassName Win32_BaseBoard if ($OperatingSystem.Caption -match "10") { $OsType = "10" } if ($OperatingSystem.Caption -match "11") { $OsType = "11" } $OsVer = (Get-Item "HKLM:SOFTWARE\Microsoft\Windows NT\CurrentVersion").GetValue('DisplayVersion') [Int32]$Year = $OsVer.Split('H')[0] [Int32]$Half = $OsVer.Split('H')[1] # if machine manufacturer is HP if (($ComputerSystem.Manufacturer -match "HP") -or ($ComputerSystem.Manufacturer -match "Hewlett-Packard")) { # test connectio with hpia.hpcloud.hp.com $TestConn = Test-Connection "hpia.hpcloud.hp.com" -Count 2 -ErrorAction Ignore if (!$TestConn) { Write-Output `n Write-Warning "hpia.hpcloud.hp.com is unavailable!`nPlease check your internet connection or try again later..`n" Break } # warn if battery charge drops below 50% $Charge = (Get-CimInstance -ClassName Win32_Battery).EstimatedChargeRemaining if ($Charge -le "50") { Write-Output `n Write-Warning "Battery level: ${Charge}%`nPLEASE CONNECT AN AC ADAPTER`n" } # create the path if (!(Test-Path -Path "C:\Temp\HPDrivers")) { New-Item -ItemType Directory -Path "C:\Temp\HPDrivers" -Force } Set-Location -Path "C:\Temp\HPDrivers" # Remove the old files Get-ChildItem -Path "C:\Temp\HPDrivers\*.xml" | Remove-Item Get-ChildItem -Path "C:\Temp\HPDrivers\*.cab" | Remove-Item # Download the CAB file containing the XML list of drivers that match your current machine if (!$OsVersion) { while (!(Test-Path -Path "C:\Temp\HPDrivers\HpDrivers.xml")) { try { $CabUri = ("https://hpia.hpcloud.hp.com/ref/$($BaseBoard.Product)/$($BaseBoard.Product)_64_${OsType}.0.${OsVer}.cab").ToLower() $WebClient = New-Object -TypeName System.Net.WebClient $WebClient.DownloadFile($CabUri, 'C:\Temp\HPDrivers\HP.cab') Invoke-Expression -Command "expand C:\Temp\HPDrivers\HP.cab C:\Temp\HPDrivers\HpDrivers.xml" | Out-Null [XML]$Script:XML = Get-Content -Path "C:\Temp\HPDrivers\HpDrivers.xml" Write-Output `n Write-Verbose "Latest drivers found: $($ComputerSystem.Model) - Windows $($OsVer.ToUpper()).." -Verbose } catch { # Try to set the previous version if ($Half.Equals(2)) { $Half = 1 } else { $Year -= 1 $Half = 2 } $OsVer = "$Year" + 'H' + "$Half" # Exit if the drivers version is older than 2020y if ($Year -lt 20) { Write-Warning "Could not find drivers that match your model ($($ComputerSystem.Model)) - Windows $($OsVer.ToUpper()).." Break } } } } # If the operating system version is defined in the parameter if ($OsVersion) { try { $CabUri = ("https://hpia.hpcloud.hp.com/ref/$($BaseBoard.Product)/$($BaseBoard.Product)_64_${OsType}.0.${OsVersion}.cab").ToLower() $WebClient = New-Object -TypeName System.Net.WebClient $WebClient.DownloadFile($CabUri, 'C:\Temp\HPDrivers\HP.cab') Invoke-Expression -Command "expand C:\Temp\HPDrivers\HP.cab C:\Temp\HPDrivers\HpDrivers.xml" | Out-Null [XML]$Script:XML = Get-Content -Path "C:\Temp\HPDrivers\HpDrivers.xml" Write-Output `n Write-Verbose "Latest drivers found: $($ComputerSystem.Model) - Windows $($OsVersion.ToUpper()).." -Verbose } catch { Write-Warning "Could not find drivers that match your model ($($ComputerSystem.Model)) - Windows $($OsVersion.ToUpper()).." Break } } # Remove the old files Get-ChildItem -Path "C:\Temp\HPDrivers\*.xml" | Remove-Item Get-ChildItem -Path "C:\Temp\HPDrivers\*.cab" | Remove-Item # Sort the driver list # 'Driverpack' = $Xml.ImagePal.Solutions.UpdateInfo | Where-Object { $_.Category -match 'Driverpack' } # 'UWPPack' = $Xml.ImagePal.Solutions.UpdateInfo | Where-Object { $_.Category -match 'UWPPack' } $Category = New-Object -Type PSObject @{ 'Driver' = $Xml.ImagePal.Solutions.UpdateInfo | Where-Object { $_.Category -match 'Driver -' } 'Diagnostic' = $Xml.ImagePal.Solutions.UpdateInfo | Where-Object { $_.Category -match 'Diagnostic' } 'Utility' = $Xml.ImagePal.Solutions.UpdateInfo | Where-Object { $_.Category -match 'Utility -' } 'Dock' = $Xml.ImagePal.Solutions.UpdateInfo | Where-Object { $_.Category -match 'Dock -' } 'Software' = $Xml.ImagePal.Solutions.UpdateInfo | Where-Object { $_.Category -match 'Software -' } 'Firmware' = $Xml.ImagePal.Solutions.UpdateInfo | Where-Object { $_.Category -match 'Firmware' } 'Manageability' = $Xml.ImagePal.Solutions.UpdateInfo | Where-Object { $_.Category -match 'Manageability -' } 'BIOS' = $Xml.ImagePal.Solutions.UpdateInfo | Where-Object { $_.Category -match 'BIOS' } } # Select driver category $AvailableDrivers = $Category.Driver # -ShowSoftware if ($ShowSoftware) { $AvailableDrivers += $Category.Diagnostic $AvailableDrivers += $Category.Utility $AvailableDrivers += $Category.Dock $AvailableDrivers += $Category.Software $AvailableDrivers += $Category.Firmware $AvailableDrivers += $Category.Manageability } # -Bios if ($BIOS) { $AvailableDrivers += $Category.BIOS } # Select drivers from the list of available drivers if (!$NoPrompt) { $SpList = $AvailableDrivers | Select-Object -Property id, Name, Category, Version, Size, DateReleased | Out-GridView -Title "Select driver(s):" -OutputMode Multiple } # Select all drivers without prompt # -NoPrompt if ($NoPrompt) { $SpList = $AvailableDrivers } # Insert a line to the log file $Date = Get-Date -Format "yyyy-MM-dd" $HR = "-" * 100 $Line = "[$Date]" + " " + $HR $Line | Out-File -FilePath "C:\Temp\HPDrivers\InstalledHPDrivers.log" -Append # Show list of available drivers if ($SpList) { Write-Verbose "The script will install the following drivers. Please wait..`n" -Verbose $SpList | Select-Object -Property Id, Name, Version, Size, DateReleased | Format-Table -AutoSize } if ($BadLinks) { Write-Warning "The following drivers are not available on the HP server `n" $BadLinks | Select-Object -Property Id, Name, Version, Size, DateReleased | Format-Table -AutoSize } # download and install selected drivers foreach ($Number in $SpList.id) { # Obtain information about the actual installed driver $Script:Name = ($Xml.ImagePal.Solutions.UpdateInfo | Where-Object { $_.Id -eq $Number }).Name $Script:Source = ($Xml.ImagePal.Solutions.UpdateInfo | Where-Object { $_.Id -eq $Number }).Url $Script:SilentInstall = ($Xml.ImagePal.Solutions.UpdateInfo | Where-Object { $_.Id -eq $Number }).SilentInstall $Script:AvailableSpVersion = ($Xml.ImagePal.Solutions.UpdateInfo | Where-Object { $_.Id -eq $Number }).Version # Get the version of the installed softpaq package $InstalledSpVersion = 0 if (!$Overwrite) { $CvaFile = Get-ChildItem -Path "C:\SWSetup\$Number" -Filter "*.cva" -Recurse -ErrorAction Ignore if ($CvaFile) { $CvaContent = Get-Content -Path $CvaFile.VersionInfo.FileName $InstalledSpVersion = ($CvaContent | Select-String -Pattern "^VendorVersion").ToString().Split('=')[1] } if (Test-Path -Path "C:\SWSetup\$Number\version.txt") { $InstalledSpVersion = Get-Content -Path "C:\SWSetup\$Number\version.txt" -ErrorAction SilentlyContinue } } # if a new driver version is available if ($AvailableSpVersion -gt $InstalledSpVersion) { try { # Download a softpaq (5 attempts) $Count = 1 while (!(Test-Path -Path "C:\Temp\HPDrivers\${Number}.exe") -and ($Count -le 5)) { Get-BitsTransfer | Remove-BitsTransfer Start-BitsTransfer -Source "https://${Source}" -Destination "C:\Temp\HPDrivers" -DisplayName "Downloading (attempt ${Count}/5):" -Description $Name -Dynamic -ErrorAction Ignore $Count += 1 } # Checksum $SPFileExist = Test-Path -Path "C:\Temp\HPDrivers\${Number}.exe" $SPFileChecksum = (Get-FileHash -Path "C:\Temp\HPDrivers\${Number}.exe" -Algorithm SHA256).Hash $OryginalChecksum = ($AvailableDrivers | Where-Object { $_.Id -eq $Number }).SHA256 # Checksum is OK if ($SPFileExist -or ($SPFileChecksum -eq $OryginalChecksum)) { # Installation process $SetupFile = $SilentInstall.Split()[0].Trim('"') $SetupCommand = $SilentInstall.Split()[0] $Param = $SilentInstall.Replace($SetupCommand, '') # Setup.exe files with a special params if ($Param) { Start-Process -FilePath "C:\Temp\HpDrivers\$Number" -Wait -ArgumentList "/s /e /f C:\SWSetup\$Number" Start-Process -FilePath "C:\SWSetup\$Number\$SetupFile" -Wait -ArgumentList $Param } # CMD Wrapper, HPUP and other installers if (!$Param) { Start-Process -FilePath "C:\Temp\HpDrivers\${Number}.exe" -Wait -ArgumentList "/s /f C:\SWSetup\$Number" } # Save file with installd version if (Test-Path -Path "C:\SWSetup\$Number") { $AvailableSpVersion | Out-File -FilePath "C:\SWSetup\$Number\version.txt" } ShowHPDriversStatus -Status "Installed" WriteToHPDriversLog -Status "Installed" Start-Sleep -Seconds 2 } else { ShowHPDriversStatus -Status "Failed!" WriteToHPDriversLog -Status "Failed!" } } catch { ShowHPDriversStatus -Status "Failed!" WriteToHPDriversLog -Status "Failed!" } # remove installation files if ($DeleteInstallationFiles -and (Test-Path -Path "C:\Temp\HPDrivers")) { Get-ChildItem -Path "C:\Temp\HPDrivers\${Number}.exe" | Remove-Item -Force } } # if the driver is up to date if ($AvailableSpVersion -le $InstalledSpVersion) { # Save file with installd version if (Test-Path -Path "C:\SWSetup\$Number") { $AvailableSpVersion | Out-File -FilePath "C:\SWSetup\$Number\version.txt" } ShowHPDriversStatus -Status "Already Installed" WriteToHPDriversLog -Status "Already Installed" } } # disable BitLocker pin for one restart (BIOS update) if ($SuspendBL -and ((Get-BitLockerVolume -MountPoint "C:").VolumeStatus -ne "FullyDecrypted")) { Suspend-BitLocker -MountPoint "C:" -RebootCount 1 } # remove installation files if ($DeleteInstallationFiles -and (Test-Path -Path "C:\Temp\HPDrivers")) { Get-ChildItem -Path "C:\Temp\HPDrivers" -Filter "*.exe" | Remove-Item -Force } } } Export-ModuleMember -Function Get-HPDrivers |