HP Driver Packs Download & CM Import via PowerShell

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.

Archive Directory:


Package Source Directory:

In the Console:

Email Notification:



<#  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
    Param (
            [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 {
    Param (
		    $Component = "HP BIOS Downloader",
    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 {
Param (
$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"
      "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'}
    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:"
            $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>&emsp;CM Package Version Currently: $PackageInfoVersion. Dell Online Version: $($DriverPack.Version)</font><br>"
            $AlreadyCurrent = $true
            {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>&emsp;Version set from $($PackageInfoVersion) to: $($DriverPack.Version) </font><br>"
            #$EmailArray += "<font color=#8B0000>&emsp;Language set to: $TargetKBID</font><br>"
            $EmailArray += "<font color=#8B0000>&emsp;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
        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.from = $username
$smtp = New-Object System.Net.Mail.SmtpClient($SMTPServer, $SMTPPort);
$smtp.EnableSSL = $true
$smtp.Credentials = New-Object System.Net.NetworkCredential($Username, $Password);
write-host "Mail Sent"

CMTraceLog -Message "Finished Script: $scriptName" -Type 1 -LogFile $LogFile
Write-Output "Finished Script: $scriptName"




9 thoughts on “HP Driver Packs Download & CM Import via PowerShell”

  1. 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

    • 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.

    • 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.

  2. 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.


Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.