HP.Softpaq.psm1
# Copyright (C)2018 HP Inc # All Rights Reserved. # # NOTICE: All information contained herein is, and remains the property of HP Inc. # # The intellectual and technical concepts contained herein are proprietary to HP Inc # and may be covered by U.S. and Foreign Patents, patents in process, and are protected by # trade secret or copyright law. Dissemination of this information or reproduction of this material # is strictly forbidden unless prior written permission is obtained from HP Inc. Set-StrictMode -Version 3.0 #requires -Modules "HP.Private","HP.Firmware" <# .SYNOPSIS Retrieve softpaq metadata (CVA) can retrieve a CVA or an alternate server. .DESCRIPTION Get a softpaq metadata file (CVA) from the location specified by the URL parameter. If URL is not specified, the Softpaq metadata is downloaded can retrieve a CVA via HTTPS. .PARAMETER Number The softpaq number for which to retrieve the metadata. Do not include prefix such as SP or extension such as .exe, specify the softpaq number only. .PARAMETER Url specify an alternate location for the softpaq URL. This URL must be http, https, or ftp. The softpaq CVAs are expected to be at the location pointed to by this URL. If not specified, ftp.hp.com is used via HTTPS protocol. .EXAMPLE Get-SoftpaqMetadata 1234 | Out-SoftpaqField -field Title .LINK [Get-Softpaq](Get-Softpaq) .LINK [Get-SoftpaqMetadataFile](Get-SoftpaqMetadataFile) .LINK [Get-SoftpaqList](Get-SoftpaqList) .LINK [Out-SoftpaqField](Out-SoftpaqField) .LINK [Clear-SoftpaqCache](Clear-SoftpaqCache) #> function Get-SoftpaqMetadata { [CmdletBinding(HelpUri = "https://developers.hp.com/hp-client-management/doc/Get%E2%80%90SoftpaqMetadata")] param( [ValidatePattern('^([Ss][Pp])*([0-9]{3,9})((\.[Ee][Xx][Ee]|\.[Cc][Vv][Aa])*)$')] [Parameter(Position = 0,Mandatory = $true)] [string]$Number, [Parameter(Position = 1,Mandatory = $false)] [string]$Url, [Parameter(Position = 2,Mandatory = $false)] [int]$MaxRetries = 0 ) $no = [int]$number.ToLower().TrimStart("sp").trimend(".exe").trimend('cva') [System.Net.ServicePointManager]::SecurityProtocol = Get-HPPrivateAllowedHttpsProtocols $loc = Get-HPPrivateItemUrl $no "cva" $url Get-HPPrivateReadINI -file $loc -Verbose:$VerbosePreference -maxRetries $maxRetries } <# .SYNOPSIS Retrieve softpaq (EXE) can retrieve a CVA or an alternate server. .DESCRIPTION This function downloads a softpaq from a the default download server (ftp.hp.com) or an alternate server. When using the default location, the download is performed over HTTPS, otherwise the protocol is dictated by the URL parameter. Get-Softpaq functionality is not supported in WinPE. .PARAMETER Number The softpaq number for which to retrieve the metadata. Do not include prefix such as SP or extension such as .exe, specify the softpaq number only. .PARAMETER SaveAs Provide a specific name for the saved softpaq, otherwise it is inferred based on the remote name or the softpaq metadata if -FriendlyName is specified. .PARAMETER FriendlyName Create a friendly name for the downloaded softpaq, based on the softpaq number and title. .PARAMETER Quiet Suppress non-errors such as download progress and other messages. .PARAMETER Overwrite This parameter controls the overwrite behavior. Options may be "no" to not overwrite existing files, "yes" to force overwrite, and "skip" to skip existing files without an error. Default is 'no' if overwrite is not specified. .PARAMETER Action Perform a specific action after download. The action may be "install" or "silentinstall". Silentinstall information is retrieved from the softpaq metadata (CVA) file. .PARAMETER Extract Extracts files from a specified zipped archive file to a specified destination folder. Note: By default, files are extracted into a new sub-folder relative to the downloaded softpaq executable. .PARAMETER DestinationPath Specifies the path to the folder in which you want to save extracted files. Enter the path to a folder, but do not specify a file name or file name extension. Note: By default, the files are extracted into a new sub-folder relative to the downloaded executable. .PARAMETER Url specify an alternate location for the softpaq URL. This URL must be http, https, or ftp. The softpaqs are expected to be at the location pointed to by this URL. If not specified, ftp.hp.com is used via HTTPS protocol. .PARAMETER KeepInvalidSigned this function performs an Authenticode signature check after a download, and deletes any downloaded file with invalid or missing signature. Use this flag to keep the file that failed the signature. .EXAMPLE Get-Softpaq 1234 .EXAMPLE Get-Softpaq 1234 -Extract -DestinationPath "c:\staging\drivers" .LINK [Get-SoftpaqMetadata](Get-SoftpaqMetadata) .LINK [Get-SoftpaqMetadataFile](Get-SoftpaqMetadataFile) .LINK [Get-SoftpaqList](Get-SoftpaqList) .LINK [Out-SoftpaqField](Out-SoftpaqField) .LINK [Clear-SoftpaqCache](Clear-SoftpaqCache) #> function Get-Softpaq { [CmdletBinding(HelpUri = "https://developers.hp.com/hp-client-management/doc/Get%E2%80%90Softpaq", DefaultParameterSetName = "DownloadParams")] param( [Parameter(ParameterSetName = "DownloadParams")] [Parameter(Position = 0, Mandatory = $true)] [string]$Number, [Parameter(ParameterSetName = "DownloadParams")] [Parameter(Position = 1, Mandatory = $false)] [string]$SaveAs, [Parameter(ParameterSetName = "DownloadParams")] [Parameter(Position = 2, Mandatory = $false)] [switch]$FriendlyName, [Parameter(ParameterSetName = "DownloadParams")] [Parameter(Position = 3, Mandatory = $false)] [switch]$Quiet, [Parameter(ParameterSetName = "DownloadParams")] [ValidateSet("no", "yes", "skip")] [Parameter(Position = 4, Mandatory = $false)] [string]$Overwrite = "no", [parameter(Position = 5, Mandatory = $false, ParameterSetName = "DownloadParams")] [parameter(Position = 5, Mandatory = $false, ParameterSetName = "InstallParams")] [ValidateSet("install", "silentinstall")] [string]$Action, [Parameter(ParameterSetName = "DownloadParams")] [Parameter(Position = 6, Mandatory = $false)] [string]$Url, [Parameter(ParameterSetName = "DownloadParams")] [Parameter(Position = 7, Mandatory = $false)] [switch]$KeepInvalidSigned, [Parameter(ParameterSetName = "DownloadParams")] [Parameter(Position = 8, Mandatory = $false)] [int]$MaxRetries = 0, [parameter(Mandatory = $false, ParameterSetName = "DownloadParams")] [parameter(Mandatory = $false, ParameterSetName = "ExtractParams")] [switch]$Extract, [parameter(Mandatory = $false, ParameterSetName = "DownloadParams")] [parameter(Mandatory = $false, ParameterSetName = "ExtractParams")] [ValidatePattern('^[a-zA-Z]:\\')] [String]$DestinationPath ) if((Test-WinPE) -and ($action)){ Throw "Softpaq installation is not supported in WinPE" } [System.Net.ServicePointManager]::SecurityProtocol = Get-HPPrivateAllowedHttpsProtocols $no = [int]$number.ToLower().TrimStart("sp").trimend(".exe") if ($keepInvalidSigned.IsPresent) { $keepInvalid = $true } else { $keepInvalid = $false } if ($quiet.IsPresent) { $progress = -not $quiet } else { $progress = $true } $loc = Get-HPPrivateItemUrl -number $no -ext "exe" -url $url $target = $null $root = $null if ($friendlyName.IsPresent -or $action) { # get softpaq metadata try { $root = Get-SoftpaqMetadata $no -url $url -maxRetries $maxRetries} catch { if ($progress -eq $true) { Write-Host -ForegroundColor Magenta "(Warning) Could not retrieve CVA file metadata for sp$no." Write-Host -ForegroundColor Magenta $_.Exception.Message } } } # build the filename if (!$saveAs) { if ($friendlyName.IsPresent) { Write-Verbose "Need to get CVA data to determine Friendly Name for Softpaq file" $target = getfriendlyFileName -number $no -info $root -Verbose:$VerbosePreference $target = "$target.exe" } else { $target = "sp$no.exe" } } else { $target = $saveAs } $targetFile = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($target) try { Invoke-HPPrivateDownloadFile -url $loc -target $targetFile -progress $progress -NoClobber $overwrite -Verbose:$VerbosePreference -maxRetries $maxRetries } catch { Write-Host -ForegroundColor Magenta "(Warning) Could not retrieve $loc." Write-Host -ForegroundColor Magenta $_.Exception.Message throw $_.Exception } # check digital signatures $signed = Get-HPPrivateCheckSignature -file $targetFile -Verbose:$VerbosePreference if ($signed -eq $false) { switch ($keepInvalid) { $true { if ($progress -eq $true) { Write-Host -ForegroundColor Magenta "(Warning): File $targetFile has invalid or missing signature" return } } $false { Invoke-HPPrivateSafeRemove -path $targetFile -Verbose:$VerbosePreference throw [System.BadImageFormatException] "File $targetFile has invalid or missing signature and will be deleted." return } } } else { if ($progress -eq $true) { Write-Verbose "Digital signature is valid." } } # perform requested action if ($action -ne $null) { $PostInstallAction = if ($Extract.IsPresent) {"extract"} else {$action} postDownloadSoftpaqAction -downloadedFile $targetFile -Action $PostInstallAction -number $number -info $root -Destination $DestinationPath } } <# .SYNOPSIS Retrieve softpaq metadata (CVA) can retrieve a CVA or an alternate server. .DESCRIPTION Use this command to download a softpaq from a specified location. By default, the softpaq is retrieved from HP.COM via HTTPS. .PARAMETER Number The softpaq number for which to retrieve the metadata. Do not include prefix such as SP or extension such as .exe. .PARAMETER SaveAs Provide a specific name for the saved softpaq metadata, otherwise it is inferred based on the remote name or the metadata if -friendlyName is specified. .PARAMETER FriendlyName Create a friendly name for the downloaded softpaq, based on the softpaq number and title. .PARAMETER Quiet Suppress non-errors such as download progress and other messages. .PARAMETER Overwrite This parameter controls the overwrite behavior. Options may be "no" to not overwrite existing files, "yes" to force overwrite, and "skip" to skip existing files without an error. Default is 'no' if overwrite is not specified. .PARAMETER url An alternate URL where to look for the softpaq .EXAMPLE Get-SoftpaqMetadataFile 1234 .LINK [Get-SoftpaqMetadata](Get-SoftpaqMetadata) .LINK [Get-Softpaq](Get-Softpaq) .LINK [Get-SoftpaqList](Get-SoftpaqList) .LINK [Out-SoftpaqField](Out-SoftpaqField) .LINK [Clear-SoftpaqCache](Clear-SoftpaqCache) #> function Get-SoftpaqMetadataFile { [CmdletBinding(HelpUri = "https://developers.hp.com/hp-client-management/doc/Get%E2%80%90SoftpaqMetadataFile")] param( [ValidatePattern('^([Ss][Pp])*([0-9]{3,9})((\.[Ee][Xx][Ee]|\.[Cc][Vv][Aa])*)$')] [Parameter(Position = 0,Mandatory = $true)] [string]$Number, [Parameter(Position = 1,Mandatory = $false)] [string]$SaveAs, [Parameter(Position = 2,Mandatory = $false)] [switch]$FriendlyName, [Parameter(Position = 3,Mandatory = $false)] [switch]$Quiet, [ValidateSet("No","Yes","Skip")] [Parameter(Position = 4,Mandatory = $false)] [string]$Overwrite = "No", [Parameter(Position = 5,Mandatory = $false)] [string]$Url, [Parameter(Position = 6,Mandatory = $false)] [int]$MaxRetries = 0 ) [System.Net.ServicePointManager]::SecurityProtocol = Get-HPPrivateAllowedHttpsProtocols $no = [int]$number.ToLower().TrimStart("sp").trimend(".exe").trimend('cva') if ($quiet.IsPresent) { $progress = -not $quiet } else { $progress = $true } $loc = Get-HPPrivateItemUrl -number $no -ext "cva" -url $url $target = $null # get softpaq metadata. We don't need this step unless we get friendly name if ($friendlyName.IsPresent) { Write-Verbose "Need to get CVA data to determine Friendly Name for CVA file" try { $root = Get-SoftpaqMetadata $number -url $url -maxRetries $maxRetries } catch { if ($progress -eq $true) { Write-Host -ForegroundColor Magenta "(Warning) Could not retrieve CVA file metadata" Write-Host -ForegroundColor Magenta $_.Exception.Message } $root = $null } } # build the filename if (!$saveAs) { if ($friendlyName.IsPresent) { Write-Verbose "Need to get CVA data to determine Friendly Name for CVA file" $target = getfriendlyFileName -number $no -info $root -Verbose:$VerbosePreference $target = "$target.cva" } else { $target = "sp$no.cva" } } else { $target = $saveAs } # download the file $targetFile = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($target) Invoke-HPPrivateDownloadFile -url $loc -target $targetFile -progress $progress -NoClobber $overwrite -Verbose:$VerbosePreference -maxRetries $maxRetries -skipSignatureCheck } <# .SYNOPSIS Filter a loaded softpaq metadata .DESCRIPTION Extract the specified field from the softpaq metadata. Some of the currently supported fields are: * Title * Description * SilentInstall * Number * Platforms * PlatformIDs * Version .PARAMETER Field The predefined filter to retrieve .EXAMPLE $mysoftpaq | Out-SoftpaqField -Field Title .LINK [Get-SoftpaqMetadata](Get-SoftpaqMetadata) .LINK [Get-Softpaq](Get-Softpaq) .LINK [Get-SoftpaqList](Get-SoftpaqList) .LINK [Get-Softpaq](Get-Softpaq) .LINK [Clear-SoftpaqCache](Clear-SoftpaqCache) #> function Out-SoftpaqField { [CmdletBinding(HelpUri = "https://developers.hp.com/hp-client-management/doc/Out%E2%80%90SoftpaqField")] param( [ValidateSet("Install","SilentInstall","Title","Description","Number","Platforms","PlatformIDs","SoftPaqSHA256","SoftPaqMD5","Version")] [Parameter(Mandatory = $True)] [string]$Field, [ValidateNotNullOrEmpty()] [Parameter(Mandatory = $False)] [string]$Language = "en", [ValidateNotNullOrEmpty()] [Parameter(ValueFromPipeline = $True,Mandatory = $True)] [Alias('In')] $InputObject ) begin { if (!$mapper.contains($field)) { throw [InvalidOperationException] "Field '$field' is not supported as a filter" } } process { $result = descendNodesAndGet $InputObject -field $field if ($mapper[$field] -match "%KeyValues\(.*\)$") { $pattern = $mapper[$field] -match "\((.*)\)" if ($pattern[0]) { return $result[$result.keys -match $matches[1]].TrimStart("0x") | Get-Unique } } return $result.TrimStart("0x") } end {} } <# .SYNOPSIS Clear the softpaq cache. .DESCRIPTION Clear the cache used for downloading softpaq database files. This is normally not needed as part of normal operation, the cache doesn't grow significantly over time, and is also cleared by norma operations that flush the user's temporary directory. The function is only intended as a debugging function. .EXAMPLE Clear-SoftpaqCache .PARAMETER cacheDir Custom location for caching data files. If not specified, the user-specific TEMP directory is used. .LINK [Get-SoftpaqMetadata](Get-SoftpaqMetadata) .LINK [Get-Softpaq](Get-Softpaq) .LINK [Get-SoftpaqList](Get-SoftpaqList) .LINK [Get-Softpaq](Get-Softpaq) .LINK [Out-SoftpaqField](Out-SoftpaqField) .NOTES This command removes the cached files from the user temporary directory. It cannot be used to clear the cache when the data files are stored inside a repository structure. Custom cache locations (other than the default) must be specified via the cacheDir folder. #> function Clear-SoftpaqCache { [CmdletBinding(HelpUri = "https://developers.hp.com/hp-client-management/doc/Clear%E2%80%90SoftpaqCache")] param( [Parameter(Mandatory = $false)] [System.IO.DirectoryInfo]$CacheDir ) $cacheDir = Get-HPPrivateCacheDirPath ($cacheDir) Invoke-HPPrivateSafeRemove -path $cacheDir -Recurse } <# .SYNOPSIS Get a list of softpaqs for a platform .DESCRIPTION This function gets a list of latest softpaqs for a specified platform ID, or the current computer. Get-SoftpaqList functionality is not supported in WinPE. .PARAMETER Platform The platform ID for which to retrieve the list of softpaqs. If not available, the current platform ID is used. .PARAMETER Bitness the platform bitness (32 or 64). If not available, the current platform bitness is used. .PARAMETER Os filter for the specified OS. The OS may be one of win7, win8, win8.1, win10. If not specified, current platform OS is used. .PARAMETER OsVer filter for the specified OS Version. Applies to Win10 only. This is a numeric value, usually the third part of a Windows 10 version (e.g. 10.0.xxxx) .PARAMETER Category The category field filters to a specific category of Softpaqs. It must be one (or more) of "bios", "firmware", "driver", "software", "os", "manageability", "diagnostic", "utility", "driverpack", "dock". .PARAMETER ReleaseType filter to specified release type. The release type must be one (or more) of "critical", "recommended", "routine". .PARAMETER Url specify an alternate location for the softpaq URL. This URL must be http, https, or ftp. The softpaqs are expected to be at the location pointed to by this URL. If not specified, ftp.hp.com is used via HTTPS protocol. .PARAMETER Quiet Suppress non-error progress messages .PARAMETER Download download matching softpaqs .PARAMETER DownloadMetadata also download CVA files (metadata) for matching softpaqs .PARAMETER DownloadNotes also download note files (human readable info files) for matching softpaqs .PARAMETER DownloadDirectory specify a directory for the downloaded files .PARAMETER Friendlyname if specified, retrieve the softpaq metadata and create a friendly file name based on the softpaq title. Applies if -download is specified. .PARAMETER Overwrite This parameter controls the overwrite behavior. Options may be "no" to not overwrite existing files, "yes" to force overwrite, and "skip" to skip existing files without an error. Default is 'no' if overwrite is not specified. .PARAMETER Format Display results in a specified format (json, xml, or csv). If not specified, results are returned as powershell objects .PARAMETER Characteristic Specify additional filter characteristics for the softpaq list. The characteristic must be one (or more) of "ssm", "dpb". .PARAMETER CacheDir Custom location for caching data files. If not specified, the user-specific TEMP directory is used. .PARAMETER MaxRetries Maximum number of retries allowed to obtain an exclusive lock to downloaded files. This is relevant only when files are downloaded into a shared directory and multiple processes may be reading or writing from the same location. Current default value is 10 retries, and each retry includes a 30 second pause, which means the maximum time the default value will wait for an exclusive logs is 300 seconds or 5 minutes. .EXAMPLE Get-SoftpaqList -Download .EXAMPLE Get-SoftpaqList -Bitness 64 -Os win10 -OsVer 1903 .EXAMPLE Get-SoftpaqList -Platform 8444 -Category Diagnostic -Format json .EXAMPLE Get-SoftpaqList -Category Driverpack .EXAMPLE Get-SoftpaqList -ReleaseType critical -characteristic SSM .EXAMPLE Get-SoftpaqList -Platform 83b2 -Category Dock,Firmware -ReleaseType Routine,Critical .LINK [Get-SoftpaqMetadata](Get-SoftpaqMetadata) .LINK [Get-Softpaq](Get-Softpaq) .LINK [Clear-SoftpaqCache](Clear-SoftpaqCache) .LINK [Get-Softpaq](Get-Softpaq) .LINK [Out-SoftpaqField](Out-SoftpaqField) .NOTES The response is a record set composed of zero or more softpaq records. The definition of a record is as follows: | Field | Description | |---------------|-------------| | Id | The softpaq identifier | | Name | The softpaq name (title) | | Category | The softpaq category | | Version | The softpaq version | | Vendor | The author of the softpaq | | ReleaseType | The softpaq release type (TODO) | | SSM | This flag indicates this softpaq support unattended silent install | | DPB | This flag indicates this softpaq is included in driver pack builds | | Url | The softpaq download URL | | ReleaseNotes | The URL to a human-readable rendering of the softpaq release notes | | Metadata | The URL to the softpaq metadata (CVA) file | | MD5 | (where available) The MD5 value for this softpaq | | Size | The softpaq size, in bytes | | ReleaseDate | The date the softpaq was published | #> function Get-SoftpaqList { [CmdletBinding(HelpUri = "https://developers.hp.com/hp-client-management/doc/Get%E2%80%90SoftpaqList", DefaultParameterSetName = "ViewParams")] param( [ValidatePattern("^[a-fA-F0-9]{4}$")] [Parameter(ParameterSetName = "DownloadParams")] [Parameter(Position = 0,Mandatory = $false,ParameterSetName = "ViewParams")] [string]$Platform, [ValidateSet(32,64)] [Parameter(ParameterSetName = "DownloadParams")] [Parameter(Position = 1,Mandatory = $false,ParameterSetName = "ViewParams")] [int]$Bitness, [ValidateSet($null,"win7","win8","win8.1","win81","win10")] [Parameter(ParameterSetName = "DownloadParams")] [Parameter(Position = 2,Mandatory = $false,ParameterSetName = "ViewParams")] [string]$Os, [ValidateRange(1507,3007)] [Parameter(ParameterSetName = "DownloadParams")] [Parameter(Position = 3,Mandatory = $false,ParameterSetName = "ViewParams")] [int]$OsVer, [Parameter(ParameterSetName = "DownloadParams")] [Parameter(Position = 4,Mandatory = $false,ParameterSetName = "ViewParams")] [string]$Url = "https://ftp.hp.com/pub/caps-softpaq/cmit/imagepal/ref", [Parameter(ParameterSetName = "DownloadParams")] [Parameter(Position = 5,Mandatory = $false,ParameterSetName = "ViewParams")] [switch]$Quiet, [Parameter(ParameterSetName = "DownloadParams")] [ValidateSet("XML","Json","CSV")] [Parameter(Position = 6, ParameterSetName = "ViewParams")] [string]$Format, [Parameter(Position = 7, ParameterSetName = "DownloadParams")] [string]$DownloadDirectory, [Alias("downloadSoftpaq", "downloadPackage")] [Parameter(Position = 8, ParameterSetName = "DownloadParams")] [switch]$Download, [Alias("downloadCva")] [Parameter(Position = 9, ParameterSetName = "DownloadParams")] [switch]$DownloadMetadata, [Parameter(Position = 10, ParameterSetName = "DownloadParams")] [switch]$DownloadNotes, [Parameter(Position = 11, ParameterSetName = "DownloadParams")] [switch]$FriendlyName, [ValidateSet("No","Yes","Skip")] [Parameter(ParameterSetName = "DownloadParams")] [Parameter(Position = 12,Mandatory = $false,ParameterSetName = "ViewParams")] [string]$Overwrite = "no", [ValidateSet("BIOS","Firmware","Driver","Software","OS","Manageability","Diagnostic","Utility","Driverpack","Dock")] [Parameter(ParameterSetName = "DownloadParams")] [Parameter(Position = 13,ParameterSetName = "ViewParams")] [string[]] $Category = $null, [ValidateSet("Critical","Recommended","Routine")] [Parameter(ParameterSetName = "DownloadParams")] [Parameter(Position = 14,ParameterSetName = "ViewParams")] [string[]] $ReleaseType = $null, [ValidateSet("SSM","DPB")] [Parameter(ParameterSetName = "DownloadParams")] [Parameter(Position = 15,ParameterSetName = "ViewParams")] [string[]] $Characteristic = $null, [Parameter(ParameterSetName = "DownloadParams")] [Parameter(Position = 16,ParameterSetName = "ViewParams")] [System.IO.DirectoryInfo]$CacheDir, [Parameter(ParameterSetName = "DownloadParams")] [Parameter(Position = 17,Mandatory=$false,ParameterSetName = "ViewParams")] [int]$MaxRetries = 0 ) if(Test-WinPE){ Throw "Softpaq List generation is not supported in WinPE" } [System.Net.ServicePointManager]::SecurityProtocol = Get-HPPrivateAllowedHttpsProtocols $ver = "" $progress = $true $cacheDir = Get-HPPrivateCacheDirPath ($cacheDir) if ($quiet.IsPresent) { $progress = -not $quiet } if (-not $platform) { $platform = Get-HPDeviceProductID } $platform = $platform.ToLower() if (!$bitness) { if ([environment]::Is64BitOperatingSystem -eq $true) { $bitness = 64 } else { $bitness = 32 } } if (!$os) { switch ([string][System.Environment]::OSVersion.Version.Major + "." + [string][System.Environment]::OSVersion.Version.Minor) { "10.0" { $os = "win10" } "6.3" { $os = "win81" } "6.2" { $os = "win8" } "6.1" { $os = "win7" } } } if (([System.Environment]::OSVersion.Version.Major -eq 10) -and (!$osver)) { $osver = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' -Name ReleaseID | Select-Object ReleaseID).ReleaseId } switch ($os) { "win10" { $ver = "10.0." + $osver.ToString() } "win81" { $ver = "6.3" } "win8.1" { $ver = "6.3" } "win8" { $ver = "6.2" } "win7" { $ver = "6.1" } default { throw [NotSupportedException] "Unsupported operating system: " + $_ } } $fn = "$($platform)_$($bitness)_$($ver)" $qurl = "$url/$platform/$fn.cab" $qfile = Get-HPPrivateTemporaryFileName -filename "$fn.cab" -cacheDir $cacheDir $downloadedFile = "$qfile.dir\$fn.xml" $result = $null try { $result = Test-HPPrivateIsDownloadNeeded -url $qurl -file $qfile -Verbose:$VerbosePreference } catch { if (-not $quiet) { Write-Host -ForegroundColor Magenta $_.Exception.Message } throw [System.Net.WebException] "Could not find a data file for this platform." } if ($result[1] -eq $true) { Write-Verbose "Cleaning cached data and downloading the data file." Invoke-HPPrivateDeleteCachedItem -cab $qfile Invoke-HPPrivateDownloadFile -url $qurl -target $qfile -progress $progress -NoClobber $overwrite -Verbose:$VerbosePreference -maxRetries $maxRetries (Get-Item $qfile).CreationTime = ($result[0]) (Get-Item $qfile).LastWriteTime = ($result[0]) } # Need to make sure that the expanded data file exists and is not corrupted. # Otherwise, expand the cab file. if (-not (Test-Path $downloadedFile) -or (-not (Test-HPPrivateIsValidXmlFile -file $downloadedFile))) { Write-Verbose "Extracting the data file, looking for $downloadedFile." $file = Invoke-HPPrivateExpandCAB -cab $qfile -expectedFile $downloadedFile } Write-Verbose "Reading XML document $downloadedFile" [xml]$data = Get-Content $downloadedFile Write-Verbose "Parsing the document" $d = Select-Xml -Xml $data -XPath "//ImagePal/Solutions/UpdateInfo" $results = $d | ForEach-Object { if (($releaseType -eq $null) -or ($_.Node.releaseType -in $releaseType)) { if (matchCategory -cat $_.Node.category -allowed $category -EQ $true) { if (($characteristic -eq $null) -or (matchAnyCharacteristic $characteristic -SSM $_.Node.SSMCompliant -DPB $_.Node.DPBCompliant)) { $pso = New-Object PSObject $pso | Add-Member NoteProperty -Name "Id" -Value $_.Node.id -Passthru $pso | Add-Member NoteProperty -Name "Name" -Value $_.Node.Name -Passthru $pso | Add-Member NoteProperty -Name "Category" -Value $_.Node.category -Passthru $pso | Add-Member NoteProperty -Name "Version" -Value $_.Node.Version.TrimStart("0") -Passthru $pso | Add-Member NoteProperty -Name "Vendor" -Value $_.Node.Vendor -Passthru $pso | Add-Member NoteProperty -Name "ReleaseType" -Value $_.Node.releaseType -Passthru $pso | Add-Member NoteProperty -Name "SSM" -Value $_.Node.SSMCompliant -Passthru $pso | Add-Member NoteProperty -Name "DPB" -Value $_.Node.DPBCompliant -Passthru $pso | Add-Member NoteProperty -Name "Url" -Value $_.Node.Url -Passthru $pso | Add-Member NoteProperty -Name "ReleaseNotes" -Value $_.Node.ReleaseNotesUrl -Passthru $pso | Add-Member NoteProperty -Name "Metadata" -Value $_.Node.CvaUrl -Passthru $pso | Add-Member NoteProperty -Name "MD5" -Value $_.Node.md5 -Passthru $pso | Add-Member NoteProperty -Name "Size" -Value $_.Node.Size -Passthru $pso | Add-Member NoteProperty -Name "ReleaseDate" -Value $_.Node.DateReleased -Passthru if ($download.IsPresent) { if ($friendlyName.IsPresent) { Write-Verbose "Need to get CVA data to determine Friendly Name for download file" $target = getfriendlyFileName -number $pso.id.ToLower().TrimStart("sp") -From $pso.Name -Verbose:$VerbosePreference } else { $target = $pso.id } if ($downloadDirectory) { $target = "$downloadDirectory\$target" } else { $cwd = Convert-Path . $target = "$cwd\$target" } if ($downloadMetadata.IsPresent) { Invoke-HPPrivateDownloadFile -url ("https://" + $pso.Metadata) -target "$target.cva" -progress $progress -NoClobber $overwrite -Verbose:$VerbosePreference -skipSignatureCheck -maxRetries $maxRetries } Invoke-HPPrivateDownloadFile -url ("https://" + $pso.Url) -target "$target.exe" -progress $progress -NoClobber $overwrite -Verbose:$VerbosePreference -maxRetries $maxRetries if ($downloadNotes.IsPresent) { Invoke-HPPrivateDownloadFile -url ("https://" + $pso.ReleaseNotes) -target "$target.htm" -progress $progress -NoClobber $overwrite -Verbose:$VerbosePreference -skipSignatureCheck -maxRetries $maxRetries } } } } } } $result = $results | Select-Object * -Unique switch ($format) { "xml" { $result | ConvertTo-Xml -As String} "json" { $result | ConvertTo-Json } "csv" { $result | ConvertTo-Csv -NoTypeInformation } default { return $result } } } # private functionality below function matchCategory ([string]$cat,[string[]]$allowed) { if ($allowed -eq $null) { return $true } if ($cat.startsWith("Driver -") -eq $true) { return $allowed -eq "driver" } if ($cat.startsWith("Operating System -") -eq $true) { return $allowed -eq "os" } if ($cat.StartsWith("Manageability - Driver Pack") -eq $true) { return $allowed -eq "driverpack"} if ($cat.StartsWith("Manageability -") -eq $true) { return $allowed -eq "manageability"} if ($cat.StartsWith("Utility -") -eq $true) { return $allowed -eq "utility"} if ($cat.StartsWith("Dock -") -eq $true) { return $allowed -eq "dock"} if (($cat -eq "BIOS") -Or ($cat.StartsWith("BIOS -") -eq $true)) { return $allowed -eq "BIOS"} if ($cat -eq "firmware") { return $allowed -eq "firmware"} if ($cat -eq "diagnostic") { return $allowed -eq "diagnostic"} else { return $allowed -eq "software" } return $false } function matchAnyCharacteristic ([string[]]$targetedCharacteristic,[string]$SSM,[string]$DPB) { if ($targetedCharacteristic -eq $null) { return $true } if ($targetedCharacteristic.Count -eq 0) { return $true } foreach ($characteristic in $targetedCharacteristic) { if (($characteristic.Trim().ToLower() -eq "ssm") -and ($SSM.Trim().ToLower() -eq "true")) { return $true } if (($characteristic.Trim().ToLower() -eq "dpb") -and ($DPB.Trim().ToLower() -eq "true")) { return $true } } return $false } function Release-Ref ($ref) { [System.Runtime.InteropServices.Marshal]::ReleaseComObject([System.__ComObject]$ref) | Out-Null [System.GC]::Collect() [System.GC]::WaitForPendingFinalizers() } # perform an action after a softpaq download completed function postDownloadSoftpaqAction ([string]$downloadedFile,[string]$action,[string]$number,$info,[string]$Destination) { $cmd = $null switch ($action) { "extract" { if(!$Destination){ $Destination = (Get-Item $downloadedFile).DirectoryName $Destination = Join-Path -Path $Destination -ChildPath (Get-Item $downloadedFile).Basename } Write-Verbose -Message "Extracting $downloadedFile to: $Destination" Start-Process -Wait "$downloadedFile" -ArgumentList "-e -f $Destination", "-s" } "install" { #$cmd = descendNodesAndGet $info -field "install" Start-Process -Wait "$downloadedFile" } "silentinstall" { # Get the silent install command from the metadata if (!$info) { $info = Get-SoftpaqMetadata $number } $cmd = descendNodesAndGet $info -field "silentinstall" Start-Process -Wait "$downloadedFile" -ArgumentList "-s","-e cmd.exe","-a","/c $cmd" } } } # create a friendly name from softpaq metadata (CVA) function getfriendlyFileName { [CmdletBinding()] param( [int]$number, $info, [string]$from ) try { $title = "sp$number" #if title was passed in, we use it if ($from) { $title = $from } #else if object was passed in, we use it elseif ($info -ne $null) { $title = ($info | Out-SoftpaqField Title) } #else use a default else { $title = "(No description available)"} $pass1 = removeInvalidCharacters $title $pass2 = $pass1.Trim() $pass3 = $pass2 -replace ('\s+','_') return $number.ToString("sp######") + "-" + $pass3 } catch { Write-Host -ForegroundColor Magenta "Could not determine friendly name, using softpaq number." Write-Host -ForegroundColor Magenta $_.Exception.Message return "sp$number" } } # remove invalid characters from a filename function removeInvalidCharacters ([string]$Name) { $invalidChars = [IO.Path]::GetInvalidFileNameChars() -join '' $re = "[{0}]" -f [regex]::Escape($invalidChars) return ($Name -replace $re) } #shortcuts to various sections of CVA file $mapper = @{ "Install" = "Install Execution|Install"; "SilentInstall" = "Install Execution|SilentInstall"; "Number" = "Softpaq|SoftpaqNumber"; "Title" = "Software Title|%lang"; "Description" = "%lang.Software Description|_body"; "Platforms" = "System Information|%KeyValues(^SysName.*$)"; "PlatformIDs" = "System Information|%KeyValues(^SysId.*$)"; "SoftPaqSHA256" = "Softpaq|SoftPaqSHA256"; "SoftPaqMD5" = "Softpaq|SoftPaqMD5"; "Version" = "General|VendorVersion"; }; #ISO to CVA language mapper $lang_mapper = @{ "en" = "us"; }; # navigate a CVA structure function descendNodesAndGet ($root,$field,$lang = "en") { $f1 = $mapper[$field].Replace("%lang",$lang_mapper[$lang]) $f = $f1.Split("|") $node = $root foreach ($c in $f) { if ($c -match "^%KeyValues\(.*\)$") { return $node } if ($c -match "^%Keys\(.*\)$") { return $node } $node = $node[$c] } $node } # SIG # Begin signature block # MIIcNwYJKoZIhvcNAQcCoIIcKDCCHCQCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDxJuIuDcabGcJA # gINj75+wvT1B7dyoQajahNZhGd4aT6CCCo0wggU2MIIEHqADAgECAhAM1s71mz4i # 3j/UnuaI4vzeMA0GCSqGSIb3DQEBCwUAMHYxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xNTAzBgNV # BAMTLERpZ2lDZXJ0IFNIQTIgSGlnaCBBc3N1cmFuY2UgQ29kZSBTaWduaW5nIENB # MB4XDTE5MDQyMjAwMDAwMFoXDTIwMDQyOTEyMDAwMFowdTELMAkGA1UEBhMCVVMx # EzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVBhbG8gQWx0bzEQMA4GA1UE # ChMHSFAgSW5jLjEZMBcGA1UECxMQSFAgQ3liZXJzZWN1cml0eTEQMA4GA1UEAxMH # SFAgSW5jLjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANEwuTFpw7fQ # 3Ds5fvexal46Gg9TNMvdiJu7qMqDZnDJNl7ECdEPyLxsioGS7/yomOS9RXdXMJOm # tyV4/wIPbBaGC8E2tbLTbQQ4IJbgvC+Vc46vbo+sI8YTG6qBICOovFw9VhUNXXEy # SwHMoBNk8JS8R1slPpJKmNGB10HSatMGaHja0Lbqos0QuEx/tx2OXe+mzepIo66T # dtSv2MfPy2tcVcXIdiJGn7f4otxoj6T9X7hVIl78r5Y2XWHYtDK8KaV1E/qkiNXK # 1Xw5S53zv2VsZl6i1LZwt3d1Q9pUmm1AZe2YdhSGvwMP2LYBJGXIBbyLYnxS4HKB # R7MYZyz7H2kCAwEAAaOCAb8wggG7MB8GA1UdIwQYMBaAFGedDyAJDMyKOuWCRnJi # /PHMkOVAMB0GA1UdDgQWBBSnSAWgK15kcBLxsg4XNsT7ncH29zAOBgNVHQ8BAf8E # BAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwbQYDVR0fBGYwZDAwoC6gLIYqaHR0 # cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItaGEtY3MtZzEuY3JsMDCgLqAshipo # dHRwOi8vY3JsNC5kaWdpY2VydC5jb20vc2hhMi1oYS1jcy1nMS5jcmwwTAYDVR0g # BEUwQzA3BglghkgBhv1sAwswKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGln # aWNlcnQuY29tL0NQUzAIBgZngQwBBAEwgYgGCCsGAQUFBwEBBHwwejAkBggrBgEF # BQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMFIGCCsGAQUFBzAChkZodHRw # Oi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRTSEEySGlnaEFzc3VyYW5j # ZUNvZGVTaWduaW5nQ0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQAD # ggEBAJQblkFw+UYKYSY2M/CIEpJxZDnf+cDhodKAy+goI3XfExRHhyLu3Gc2ibFB # Y4wyz/sJSfHehtNPYckXxR9k/FB/GfYtEACug9xXxJ+iLxWUNQ4KPt3bXY/kmDxW # D1QXJFLbW5Dop3w/K0DL3fxnjOfYCcxsYodbeEiCJprCdNi3zd6x/J8Y35GDbLA5 # p7RfIAzKrmBLPHFGDWr/jWTfwPfUNz6jYJ51m0Ba9j81kzpxNUD0yBIZXBkVvSkx # A09KxzMSSvxvV9DSqSezQBVgWnl9TbElouYUQwk64i0GzL4lTsphK4rQJJ2uuKtH # wN4E0ibpm0uIqbLhgk+3ic8fHTIwggVPMIIEN6ADAgECAhALfhCQPDhJD/ovZ5qH # oae5MA0GCSqGSIb3DQEBCwUAMGwxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdp # Q2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xKzApBgNVBAMTIkRp # Z2lDZXJ0IEhpZ2ggQXNzdXJhbmNlIEVWIFJvb3QgQ0EwHhcNMTMxMDIyMTIwMDAw # WhcNMjgxMDIyMTIwMDAwWjB2MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNl # cnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMTUwMwYDVQQDEyxEaWdp # Q2VydCBTSEEyIEhpZ2ggQXNzdXJhbmNlIENvZGUgU2lnbmluZyBDQTCCASIwDQYJ # KoZIhvcNAQEBBQADggEPADCCAQoCggEBALRKXn0HD0HexPV2Fja9cf/PP09zS5zR # Df5Ky1dYXoUW3QIVVJnwjzwvTQJ4EGjI2DVLP8H3Z86YHK4zuS0dpApUk8SFot81 # sfXxPKezNPtdSMlGyWJEvEiZ6yhJU8M9j8AO3jWY6WJR3z1rQGHuBEHaz6dcVpbR # +Uy3RISHmGnlgrkT5lW/yJJwkgoxb3+LMqvPa1qfYsQ+7r7tWaRTfwvxUoiKewpn # JMuQzezSTTRMsOG1n5zG9m8szebKU3QBn2c13jhJLc7tOUSCGXlOGrK1+7t48Elm # p8/6XJZ1kosactn/UJJTzD7CQzIJGoYTaTz7gTIzMmR1cygmHQgwOwcCAwEAAaOC # AeEwggHdMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMBMGA1Ud # JQQMMAoGCCsGAQUFBwMDMH8GCCsGAQUFBwEBBHMwcTAkBggrBgEFBQcwAYYYaHR0 # cDovL29jc3AuZGlnaWNlcnQuY29tMEkGCCsGAQUFBzAChj1odHRwOi8vY2FjZXJ0 # cy5kaWdpY2VydC5jb20vRGlnaUNlcnRIaWdoQXNzdXJhbmNlRVZSb290Q0EuY3J0 # MIGPBgNVHR8EgYcwgYQwQKA+oDyGOmh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9E # aWdpQ2VydEhpZ2hBc3N1cmFuY2VFVlJvb3RDQS5jcmwwQKA+oDyGOmh0dHA6Ly9j # cmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEhpZ2hBc3N1cmFuY2VFVlJvb3RDQS5j # cmwwTwYDVR0gBEgwRjA4BgpghkgBhv1sAAIEMCowKAYIKwYBBQUHAgEWHGh0dHBz # Oi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCgYIYIZIAYb9bAMwHQYDVR0OBBYEFGed # DyAJDMyKOuWCRnJi/PHMkOVAMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSYJhoIAu9j # ZCvDMA0GCSqGSIb3DQEBCwUAA4IBAQBqDv9+E3wGpUvALoz5U2QJ4rpYkTBQ7Myf # 4dOoL0hGNhgp0HgoX5hWQA8eur2xO4dc3FvYIA3tGhZN1REkIUvxJ2mQE+sRoQHa # /bVOeVl1vTgqasP2jkEriqKL1yxRUdmcoMjjTrpsqEfSTtFoH4wCVzuzKWqOaiAq # ufIAYmS6yOkA+cyk1LqaNdivLGVsFnxYId5KMND66yRdBsmdFretSkXTJeIM8ECq # XE2sfs0Ggrl2RmkI2DK2gv7jqVg0QxuOZ2eXP2gxFjY4lT6H98fDr516dxnZ3pO1 # /W4r/JT5PbdMEjUsML7ojZ4FcJpIE/SM1ucerDjnqPOtDLd67GftMYIRADCCEPwC # AQEwgYowdjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcG # A1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTE1MDMGA1UEAxMsRGlnaUNlcnQgU0hBMiBI # aWdoIEFzc3VyYW5jZSBDb2RlIFNpZ25pbmcgQ0ECEAzWzvWbPiLeP9Se5oji/N4w # DQYJYIZIAWUDBAIBBQCgfDAQBgorBgEEAYI3AgEMMQIwADAZBgkqhkiG9w0BCQMx # DAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkq # hkiG9w0BCQQxIgQg4RqaGA25A/Q2SZRr1TmtKMiRHVkt/Hd7m4+TFikduD4wDQYJ # KoZIhvcNAQEBBQAEggEAm4gDywRqcGyQM2nPVeb45ELdVr9Vj4kbSvGd3DHJlOXP # K0kTFBOMkRixomXMh7sY63AuArhzfHc+ZXxcz3e4fpDLgMcrEGFBqZWJowzvmbuV # Z8+yPNTHSXHRjBfQrrDRcxVGC7Wa6uOVBR7LLL5UousSSc+We5V2C+DCFHiy+WX5 # BOL3pD3RpHmGZSd22fJ/ipxxOqxym1wGgC8UZDe/M8O3p34T1PPkommBYefGaqJk # jWhoS0qsRPBmInXG06d0vmLEEvcnAowdr0a6kGfKXlMT51YjEKOTc05qcsaXidx/ # rwSYl5CHw3AgBAozDQpnTW/2m7XnZKgqDV6mFKTRBKGCDsgwgg7EBgorBgEEAYI3 # AwMBMYIOtDCCDrAGCSqGSIb3DQEHAqCCDqEwgg6dAgEDMQ8wDQYJYIZIAWUDBAIB # BQAwdwYLKoZIhvcNAQkQAQSgaARmMGQCAQEGCWCGSAGG/WwHATAxMA0GCWCGSAFl # AwQCAQUABCAlEQnP/EcdQN2X+ZlL4trQiOZ+L28N1WQcak/7u0Y6zAIQJEWsAUbC # o8Nli396tCKzhxgPMjAyMDAyMTQyMjUwMzBaoIILuzCCBoIwggVqoAMCAQICEATN # P4VornbGG7D+cWDMp20wDQYJKoZIhvcNAQELBQAwcjELMAkGA1UEBhMCVVMxFTAT # BgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEx # MC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIFRpbWVzdGFtcGluZyBD # QTAeFw0xOTEwMDEwMDAwMDBaFw0zMDEwMTcwMDAwMDBaMEwxCzAJBgNVBAYTAlVT # MRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjEkMCIGA1UEAxMbVElNRVNUQU1QLVNI # QTI1Ni0yMDE5LTEwLTE1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA # 6WQ1nPqpmGVkG+QX3LgpNsxnCViFTTDgyf/lOzwRKFCvBzHiXQkYwvaJjGkIBCPg # dy2dFeW46KFqjv/UrtJ6Fu/4QbUdOXXBzy+nrEV+lG2sAwGZPGI+fnr9RZcxtPq3 # 2UI+p1Wb31pPWAKoMmkiE76Lgi3GmKtrm7TJ8mURDHQNsvAIlnTE6LJIoqEUpfj6 # 4YlwRDuN7/uk9MO5vRQs6wwoJyWAqxBLFhJgC2kijE7NxtWyZVkh4HwsEo1wDo+K # yuDT17M5d1DQQiwues6cZ3o4d1RA/0+VBCDU68jOhxQI/h2A3dDnK3jqvx9wxu5C # FlM2RZtTGUlinXoCm5UUowIDAQABo4IDODCCAzQwDgYDVR0PAQH/BAQDAgeAMAwG # A1UdEwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwggG/BgNVHSAEggG2 # MIIBsjCCAaEGCWCGSAGG/WwHATCCAZIwKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3 # LmRpZ2ljZXJ0LmNvbS9DUFMwggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAA # dQBzAGUAIABvAGYAIAB0AGgAaQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAA # YwBvAG4AcwB0AGkAdAB1AHQAZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8A # ZgAgAHQAaABlACAARABpAGcAaQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4A # ZAAgAHQAaABlACAAUgBlAGwAeQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUA # ZQBtAGUAbgB0ACAAdwBoAGkAYwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwA # aQB0AHkAIABhAG4AZAAgAGEAcgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQA # IABoAGUAcgBlAGkAbgAgAGIAeQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZI # AYb9bAMVMB8GA1UdIwQYMBaAFPS24SAd/imu0uRhpbKiJbLIFzVuMB0GA1UdDgQW # BBRWUw/BxgenTdfYbldygFBM5OyewTBxBgNVHR8EajBoMDKgMKAuhixodHRwOi8v # Y3JsMy5kaWdpY2VydC5jb20vc2hhMi1hc3N1cmVkLXRzLmNybDAyoDCgLoYsaHR0 # cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTItYXNzdXJlZC10cy5jcmwwgYUGCCsG # AQUFBwEBBHkwdzAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29t # ME8GCCsGAQUFBzAChkNodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNl # cnRTSEEyQXNzdXJlZElEVGltZXN0YW1waW5nQ0EuY3J0MA0GCSqGSIb3DQEBCwUA # A4IBAQAug6FEBUoE47kyUvrZgfAau/gJjSO5PdiSoeZGHEovbno8Y243F6Mav1gj # skOclINOOQmwLOjH4eLM7ct5a87eIwFH7ZVUgeCAexKxrwKGqTpzav74n8GN0SGM # 5CmCw4oLYAACnR9HxJ+0CmhTf1oQpvgi5vhTkjFf2IKDLW0TQq6DwRBOpCT0R5ze # DyJyd1x/T+k5mCtXkkTX726T2UPHBDNjUTdWnkcEEcOjWFQh2OKOVtdJP1f8Cp8j # Xnv0lI3dnRq733oqptJFplUMj/ZMivKWz4lG3DGykZCjXzMwYFX1/GswrKHt5EdO # M55naii1TcLtW5eC+MupCGxTCbT3MIIFMTCCBBmgAwIBAgIQCqEl1tYyG35B5AXa # NpfCFTANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGln # aUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtE # aWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMTYwMTA3MTIwMDAwWhcNMzEw # MTA3MTIwMDAwWjByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5j # MRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBT # SEEyIEFzc3VyZWQgSUQgVGltZXN0YW1waW5nIENBMIIBIjANBgkqhkiG9w0BAQEF # AAOCAQ8AMIIBCgKCAQEAvdAy7kvNj3/dqbqCmcU5VChXtiNKxA4HRTNREH3Q+X1N # aH7ntqD0jbOI5Je/YyGQmL8TvFfTw+F+CNZqFAA49y4eO+7MpvYyWf5fZT/gm+vj # RkcGGlV+Cyd+wKL1oODeIj8O/36V+/OjuiI+GKwR5PCZA207hXwJ0+5dyJoLVOOo # CXFr4M8iEA91z3FyTgqt30A6XLdR4aF5FMZNJCMwXbzsPGBqrC8HzP3w6kfZiFBe # /WZuVmEnKYmEUeaC50ZQ/ZQqLKfkdT66mA+Ef58xFNat1fJky3seBdCEGXIX8RcG # 7z3N1k3vBkL9olMqT4UdxB08r8/arBD13ays6Vb/kwIDAQABo4IBzjCCAcowHQYD # VR0OBBYEFPS24SAd/imu0uRhpbKiJbLIFzVuMB8GA1UdIwQYMBaAFEXroq/0ksuC # MS1Ri6enIZ3zbcgPMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGG # MBMGA1UdJQQMMAoGCCsGAQUFBwMIMHkGCCsGAQUFBwEBBG0wazAkBggrBgEFBQcw # AYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEMGCCsGAQUFBzAChjdodHRwOi8v # Y2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3J0 # MIGBBgNVHR8EejB4MDqgOKA2hjRodHRwOi8vY3JsNC5kaWdpY2VydC5jb20vRGln # aUNlcnRBc3N1cmVkSURSb290Q0EuY3JsMDqgOKA2hjRodHRwOi8vY3JsMy5kaWdp # Y2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3JsMFAGA1UdIARJMEcw # OAYKYIZIAYb9bAACBDAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy # dC5jb20vQ1BTMAsGCWCGSAGG/WwHATANBgkqhkiG9w0BAQsFAAOCAQEAcZUS6VGH # VmnN793afKpjerN4zwY3QITvS4S/ys8DAv3Fp8MOIEIsr3fzKx8MIVoqtwU0HWqu # mfgnoma/Capg33akOpMP+LLR2HwZYuhegiUexLoceywh4tZbLBQ1QwRostt1AuBy # x5jWPGTlH0gQGF+JOGFNYkYkh2OMkVIsrymJ5Xgf1gsUpYDXEkdws3XVk4WTfraS # Z/tTYYmo9WuWwPRYaQ18yAGxuSh1t5ljhSKMYcp5lH5Z/IwP42+1ASa2bKXuh1Eh # 5Fhgm7oMLSttosR+u8QlK0cCCHxJrhO24XxCQijGGFbPQTS2Zl22dHv1VjMiLyI2 # skuiSpXY9aaOUjGCAk0wggJJAgEBMIGGMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNV # BAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJRCBUaW1lc3RhbXBpbmcgQ0ECEATN # P4VornbGG7D+cWDMp20wDQYJYIZIAWUDBAIBBQCggZgwGgYJKoZIhvcNAQkDMQ0G # CyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0yMDAyMTQyMjUwMzBaMCsGCyqG # SIb3DQEJEAIMMRwwGjAYMBYEFAMlvVBe2pYwLcIvT6AeTCi+KDTFMC8GCSqGSIb3 # DQEJBDEiBCBsIrcq7Hz20E3Xc3DQG96yCCz53Goy8zTZ894ptzz1uDANBgkqhkiG # 9w0BAQEFAASCAQCw+5tR5NajbxePumXp2x1TlRn692fE3yqaGBKSHL7AmMotrI02 # pcJxVryAX3nxP5yO55NaqvR9VCcZQQWqD07J9Vbr8VzaQBp5x+1ygMpnSOmPVqut # TNuxFLE3ZF3Y6lLDLmKzEihSAj9JprF4Ipra0GmgLR3un/zgaQr9PLkJeGb2ud1p # T2KaadelO2AuNkKtBatb2WsiJFXEils1+leWVHb01kgLtGHdcdtWn8MqvRN2UpYj # QJeDAteMhLSWICo+ktECJ7c+b8p3/3T2AJGFkgFxBfGYENeqmYG6MF+28oOeI1Bq # unGkjiM4tBUtvmxn7KX/S9VwJMMfNPTqRV+u # SIG # End signature block |