Update: a few small mods to the Script after a conversation with Nathan from HP.
This script will Allow you to Check and Update your HP Drive Packs that you have CM Legacy Packages For. Email Notification When Complete, because you don’t want to sit around and wait for all this to happen. Also, not all of the code in the script is used, This script is a basic template I use for Both Drivers & BIOS for both Dell & HP. Feel free to clean it up.
In the script you Specify your Models, their Product ID, and the Package ID in CM
It then grabs the latest Driver Pack Info from HP, compares it to your Package and updates if needed.
Process: (For Each Model)
- Get SoftPaq Info for Latest Driver pack
- Get Package Versions
- If SoftPaq Version newer than Package Version, Download
- Downloads SoftPaq EXE to Archive Directory
- Extract SoftPaq to Local Temp Location
- Deletes Current Package Source
- Copies Updated Package Source Files to Package Source
- Creates XML file of Softpaq Info in Source Folder
- Updates CM Package Info
- Updates DPs
Directory Paths are all Variables, so change to fit your standards.
Script:
<# Creator @gwblok - GARYTOWN.COM Used to download Drivers Updates from HP This Script was created to build a Drivers Update Package. REQUIREMENTS: HP Client Management Script Library Download / Installer: https://ftp.hp.com/pub/caps-softpaq/cmit/hp-cmsl.html Docs: https://developers.hp.com/hp-client-management/doc/client-management-script-library This Script was created using version 1.2.1 Modes... Report - only compares HP against what you have in CM (No downloading) Download - compares HP to CM and Downloads and Updates CM #> [CmdletBinding()] Param ( [Parameter(Mandatory=$true,Position=1,HelpMessage="Application")] [ValidateNotNullOrEmpty()] [ValidateSet("Report", "Download", "DownloadOnly", "UpdateCMPackageOnly")] $RunMethod = "Report" ) #Settings for Google - Rest of Info @ Bottom $SMTPServer = "smtp.gmail.com" $SMTPPort = "587" $Username = "username@gmail.com" $Password = "password" #Script Vars $EmailArray = @() $scriptName = $MyInvocation.MyCommand.Name #Script Vars Environment Specific $FileServerName = "SRC" $OS = "Win10" $OSVER = "1809" $LogFile = "$PSScriptRoot\HPDriverPackDownload.log" $DownloadDir = "C:\HPContent\Downloads" $ExtractedDir = "C:\HPContent\Packages\HP" $SiteCode = "PS2" #Reset Vars $DriverPack = "" $Model = "" #region: CMTraceLog Function formats logging in CMTrace style function CMTraceLog { [CmdletBinding()] Param ( [Parameter(Mandatory=$false)] $Message, [Parameter(Mandatory=$false)] $ErrorMessage, [Parameter(Mandatory=$false)] $Component = "HP BIOS Downloader", [Parameter(Mandatory=$false)] [int]$Type, [Parameter(Mandatory=$true)] $LogFile ) <# Type: 1 = Normal, 2 = Warning (yellow), 3 = Error (red) #> $Time = Get-Date -Format "HH:mm:ss.ffffff" $Date = Get-Date -Format "MM-dd-yyyy" if ($ErrorMessage -ne $null) {$Type = 3} if ($Component -eq $null) {$Component = " "} if ($Type -eq $null) {$Type = 1} $LogMessage = "<![LOG[$Message $ErrorMessage" + "]LOG]!><time=`"$Time`" date=`"$Date`" component=`"$Component`" context=`"`" type=`"$Type`" thread=`"`" file=`"`">" $LogMessage | Out-File -Append -Encoding UTF8 -FilePath $LogFile } function Get-FolderSize { [CmdletBinding()] Param ( [Parameter(Mandatory=$true,ValueFromPipeline=$true)] $Path, [ValidateSet("KB","MB","GB")] $Units = "MB" ) if ( (Test-Path $Path) -and (Get-Item $Path).PSIsContainer ) { $Measure = Get-ChildItem $Path -Recurse -Force -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum $Sum = $Measure.Sum / "1$Units" [PSCustomObject]@{ "Path" = $Path "Size($Units)" = $Sum } } } $HPModelsTable= @( @{ ProdCode = '80FC'; Model = "Elite x2 1012 G1"; PackageID = "PS20009D"} @{ ProdCode = '82CA'; Model = "Elite x2 1012 G2"; PackageID = "PS20009E" } @{ ProdCode = '80FB'; Model = "EliteBook 1030 G1"; PackageID = "PS20009F" } @{ ProdCode = '80FA'; Model = "EliteBook 1040 G3"; PackageID = "PS2000A0" } @{ ProdCode = '225A'; Model = "EliteBook 820 G2"; PackageID = "PS2000A1" } @{ ProdCode = '807C'; Model = "EliteBook 820 G3"; PackageID = "PS2000A2" } @{ ProdCode = '2216'; Model = "EliteBook 840 G2"; PackageID = "PS2000A3" } @{ ProdCode = '8079'; Model = "EliteBook 840 G3"; PackageID = "PS2000A4" } @{ ProdCode = '827D'; Model = "EliteBook x360 1030 G2"; PackageID = "PS2000A5"} @{ ProdCode = '83D2'; Model = "ProBook 640 G4"; PackageID = "PS2000A6" } @{ ProdCode = '8062'; Model = "ProDesk 400 G3"; PackageID = "PS2000A7" } @{ ProdCode = '82A2'; Model = "ProDesk 400 G4"; PackageID = "PS2000A8" } @{ ProdCode = '83F2'; Model = "ProDesk 400 G5"; PackageID = "PS2000A9" } @{ ProdCode = '21D0'; Model = "ProDesk 600 G1"; PackageID = "PS2000AA" } @{ ProdCode = '8053'; Model = "ProDesk 600 G2"; PackageID = "PS2000AB" } @{ ProdCode = '829E'; Model = "ProDesk 600 G3"; PackageID = "PS2000AC" } @{ ProdCode = '83EF'; Model = "ProDesk 600 G4"; PackageID = "PS2000AD" } ) CMTraceLog -Message "Starting Script: $scriptName" -Type 1 -LogFile $LogFile Write-Output "Starting Script: $scriptName" Try {Test-Connection -ComputerName "$FileServerName" -Quiet $DownloadDriverPackRootArchive = "\\$($FileServerName)\src$\osd\Drivers\HPArchive" $DownloadDriverPackRootPackage = "\\$($FileServerName)\src$\osd\Drivers\HP" $DownloadToServer = $true Write-Output "Connected to Server $FileServerName" $EmailArray += "<font color=Black>Script was run in Mode: $($RunMethod)</font><br>" $EmailArray += "<font color=Black>Connecting to File Share Server: $($FileServerName)</font><br>" if (Test-Path 'C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin'){Import-Module 'C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1'} } Catch { Write-Output "Not Connected to File Server, Exiting" $DownloadToServer = $false } foreach ($HPModel in $HPModelsTable) { Write-Output "Checking Model $($HPModel.Model) Product Code $($HPModel.ProdCode) for Driver Pack Updates" $SoftPaq = Get-SoftpaqList -platform $HPModel.ProdCode -os $OS -osver $OSVER $DriverPack = $SoftPaq | Where-Object { $_.category -eq 'Manageability - Driver Pack'} $DriverPack = $DriverPack | Where-Object { $_.Name -notmatch "Windows PE"} $DriverPack = $DriverPack | Where-Object { $_.Name -notmatch "WinPE"} if ($DriverPack) { #$BIOS = Get-HPBiosUpdates -platform $HPModel.ProdCode -latest $DownloadDriverPackRootArchiveFullPath = "$($DownloadDriverPackRootArchive)\$($HPModel.Model)\$($DriverPack.Version)" $DownloadDriverPackRootPackageFullPath = "$($DownloadDriverPackRootPackage)\$($HPModel.Model)\Pilot" #Get Current Driver CMPackage Version from CM if ($DownloadToServer -eq $true) { Set-Location -Path "$($SiteCode):" $PackageInfo = Get-CMPackage -Id $HPModel.PackageID -Fast $PackageInfoVersion = $PackageInfo.Version Set-Location -Path "C:" } Else { $PackageInfoVersion = $null } if ($PackageInfoVersion -eq $DriverPack.Version) {Write-Output "$($HPModel.Model) already current with version $($PackageInfoVersion)" CMTraceLog -Message "CM Package $($PackageInfo.Name) already Current: $PackageInfoVersion HP: $($DriverPack.Version)" -Type 1 -LogFile $LogFile $EmailArray += "<font color=Green>CM Package <b>$($PackageInfo.Name)</b> Already Current</font><br>" $EmailArray += "<font color=Green> CM Package Version Currently: $PackageInfoVersion. Dell Online Version: $($DriverPack.Version)</font><br>" $AlreadyCurrent = $true } else {Write-Output "$($HPModel.Model) package is version $($PackageInfoVersion), new version available $($DriverPack.Version)" if (-not(Test-Path $DownloadDriverPackRootArchiveFullPath)) {new-Item -Path $DownloadDriverPackRootArchiveFullPath -ItemType Directory -Force } $SaveAs = "$($DownloadDriverPackRootArchiveFullPath)\$($DriverPack.id).exe" Get-Softpaq -number $DriverPack.id -saveAs $SaveAs -overwrite yes if (Test-Path $DownloadDriverPackRootPackageFullPath) {Remove-Item -Path $DownloadDriverPackRootPackageFullPath -Recurse -Force } New-Item $DownloadDriverPackRootPackageFullPath -ItemType Directory -Force #Copy-Item $SaveAs -Destination $DownloadDriverPackRootPackageFullPath -Force $TempDir = "$($env:temp)\SPExtract\$($HPModel.ProdCode)" if (Test-Path $TempDir) {Remove-Item -Path $TempDir -Recurse -Force -ErrorAction SilentlyContinue } New-Item $TempDir -ItemType Directory -Force Start-Process $SaveAs -ArgumentList "-pdf -e -s -f$($TempDir)" -Wait $CopyFromDir = (Get-ChildItem -Path ((Get-ChildItem -Path $TempDir -Directory).FullName) -Directory).FullName Copy-Item "$($CopyFromDir)\*" -Destination $DownloadDriverPackRootPackageFullPath -Force -Recurse Export-Clixml -InputObject $DriverPack -Path "$($DownloadDriverPackRootPackageFullPath)\DriverPackInfo.XML" if (Test-Path $TempDir) {Remove-Item -Path $TempDir -Recurse -Force -ErrorAction SilentlyContinue } $AlreadyCurrent = $false } if (($RunMethod -eq "Download" -and $AlreadyCurrent -ne $true) -or $RunMethod -eq "UpdateCMPackageOnly") { write-output "Updating Package Info in ConfigMgr $($PackageInfo.Name) ID: $($HPModel.PackageID)" Import-Module 'C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1' Set-Location -Path "$($SiteCode):" Set-CMPackage -Id $HPModel.PackageID -path "$($DownloadDriverPackRootPackageFullPath)" Set-CMPackage -Id $HPModel.PackageID -Version "$($DriverPack.Version)" Set-CMPackage -Id $HPModel.PackageID -Description "Version $($DriverPack.Version) Released $($DriverPack.ReleaseDate). Archive Folder = $($DownloadDriverPackRootArchiveFullPath)" Set-CMPackage -Id $HPModel.PackageID -Language $DriverPack.Id Set-CMPackage -ID $HPModel.PackageID -Manufacturer "HP" $PackageInfo = Get-CMPackage -Id $HPModel.PackageID -Fast $EmailArray += "<font color=#8B0000>Updated Package $($PackageInfo.Name), ID $($HPModel.PackageID) Information: </font><br>" $EmailArray += "<font color=#8B0000> Version set from $($PackageInfoVersion) to: $($DriverPack.Version) </font><br>" #$EmailArray += "<font color=#8B0000> Language set to: $TargetKBID</font><br>" $EmailArray += "<font color=#8B0000> Desciption set to: Version $($DriverPack.Version) Released $($DriverPack.ReleaseDate). Archive Folder = $($DownloadDriverPackRootArchiveFullPath) </font><br>" Update-CMDistributionPoint -PackageId $HPModel.PackageID Set-Location -Path "C:" CMTraceLog -Message "Updated Package $($PackageInfo.Name), ID $($HPModel.PackageID) to $($DriverPack.Version) which was released $($DriverPack.ReleaseDate)" -Type 1 -LogFile $LogFile } } else { Write-Output "No Driver Pack Available for $($HPModel.Model) Product Code $($HPModel.ProdCode) via Internet" $EmailArray += "<font color=#8B0000>No Driver Pack Available for<b> $($HPModel.Model) </b>Product Code $($HPModel.ProdCode) via Internet </font><br>" } } #Settings for Email #Customize this Part for your Subject & Body. Keep it short if you plan to use SMS texts. $to = "user@gmail.com" $subject = "HP Driver Pack Updates" $body = "$EmailArray" $message = New-Object System.Net.Mail.MailMessage $message.subject = $subject $message.body = $body $message.IsBodyHTML = $true $message.to.add($to) $message.from = $username $smtp = New-Object System.Net.Mail.SmtpClient($SMTPServer, $SMTPPort); $smtp.EnableSSL = $true $smtp.Credentials = New-Object System.Net.NetworkCredential($Username, $Password); $smtp.send($message) write-host "Mail Sent" CMTraceLog -Message "Finished Script: $scriptName" -Type 1 -LogFile $LogFile Write-Output "Finished Script: $scriptName"
GARYTOWN.COM
how do we know how to populate that table. Example – we have 640 G2 here. That isn’t listed there.
So I assume I make a shell package that is blank but has a directory source, and once I have that table properly populated I’d run it, and it would download and extract the drivers to that folder.
@{ ProdCode = ‘8053’; Model = “ProDesk 600 G2”; PackageID = “PS2000AB” }
@{ ProdCode = ‘829E’; Model = “ProDesk 600 G3”; PackageID = “PS2000AC” }
I have no idea how to populate the ProdCode
Get-CimInstance -ClassName Win32_BaseBoard
or (Get-CimInstance -ClassName Win32_BaseBoard).Product
I can’t remember which CMSL this was added, but you can now do the following to get the baseboards.
Get-HPDeviceDetails -match “640 G2”
Result of above is:
SystemID Name DriverPackSupport
——– —- —————–
80FD HP ProBook 640 G2 Notebook PC True
This match field can be set with whatever you like.
Hi, Gary Anything on Lenovo drivers?
Sorry, I don’t personally have any Lenovo Enterprise devices, so I don’t do any blogging on their products.
Gary how and from where do you run this script, I would like to implement. From Windows task scheduler or from inside sccm?
You have to run it on a machine that has the SCCM PowerSHell Module (One with the CM COnsole). Other than that, it has to run under an account that has rights in CM.
Hi Gary, as a pro OSDBuilder supporter yourself, what about the other tool OSDDrivers? Looks promising as there are no driver duplicates and the packs are really clean and compressed.
Depends on your environment. Doesn’t work for us, we need to tightly control the drivers for each model, regression testing and certifying each model. If we make a change, we don’t want it to impact other models, which is why we keep each of them separated.