This is my initial script, still working on the part that will update the Application in CM, but for now, I am going to post this. If you use HP hardware, you NEED to learn these tools.
https://developers.hp.com/hp-client-management/doc/client-management-script-library
What the script does, downloads the XML information from HP, looks up the latest version of the Tools, then downloads and installs. You can set it to Download to Server Location or Local via Param.
Changes you should change…
- Update Proxy Info (or remove)
- Server Location for Download
Parameters: RunMethod & Install
- RunMethod = Local or Server
- Local downloads the EXE to local temp folder
- Server downloads to Server Path
- Install = True or False
- True = It installs on the machine you’re running script
- False = Downloads only
Here is how it looks in the Programs & Features.. note the version does NOT match the XML version. I was told by HP I could drop the last .X from the version safely, making the version 1.2.1
Code:
#This will download the latest version of the HP Script Library, Install it and confirm it's installed. [CmdletBinding()] Param ( #Download to Server Share or Local Temp (Probably Local temp if you're going to install) [Parameter(Mandatory=$true,Position=1,HelpMessage="Run Method")] [ValidateNotNullOrEmpty()] [ValidateSet("Local", "Server")] $RunMethod = "Local", #Install will Install, otherwise it will download only [Parameter(Mandatory=$true,Position=1,HelpMessage="Install App")] [ValidateNotNullOrEmpty()] [ValidateSet($true, $false)] $Install = $false ) #Borrowed from internet... this was the only way I was able to "query" if it was installed. Function Get-Software { [OutputType('System.Software.Inventory')] [Cmdletbinding()] Param( [Parameter(ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)] [String[]]$Computername=$env:COMPUTERNAME ) Begin { } Process { ForEach ($Computer in $Computername){ If (Test-Connection -ComputerName $Computer -Count 1 -Quiet) { $Paths = @("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall","SOFTWARE\\Wow6432node\\Microsoft\\Windows\\CurrentVersion\\Uninstall") ForEach($Path in $Paths) { Write-Verbose "Checking Path: $Path" # Create an instance of the Registry Object and open the HKLM base key Try { $reg=[microsoft.win32.registrykey]::OpenRemoteBaseKey('LocalMachine',$Computer,'Registry64') } Catch { Write-Error $_ Continue } # Drill down into the Uninstall key using the OpenSubKey Method Try { $regkey=$reg.OpenSubKey($Path) # Retrieve an array of string that contain all the subkey names $subkeys=$regkey.GetSubKeyNames() # Open each Subkey and use GetValue Method to return the required values for each ForEach ($key in $subkeys){ Write-Verbose "Key: $Key" $thisKey=$Path+"\\"+$key Try { $thisSubKey=$reg.OpenSubKey($thisKey) # Prevent Objects with empty DisplayName $DisplayName = $thisSubKey.getValue("DisplayName") If ($DisplayName -AND $DisplayName -notmatch '^Update for|rollup|^Security Update|^Service Pack|^HotFix') { $Date = $thisSubKey.GetValue('InstallDate') If ($Date) { Try { $Date = [datetime]::ParseExact($Date, 'yyyyMMdd', $Null) } Catch{ Write-Warning "$($Computer): $_ <$($Date)>" $Date = $Null } } # Create New Object with empty Properties $Publisher = Try { $thisSubKey.GetValue('Publisher').Trim() } Catch { $thisSubKey.GetValue('Publisher') } $Version = Try { #Some weirdness with trailing [char]0 on some strings $thisSubKey.GetValue('DisplayVersion').TrimEnd(([char[]](32,0))) } Catch { $thisSubKey.GetValue('DisplayVersion') } $UninstallString = Try { $thisSubKey.GetValue('UninstallString').Trim() } Catch { $thisSubKey.GetValue('UninstallString') } $InstallLocation = Try { $thisSubKey.GetValue('InstallLocation').Trim() } Catch { $thisSubKey.GetValue('InstallLocation') } $InstallSource = Try { $thisSubKey.GetValue('InstallSource').Trim() } Catch { $thisSubKey.GetValue('InstallSource') } $HelpLink = Try { $thisSubKey.GetValue('HelpLink').Trim() } Catch { $thisSubKey.GetValue('HelpLink') } $Object = [pscustomobject]@{ Computername = $Computer DisplayName = $DisplayName Version = $Version InstallDate = $Date Publisher = $Publisher UninstallString = $UninstallString InstallLocation = $InstallLocation InstallSource = $InstallSource HelpLink = $thisSubKey.GetValue('HelpLink') EstimatedSizeMB = [decimal]([math]::Round(($thisSubKey.GetValue('EstimatedSize')*1024)/1MB,2)) } $Object.pstypenames.insert(0,'System.Software.Inventory') Write-Output $Object } } Catch { Write-Warning "$Key : $_" } } } Catch {} $reg.Close() } } Else { Write-Error "$($Computer): unable to reach remote system!" } } } } #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 Script Library Installer", [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 } $URL = "https://ftp.hp.com/pub/caps-softpaq/cmit/release/cmsl/hp-cmsl-latest.exe" $XMLURL = "ftp://ftp.hp.com/pub/caps-softpaq/cmit/release/cmsl/hpcmsl.xml" $XMLPath = "$PSScriptRoot\hpcmsl.xml" $LogFile = "$($env:Temp)\HPScriptLibInstaller.log" $HPScriptLibVer = $null $scriptName = $MyInvocation.MyCommand.Name #Set Download location based on Param (Local or Server) if ($RunMethod -eq "Server"){$DownloadPath = "\\src\src$\Apps\HP\HPScriptLibrary"} if ($RunMethod -eq "Local"){$DownloadPath = $env:TEMP} # Future Code for when I have it update the Application in CM #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'} #$SiteCode = "PS2" CMTraceLog -Message "----- Started Script: $scriptName -----" -Type 1 -LogFile $LogFile # Download HP XML if ((Test-NetConnection proxy-garytown.com -Port 8080).PingSucceeded -eq $True) { $UseProxy = $true CMTraceLog -Message "Found Proxy Server, using for Downloads" -Type 1 -LogFile $LogFile Write-Output "Found Proxy Server, using for Downloads" $ProxyServer = "http://proxy-garytown.com:8080" $BitsProxyList = @("192.168.1.176:8080, 168.33.22.169:8080, 111.222.214.218.21:8080") } Else { $ProxyServer = $null CMTraceLog -Message "No Proxy Server Found, continuing without" -Type 1 -LogFile $LogFile Write-Output "No Proxy Server Found, continuing without" } If(Test-Path $XMLPath){Remove-Item -Path $XMLPath -Force -Verbose} Invoke-WebRequest -Uri $XMLURL -OutFile $XMLPath -UseBasicParsing -Verbose -Proxy $ProxyServer [int32]$n=1 While(!(Test-Path $XMLPath) -and $n -lt '3') { Invoke-WebRequest -Uri $XMLURL -OutFile $XMLPath -UseBasicParsing -Verbose -Proxy $ProxyServer $n++ } [xml]$XML = Get-Content $XMLPath -Verbose $Packages = $XML.'hp-update-catalog'.product.package $LatestVersion = ($Packages | Measure-Object -Property "Version" -Maximum).Maximum $LatestPackage = $Packages | Where-Object -FilterScript {$PSitem.Version -eq $LatestVersion} $LatestFileName = $LatestPackage.url.Split('/')[-1] $LatestFileDownloadPath = "$($DownloadPath)\$($LatestVersion)\$($LatestFileName)" #Check if already installed.. and if current if ($Install -eq $true) { $Software = Get-Software $HPScriptLib = $Software | Where-Object -FilterScript {$_.DisplayName -eq "HP Client Management Script Library"} if ($HPScriptLib -ne $null){$HPScriptLibVer = $HPScriptLib.version.substring(0,5)} if ($HPScriptLibVer -eq $LatestVersion) { Write-Output "Already Current running version $($HPScriptLibVer)" CMTraceLog -Message "Already Current running version $($HPScriptLibVer)" -Type 1 -LogFile $LogFile $AlreadyCurrent = $true } else { Write-Output "Does not have the Current Version $($LatestVersion) Installed" CMTraceLog -Message "Does not have the Current Version $($LatestVersion) Installed" -Type 1 -LogFile $LogFile $AlreadyCurrent = $false } } #Check if Donwloaded already, if not.. download it if (($Install -eq $true -and $AlreadyCurrent -ne $true) -or $Install -eq $false) { if (Test-Path $LatestFileDownloadPath) { Write-Output "Already have Latest Version Downloaded" CMTraceLog -Message "Already have Latest Version Downloaded" -Type 1 -LogFile $LogFile } else { New-Item -Path "$($DownloadPath)\$($LatestVersion)" -ItemType Directory -Force CMTraceLog -Message "Downloading ver $($LatestVersion) to $($DownloadPath)" -Type 1 -LogFile $LogFile Write-Output "Downloading ver $($LatestVersion) to $($DownloadPath)" Invoke-WebRequest -Uri $LatestPackage.url -OutFile $LatestFileDownloadPath -UseBasicParsing -Verbose -Proxy $ProxyServer [int32]$n=1 While(!(Test-Path $LatestFileDownloadPath) -and $n -lt '3') { Invoke-WebRequest -Uri $LatestPackage.url -OutFile $LatestFileDownloadPath -UseBasicParsing -Verbose -Proxy $ProxyServer $n++ } } } #Install the Software if ($Install -eq $true -and $AlreadyCurrent -ne $true) { CMTraceLog -Message "Triggering Installer: $($LatestFileName) $($LatestPackage.silentuninstall)" -Type 1 -LogFile $LogFile Write-Output "Triggering Installer: $($LatestFileName) $($LatestPackage.silentuninstall)" Start-Process $LatestFileDownloadPath -ArgumentList "$($LatestPackage.silentinstall)" -Wait $Software = Get-Software $HPScriptLib = $Software | Where-Object -FilterScript {$_.DisplayName -eq "HP Client Management Script Library"} $HPScriptLibVer = $HPScriptLib.version.substring(0,5) if ($HPScriptLibVer -eq $LatestVersion) { Write-Output "Installation Successful" CMTraceLog -Message "Installation Successful" -Type 1 -LogFile $LogFile } Else { Write-Output "Installation FAILED" CMTraceLog -Message "Installation FAILED" -Type 1 -LogFile $LogFile } } #Uninstall Command: Start-Process -FilePath $($HPScriptLib.UninstallString) -ArgumentList $($LatestPackage.silentuninstall) -wait <#Future work on updating the AppModel App in CM. $AppModelVersion = $LatestVersion $AppModelSilentInstall = "$LatestFileName $($LatestPackage.silentinstall)" $AppModelSilentUninstall = "$($HPScriptLib.UninstallString) $($LatestPackage.silentuninstall)" $AppModelDetectionMethod = "" #Still working on. #> CMTraceLog -Message "----- Finished Script: $scriptName -----" -Type 1 -LogFile $LogFile
GARYTOWN.COM
Hi Gary,
Thank you for sharing this wonderful script to automate driver downloading and extraction process. I was wondering if you had a chance to test the downloading process for "20H2". It appears that Get-SoftpaqList -osver Parameter does not accept the string value and hence it fails. Could you please advice ?
Did you try 2009?