1
0
Files
Repository/Bios-Update-HP-v2.0/module/HP.Firmware/HP.Firmware.SureRecover.psm1
2025-10-31 08:58:36 +01:00

1713 lines
91 KiB
PowerShell

#
# Copyright 2018-2024 HP Development Company, L.P.
# All Rights Reserved.
#
# NOTICE: All information contained herein is, and remains the property of HP Development Company, L.P.
#
# The intellectual and technical concepts contained herein are proprietary to HP Development Company, L.P
# 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 Development Company, L.P.
using namespace HP.CMSLHelper
Set-StrictMode -Version 3.0
$ErrorActionPreference = 'Stop'
#requires -Modules "HP.Private"
# CMSL is normally installed in C:\Program Files\WindowsPowerShell\Modules
# but if installed via PSGallery and via PS7, it is installed in a different location
if (Test-Path "$PSScriptRoot\..\HP.Private\HP.CMSLHelper.dll") {
Add-Type -Path "$PSScriptRoot\..\HP.Private\HP.CMSLHelper.dll"
}
else{
Add-Type -Path "$PSScriptRoot\..\..\HP.Private\1.7.2\HP.CMSLHelper.dll"
}
[Flags()] enum DeprovisioningTarget{
AgentProvisioning = 1
OSImageProvisioning = 2
ConfigurationData = 4
TriggerRecoveryData = 8
ScheduleRecoveryData = 16
}
# Converts a BIOS value to a boolean
function ConvertValue {
param($value)
if ($value -eq "Enable" -or $value -eq "Yes") { return $true }
$false
}
<#
.SYNOPSIS
Retrieves the current state of the HP Sure Recover feature
.DESCRIPTION
This command retrieves the current state of the HP Sure Recover feature.
Refer to the New-HPSureRecoverConfigurationPayload command for more information on how to configure HP Sure Recover.
.PARAMETER All
If specified, the output includes the OS Recovery Image and the OS Recovery Agent configuration.
.NOTES
- Requires HP BIOS with HP Sure Recover support.
- This command requires elevated privileges.
.LINK
[Blog post: HP Secure Platform Management with the HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/hp-secure-platform-management-hp-client-management-script-library)
.LINK
[Blog post: Provisioning and Configuring HP Sure Recover with HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/provisioning-and-configuring-hp-sure-recover-hp-client-management-script-library)
.EXAMPLE
Get-HPSureRecoverState
#>
function Get-HPSureRecoverState
{
[CmdletBinding(HelpUri = "https://developers.hp.com/hp-client-management/doc/Get-HPSureRecoverState")]
param([switch]$All)
$mi_result = 0
$data = New-Object -TypeName surerecover_state_t
$c = '[DfmNativeSureRecover]::get_surerecover_state' + (Test-OSBitness) + '([ref]$data,[ref]$mi_result);'
$result = Invoke-Expression -Command $c
Test-HPPrivateCustomResult -result 0x80000711 -mi_result $mi_result -Category 0x05 -Verbose:$VerbosePreference
$fixed_version = "$($data.subsystem_version[0]).$($data.subsystem_version[1])"
if ($fixed_version -eq "0.0") {
Write-Verbose "Patched SureRecover version 0.0 to 1.0"
$fixed_version = "1.0"
}
$SchedulerIsDisabled = ($data.schedule.window_size -eq 0)
$RecoveryTimeBetweenRetries = ([uint32]$data.os_flags -shr 8) -band 0x0f
$RecoveryNumberOfRetries = ([uint32]$data.os_flags -shr 12) -band 0x07
if ($RecoveryNumberOfRetries -eq 0)
{
$RecoveryNumberOfRetries = "Infinite"
}
$imageFailoverIsConfigured = [bool]$data.image_failover
$obj = [ordered]@{
Version = $fixed_version
Nonce = $data.Nonce
BIOSFlags = ($data.os_flags -band 0xff)
ImageIsProvisioned = (($data.flags -band 2) -ne 0)
AgentFlags = ($data.re_flags -band 0xff)
AgentIsProvisioned = (($data.flags -band 1) -ne 0)
RecoveryTimeBetweenRetries = $RecoveryTimeBetweenRetries
RecoveryNumberOfRetries = $RecoveryNumberOfRetries
Schedule = New-Object -TypeName PSObject -Property @{
DayOfWeek = $data.schedule.day_of_week
hour = [uint32]$data.schedule.hour
minute = [uint32]$data.schedule.minute
WindowSize = [uint32]$data.schedule.window_size
}
ConfigurationDataIsProvisioned = (($data.flags -band 4) -ne 0)
TriggerRecoveryDataIsProvisioned = (($data.flags -band 8) -ne 0)
ScheduleRecoveryDataIsProvisioned = (($data.flags -band 16) -ne 0)
SchedulerIsDisabled = $SchedulerIsDisabled
ImageFailoverIsConfigured = $imageFailoverIsConfigured
}
if ($all.IsPresent)
{
$ia = [ordered]@{
Url = (Get-HPBIOSSettingValue -Name "OS Recovery Image URL")
Username = (Get-HPBIOSSettingValue -Name "OS Recovery Image Username")
#PublicKey = (Get-HPBiosSettingValue -name "OS Recovery Image Public Key")
ProvisioningVersion = (Get-HPBIOSSettingValue -Name "OS Recovery Image Provisioning Version")
}
$aa = [ordered]@{
Url = (Get-HPBIOSSettingValue -Name "OS Recovery Agent URL")
Username = (Get-HPBIOSSettingValue -Name "OS Recovery Agent Username")
#PublicKey = (Get-HPBiosSettingValue -name "OS Recovery Agent Public Key")
ProvisioningVersion = (Get-HPBIOSSettingValue -Name "OS Recovery Agent Provisioning Version")
}
$Image = New-Object -TypeName PSObject -Property $ia
$Agent = New-Object -TypeName PSObject -Property $aa
$obj.Add("Image",$Image)
$osFailover = New-Object System.Collections.Generic.List[PSCustomObject]
if ($imageFailoverIsConfigured) {
try {
$osFailoverIndex = Get-HPSureRecoverFailoverConfiguration -Image 'os'
$osFailover.Add($osFailoverIndex)
}
catch {
Write-Warning "Error reading OS Failover configuration $($Index): $($_.Exception.Message)"
}
$obj.Add("ImageFailover",$osFailover)
}
$obj.Add("Agent",$Agent)
}
return New-Object -TypeName PSCustomObject -Property $obj
}
<#
.SYNOPSIS
Retrieves the current HP Sure Recover failover configuration
.DESCRIPTION
This command retrieves the current configuration of the HP Sure Recover failover feature.
.PARAMETER Image
Specifies whether this command will create a configuration payload for a Recovery Agent image or a Recovery OS image. However, only the value 'os' is supported for now.
.NOTES
- Requires HP BIOS with HP Sure Recover and Failover support.
- This command requires elevated privileges.
.EXAMPLE
Get-HPSureRecoverFailoverConfiguration -Image os
#>
function Get-HPSureRecoverFailoverConfiguration
{
[CmdletBinding(HelpUri = "https://developers.hp.com/hp-client-management/doc/Get-HPSureRecoverFailoverConfiguration")]
param(
[ValidateSet("os")]
[Parameter(Mandatory = $false,Position = 0)]
[string]$Image = 'os'
)
$mi_result = 0
$data = New-Object -TypeName surerecover_failover_configuration_t
$index = 1
$c = '[DfmNativeSureRecover]::get_surerecover_failover_configuration' + (Test-OSBitness) + '([bool]$False,[int]$index,[ref]$data,[ref]$mi_result);'
try {
$result = Invoke-Expression -Command $c
Test-HPPrivateCustomResult -result $result -mi_result $mi_result -Category 0x05 -Verbose:$VerbosePreference
}
catch {
Write-Error "Failover is not configured properly. Error: $($_.Exception.Message)"
}
return [PSCustomObject]@{
Index = $Index
Version = $data.version
Url = $data.url
Username = $data.username
}
}
<#
.SYNOPSIS
Retrieves information about the HP Sure Recover embedded reimaging device
.DESCRIPTION
This command retrieves information about the embedded reimaging device for HP Sure Recover.
.NOTES
The embedded reimaging device is an optional hardware feature, and if not present, the field Embedded Reimaging Device is false.
.NOTES
- Requires HP BIOS with HP Sure Recover support
- Requires Embedded Reimaging device hardware option
- This command requires elevated privileges.
.LINK
[Blog post: HP Secure Platform Management with the HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/hp-secure-platform-management-hp-client-management-script-library)
.LINK
[Blog post: Provisioning and Configuring HP Sure Recover with HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/provisioning-and-configuring-hp-sure-recover-hp-client-management-script-library)
.EXAMPLE
Get-HPSureRecoverReimagingDeviceDetails
#>
function Get-HPSureRecoverReimagingDeviceDetails
{
[CmdletBinding(HelpUri = "https://developers.hp.com/hp-client-management/doc/Get-HPSureRecoverReimagingDeviceDetails")]
param()
$result = @{}
try {
[string]$ImageVersion = Get-HPBIOSSettingValue -Name "OS Recovery Image Version"
$result.Add("ImageVersion",$ImageVersion)
}
catch {}
try {
[string]$DriverVersion = Get-HPBIOSSettingValue -Name "OS Recovery Driver Version"
$result.Add("DriverVersion",$DriverVersion)
}
catch {}
try{
# eMMC module is present if Embedded Storage for Recovery BIOS setting exists
[string]$OSRsize = Get-HPBIOSSettingValue -Name "Embedded Storage for Recovery"
$result.Add("EmbeddedReimagingDevice", $true)
}
catch{
$result.Add("EmbeddedReimagingDevice", $false)
}
$result
}
<#
.SYNOPSIS
Creates a payload to configure the HP Sure Recover OS or Recovery image
.DESCRIPTION
This command creates a payload to configure a custom HP Sure Recover OS or Recovery image. There are three signing options to choose from:
- Signing Key File (and Password) using -SigningKeyFile and -SigningKeyPassword parameters
- Signing Key Certificate using -SigningKeyCertificate parameter
- Remote Signing using -RemoteSigningServiceKeyID and -RemoteSigningServiceURL parameters
Please note that using a Key File with Password in PFX format is recommended over using an X509 Certificate object because a private key in a certificate is not password protected.
This command writes the created payload to the pipeline or to the file specified in the OutputFile parameter.
This payload can then be passed to the Set-HPSecurePlatformPayload command.
Security note: Payloads should only be created on secure servers. Once created, the payload may be transferred to a client and applied via the Set-HPSecurePlatformPayload. Creating the payload and passing it to the Set-HPSecurePlatformPayload command via the pipeline is not a recommended production pattern.
.PARAMETER Image
Specifies whether this command will create a configuration payload for a Recovery Agent image or a Recovery OS image. The value must be either 'agent' or 'os'.
.PARAMETER SigningKeyFile
Specifies the path to the Secure Platform Management signing key as a PFX file. If the PFX file is protected by a password (recommended), the SigningKeyPassword parameter should also be provided.
.PARAMETER SigningKeyPassword
Specifies the Secure Platform Management signing key file password, if required
.PARAMETER SigningKeyCertificate
Specifies the Secure Platform Management signing key certificate as an X509Certificate object
.PARAMETER ImageCertificateFile
Specifies the path to the image signing certificate as a PFX file. If the PFX file is protected by a password (recommended), the ImageCertificatePassword parameter should also be provided. Depending on the Image switch, this will be either the signing key file for the Agent or the OS image.
ImageCertificateFile and PublicKeyFile are mutually exclusive.
.PARAMETER ImageCertificatePassword
Specifies the image signing key file password, if required
.PARAMETER ImageCertificate
Specifies the image signing key certificate as an X509Certificate object. Depending on the Image parameter, this value will be either the signing key certificate for the Agent or the OS image.
.PARAMETER PublicKeyFile
Specifies the image signing key as the path to a base64-encoded RSA key (a PEM file).
ImageCertificateFile and PublicKeyFile are mutually exclusive.
.PARAMETER PublicKey
Specifies the image signing key as an array of bytes, including modulus and exponent.
This option is currently reserved for internal use.
.PARAMETER Nonce
Specifies a Nonce. If nonce is specified, the Secure Platform Management subsystem will only accept commands with a nonce greater or equal to the last nonce sent. This approach helps to prevent replay attacks. If not specified, the nonce is inferred from the current local time. The current local time as the nonce works in most cases. However, this approach has a resolution of seconds, so when performing parallel operations or a high volume of operations, it is possible for the same counter to be interpreted for more than one command. In these cases, the caller should use its own nonce derivation and provide it through this parameter.
.PARAMETER Version
Specifies the operation version. Each new configuration payload must increment the last operation payload version, as available in the public WMI setting 'OS Recovery Image Provisioning Version'. If this parameter is not provided, this command will read the public wmi setting and increment it automatically.
.PARAMETER Username
Specifies the username for accessing the url specified in the Url parameter, if any.
.PARAMETER Password
Specifies the password for accessing the url specified in the Url parameter, if any.
.PARAMETER Url
Specifies the url from where to download the image. If not specified, the default HP.COM location will be used.
.PARAMETER OutputFile
Specifies the file to write output to instead of writing the output to the pipeline
.PARAMETER RemoteSigningServiceKeyID
Specifies the Signing Key ID to be used
.PARAMETER RemoteSigningServiceURL
Specifies the (Key Management Service) KMS server URL (I.e.: https://<KMSAppName>.azurewebsites.net/)
.PARAMETER CacheAccessToken
If specified, the access token is cached in msalcache.dat file and user credentials will not be asked again until the credentials expire.
This parameter should be specified for caching the access token when performing multiple operations on the KMS server.
If access token is not cached, the user must re-enter credentials on each call of this command.
.NOTES
- Requires HP BIOS with HP Sure Recover support
.LINK
[Blog post: HP Secure Platform Management with the HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/hp-secure-platform-management-hp-client-management-script-library)
.LINK
[Blog post: Provisioning and Configuring HP Sure Recover with HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/provisioning-and-configuring-hp-sure-recover-hp-client-management-script-library)
.EXAMPLE
$payload = New-HPSureRecoverImageConfigurationPayload -SigningKeyFile "$path\signing_key.pfx" -Image OS -ImageKeyFile `
"$path\os.pfx" -username my_http_user -password `s3cr3t` -url "http://my.company.com"
...
$payload | Set-HPSecurePlatformPayload
#>
function New-HPSureRecoverImageConfigurationPayload
{
[CmdletBinding(DefaultParameterSetName = "SKFileCert_OSFilePem",HelpUri = "https://developers.hp.com/hp-client-management/doc/New-HPSureRecoverImageConfigurationPayload")]
param(
[Parameter(ParameterSetName = "SKFileCert_OSBytesCert",Mandatory = $true,Position = 0)]
[Parameter(ParameterSetName = "SKBytesCert_OSBytesCert",Mandatory = $true,Position = 0)]
[Parameter(ParameterSetName = "SKFileCert_OSFileCert",Mandatory = $true,Position = 0)]
[Parameter(ParameterSetName = "SKBytesCert_OSFileCert",Mandatory = $true,Position = 0)]
[Parameter(ParameterSetName = "SKFileCert_OSBytesPem",Mandatory = $true,Position = 0)]
[Parameter(ParameterSetName = "SKBytesCert_OSBytesPem",Mandatory = $true,Position = 0)]
[Parameter(ParameterSetName = "SKFileCert_OSFilePem",Mandatory = $true,Position = 0)]
[Parameter(ParameterSetName = "SKBytesCert_OSFilePem",Mandatory = $true,Position = 0)]
[Parameter(ParameterSetName = "RemoteSigning_OSBytesCert",Mandatory = $true,Position = 0)]
[Parameter(ParameterSetName = "RemoteSigning_OSFileCert",Mandatory = $true,Position = 0)]
[Parameter(ParameterSetName = "RemoteSigning_OSBytesPem",Mandatory = $true,Position = 0)]
[Parameter(ParameterSetName = "RemoteSigning_OSFilePem",Mandatory = $true,Position = 0)]
[ValidateSet("os","agent")]
[string]$Image,
[Parameter(ParameterSetName = "SKFileCert_OSBytesCert",Mandatory = $true,Position = 1)]
[Parameter(ParameterSetName = "SKFileCert_OSFileCert",Mandatory = $true,Position = 1)]
[Parameter(ParameterSetName = "SKFileCert_OSBytesPem",Mandatory = $true,Position = 1)]
[Parameter(ParameterSetName = "SKFileCert_OSFilePem",Mandatory = $true,Position = 1)]
[System.IO.FileInfo]$SigningKeyFile,
[Parameter(ParameterSetName = "SKFileCert_OSBytesCert",Mandatory = $false,Position = 2)]
[Parameter(ParameterSetName = "SKFileCert_OSFileCert",Mandatory = $false,Position = 2)]
[Parameter(ParameterSetName = "SKFileCert_OSBytesPem",Mandatory = $false,Position = 2)]
[Parameter(ParameterSetName = "SKFileCert_OSFilePem",Mandatory = $false,Position = 2)]
[string]$SigningKeyPassword,
[Parameter(ParameterSetName = "SKBytesCert_OSBytesCert",Mandatory = $true,Position = 3)]
[Parameter(ParameterSetName = "SKBytesCert_OSFileCert",Mandatory = $true,Position = 3)]
[Parameter(ParameterSetName = "SKBytesCert_OSBytesPem",Mandatory = $true,Position = 3)]
[Parameter(ParameterSetName = "SKBytesCert_OSFilePem",Mandatory = $true,Position = 3)]
[System.Security.Cryptography.X509Certificates.X509Certificate2]$SigningKeyCertificate,
[Parameter(ParameterSetName = "SKFileCert_OSFileCert",Mandatory = $true,Position = 4)]
[Parameter(ParameterSetName = "SKBytesCert_OSFileCert",Mandatory = $true,Position = 4)]
[Parameter(ParameterSetName = "RemoteSigning_OSFileCert",Mandatory = $true,Position = 1)]
[Alias("ImageKeyFile")]
[System.IO.FileInfo]$ImageCertificateFile,
[Parameter(ParameterSetName = "SKFileCert_OSFileCert",Mandatory = $false,Position = 5)]
[Parameter(ParameterSetName = "SKBytesCert_OSFileCert",Mandatory = $false,Position = 5)]
[Parameter(ParameterSetName = "RemoteSigning_OSFileCert",Mandatory = $false,Position = 2)]
[Alias("ImageKeyPassword")]
[string]$ImageCertificatePassword,
[Parameter(ParameterSetName = "SKFileCert_OSBytesCert",Mandatory = $true,Position = 6)]
[Parameter(ParameterSetName = "SKBytesCert_OSBytesCert",Mandatory = $true,Position = 6)]
[Parameter(ParameterSetName = "RemoteSigning_OSBytesCert",Mandatory = $true,Position = 1)]
[System.Security.Cryptography.X509Certificates.X509Certificate2]$ImageCertificate,
[Parameter(ParameterSetName = "SKFileCert_OSFilePem",Mandatory = $true,Position = 7)]
[Parameter(ParameterSetName = "SKBytesCert_OSFilePem",Mandatory = $true,Position = 7)]
[Parameter(ParameterSetName = "RemoteSigning_OSFilePem",Mandatory = $true,Position = 1)]
[System.IO.FileInfo]$PublicKeyFile,
[Parameter(ParameterSetName = "SKFileCert_OSBytesPem",Mandatory = $true,Position = 8)]
[Parameter(ParameterSetName = "SKBytesCert_OSBytesPem",Mandatory = $true,Position = 8)]
[Parameter(ParameterSetName = "RemoteSigning_OSBytesPem",Mandatory = $true,Position = 1)]
[byte[]]$PublicKey,
[Parameter(ParameterSetName = "SKFileCert_OSBytesCert",Mandatory = $false,Position = 9)]
[Parameter(ParameterSetName = "SKBytesCert_OSBytesCert",Mandatory = $false,Position = 9)]
[Parameter(ParameterSetName = "SKFileCert_OSFileCert",Mandatory = $false,Position = 9)]
[Parameter(ParameterSetName = "SKBytesCert_OSFileCert",Mandatory = $false,Position = 9)]
[Parameter(ParameterSetName = "SKFileCert_OSBytesPem",Mandatory = $false,Position = 9)]
[Parameter(ParameterSetName = "SKBytesCert_OSBytesPem",Mandatory = $false,Position = 9)]
[Parameter(ParameterSetName = "SKFileCert_OSFilePem",Mandatory = $false,Position = 9)]
[Parameter(ParameterSetName = "SKBytesCert_OSFilePem",Mandatory = $false,Position = 9)]
[Parameter(ParameterSetName = "RemoteSigning_OSBytesCert",Mandatory = $false,Position = 2)]
[Parameter(ParameterSetName = "RemoteSigning_OSFileCert",Mandatory = $false,Position = 3)]
[Parameter(ParameterSetName = "RemoteSigning_OSBytesPem",Mandatory = $false,Position = 2)]
[Parameter(ParameterSetName = "RemoteSigning_OSFilePem",Mandatory = $false,Position = 2)]
[uint32]$Nonce = [math]::Floor([decimal](Get-Date (Get-Date).ToUniversalTime() -UFormat "%s").Replace(',','.')),
[Parameter(ParameterSetName = "SKFileCert_OSBytesCert",Mandatory = $false,Position = 10)]
[Parameter(ParameterSetName = "SKBytesCert_OSBytesCert",Mandatory = $false,Position = 10)]
[Parameter(ParameterSetName = "SKFileCert_OSFileCert",Mandatory = $false,Position = 10)]
[Parameter(ParameterSetName = "SKBytesCert_OSFileCert",Mandatory = $false,Position = 10)]
[Parameter(ParameterSetName = "SKFileCert_OSBytesPem",Mandatory = $false,Position = 10)]
[Parameter(ParameterSetName = "SKBytesCert_OSBytesPem",Mandatory = $false,Position = 10)]
[Parameter(ParameterSetName = "SKFileCert_OSFilePem",Mandatory = $false,Position = 10)]
[Parameter(ParameterSetName = "SKBytesCert_OSFilePem",Mandatory = $false,Position = 10)]
[Parameter(ParameterSetName = "RemoteSigning_OSBytesCert",Mandatory = $false,Position = 3)]
[Parameter(ParameterSetName = "RemoteSigning_OSFileCert",Mandatory = $false,Position = 4)]
[Parameter(ParameterSetName = "RemoteSigning_OSBytesPem",Mandatory = $false,Position = 3)]
[Parameter(ParameterSetName = "RemoteSigning_OSFilePem",Mandatory = $false,Position = 3)]
[uint16]$Version,
[Parameter(ParameterSetName = "SKFileCert_OSBytesCert",Mandatory = $false,Position = 11)]
[Parameter(ParameterSetName = "SKBytesCert_OSBytesCert",Mandatory = $false,Position = 11)]
[Parameter(ParameterSetName = "SKFileCert_OSFileCert",Mandatory = $false,Position = 11)]
[Parameter(ParameterSetName = "SKBytesCert_OSFileCert",Mandatory = $false,Position = 11)]
[Parameter(ParameterSetName = "SKFileCert_OSBytesPem",Mandatory = $false,Position = 11)]
[Parameter(ParameterSetName = "SKBytesCert_OSBytesPem",Mandatory = $false,Position = 11)]
[Parameter(ParameterSetName = "SKFileCert_OSFilePem",Mandatory = $false,Position = 11)]
[Parameter(ParameterSetName = "SKBytesCert_OSFilePem",Mandatory = $false,Position = 11)]
[Parameter(ParameterSetName = "RemoteSigning_OSBytesCert",Mandatory = $false,Position = 4)]
[Parameter(ParameterSetName = "RemoteSigning_OSFileCert",Mandatory = $false,Position = 5)]
[Parameter(ParameterSetName = "RemoteSigning_OSBytesPem",Mandatory = $false,Position = 4)]
[Parameter(ParameterSetName = "RemoteSigning_OSFilePem",Mandatory = $false,Position = 4)]
[string]$Username,
[Parameter(ParameterSetName = "SKFileCert_OSBytesCert",Mandatory = $false,Position = 12)]
[Parameter(ParameterSetName = "SKBytesCert_OSBytesCert",Mandatory = $false,Position = 12)]
[Parameter(ParameterSetName = "SKFileCert_OSFileCert",Mandatory = $false,Position = 12)]
[Parameter(ParameterSetName = "SKBytesCert_OSFileCert",Mandatory = $false,Position = 12)]
[Parameter(ParameterSetName = "SKFileCert_OSBytesPem",Mandatory = $false,Position = 12)]
[Parameter(ParameterSetName = "SKBytesCert_OSBytesPem",Mandatory = $false,Position = 12)]
[Parameter(ParameterSetName = "SKFileCert_OSFilePem",Mandatory = $false,Position = 12)]
[Parameter(ParameterSetName = "SKBytesCert_OSFilePem",Mandatory = $false,Position = 12)]
[Parameter(ParameterSetName = "RemoteSigning_OSBytesCert",Mandatory = $false,Position = 5)]
[Parameter(ParameterSetName = "RemoteSigning_OSFileCert",Mandatory = $false,Position = 6)]
[Parameter(ParameterSetName = "RemoteSigning_OSBytesPem",Mandatory = $false,Position = 5)]
[Parameter(ParameterSetName = "RemoteSigning_OSFilePem",Mandatory = $false,Position = 5)]
[string]$Password,
[Parameter(ParameterSetName = "SKFileCert_OSBytesCert",Mandatory = $false,Position = 13)]
[Parameter(ParameterSetName = "SKBytesCert_OSBytesCert",Mandatory = $false,Position = 13)]
[Parameter(ParameterSetName = "SKFileCert_OSFileCert",Mandatory = $false,Position = 13)]
[Parameter(ParameterSetName = "SKBytesCert_OSFileCert",Mandatory = $false,Position = 13)]
[Parameter(ParameterSetName = "SKFileCert_OSBytesPem",Mandatory = $false,Position = 13)]
[Parameter(ParameterSetName = "SKBytesCert_OSBytesPem",Mandatory = $false,Position = 13)]
[Parameter(ParameterSetName = "SKFileCert_OSFilePem",Mandatory = $false,Position = 13)]
[Parameter(ParameterSetName = "SKBytesCert_OSFilePem",Mandatory = $false,Position = 13)]
[Parameter(ParameterSetName = "RemoteSigning_OSBytesCert",Mandatory = $false,Position = 6)]
[Parameter(ParameterSetName = "RemoteSigning_OSFileCert",Mandatory = $false,Position = 7)]
[Parameter(ParameterSetName = "RemoteSigning_OSBytesPem",Mandatory = $false,Position = 6)]
[Parameter(ParameterSetName = "RemoteSigning_OSFilePem",Mandatory = $false,Position = 6)]
[uri]$Url = "",
[Parameter(ParameterSetName = "SKFileCert_OSBytesCert",Mandatory = $false,Position = 14)]
[Parameter(ParameterSetName = "SKBytesCert_OSBytesCert",Mandatory = $false,Position = 14)]
[Parameter(ParameterSetName = "SKFileCert_OSFileCert",Mandatory = $false,Position = 14)]
[Parameter(ParameterSetName = "SKBytesCert_OSFileCert",Mandatory = $false,Position = 14)]
[Parameter(ParameterSetName = "SKFileCert_OSBytesPem",Mandatory = $false,Position = 14)]
[Parameter(ParameterSetName = "SKBytesCert_OSBytesPem",Mandatory = $false,Position = 14)]
[Parameter(ParameterSetName = "SKFileCert_OSFilePem",Mandatory = $false,Position = 14)]
[Parameter(ParameterSetName = "SKBytesCert_OSFilePem",Mandatory = $false,Position = 14)]
[Parameter(ParameterSetName = "RemoteSigning_OSBytesCert",Mandatory = $false,Position = 7)]
[Parameter(ParameterSetName = "RemoteSigning_OSFileCert",Mandatory = $false,Position = 8)]
[Parameter(ParameterSetName = "RemoteSigning_OSBytesPem",Mandatory = $false,Position = 7)]
[Parameter(ParameterSetName = "RemoteSigning_OSFilePem",Mandatory = $false,Position = 7)]
[System.IO.FileInfo]$OutputFile,
[Parameter(ParameterSetName = "RemoteSigning_OSBytesCert",Mandatory = $true,Position = 8)]
[Parameter(ParameterSetName = "RemoteSigning_OSFileCert",Mandatory = $true,Position = 9)]
[Parameter(ParameterSetName = "RemoteSigning_OSBytesPem",Mandatory = $true,Position = 8)]
[Parameter(ParameterSetName = "RemoteSigning_OSFilePem",Mandatory = $true,Position = 8)]
[string]$RemoteSigningServiceKeyID,
[Parameter(ParameterSetName = "RemoteSigning_OSBytesCert",Mandatory = $true,Position = 9)]
[Parameter(ParameterSetName = "RemoteSigning_OSFileCert",Mandatory = $true,Position = 10)]
[Parameter(ParameterSetName = "RemoteSigning_OSBytesPem",Mandatory = $true,Position = 9)]
[Parameter(ParameterSetName = "RemoteSigning_OSFilePem",Mandatory = $true,Position = 9)]
[string]$RemoteSigningServiceURL,
[Parameter(ParameterSetName = "RemoteSigning_OSBytesCert",Mandatory = $false,Position = 10)]
[Parameter(ParameterSetName = "RemoteSigning_OSFileCert",Mandatory = $false,Position = 11)]
[Parameter(ParameterSetName = "RemoteSigning_OSBytesPem",Mandatory = $false,Position = 10)]
[Parameter(ParameterSetName = "RemoteSigning_OSFilePem",Mandatory = $false,Position = 10)]
[switch]$CacheAccessToken
)
Write-Verbose "Creating SureRecover Image provisioning payload"
if ($PublicKeyFile -or $PublicKey) {
$osk = Get-HPPrivatePublicKeyCoalesce -File $PublicKeyFile -key $PublicKey -Verbose:$VerbosePreference
}
else {
$osk = Get-HPPrivateX509CertCoalesce -File $ImageCertificateFile -password $ImageCertificatePassword -cert $ImageCertificate -Verbose:$VerbosePreference
}
$OKBytes = $osk.Modulus
$opaque = New-Object opaque4096_t
$opaqueLength = 4096
$mi_result = 0
if (-not $Version) {
if ($image -eq "os")
{
$Version = [uint16](Get-HPBIOSSettingValue "OS Recovery Image Provisioning Version") + 1
}
else {
$Version = [uint16](Get-HPBIOSSettingValue "OS Recovery Agent Provisioning Version") + 1
}
Write-Verbose "New version number is $version"
}
$cmd = '[DfmNativeSureRecover]::get_surerecover_provisioning_opaque' + (Test-OSBitness) + '($Nonce, $Version, $OKBytes,$($OKBytes.Count),$Username, $Password, $($Url.ToString()), [ref]$opaque, [ref]$opaqueLength, [ref]$mi_result);'
$result = Invoke-Expression -Command $cmd
Test-HPPrivateCustomResult -result $result -mi_result $mi_result -Category 0x05
$payload = $opaque.raw[0..($opaqueLength - 1)]
if ($PSCmdlet.ParameterSetName -eq "RemoteSigning_OSBytesCert" -or $PSCmdlet.ParameterSetName -eq "RemoteSigning_OSFileCert" -or $PSCmdlet.ParameterSetName -eq "RemoteSigning_OSBytesPem" -or $PSCmdlet.ParameterSetName -eq "RemoteSigning_OSFilePem") {
$sig = Invoke-HPPrivateRemoteSignData -Data $payload -CertificateId $RemoteSigningServiceKeyID -KMSUri $RemoteSigningServiceURL -CacheAccessToken:$CacheAccessToken -Verbose:$VerbosePreference
}
else {
$sk = Get-HPPrivateX509CertCoalesce -File $SigningKeyFile -password $SigningKeyPassword -cert $SigningKeycertificate -Verbose:$VerbosePreference
$sig = Invoke-HPPrivateSignData -Data $payload -Certificate $sk.Full -Verbose:$VerbosePreference
}
[byte[]]$out = $sig + $payload
Write-Verbose "Building output document"
$output = New-Object -TypeName PortableFileFormat
$output.Data = $out
if ($Image -eq "os") {
$output.purpose = "hp:surerecover:provision:os_image"
}
else {
$output.purpose = "hp:surerecover:provision:recovery_image"
}
Write-Verbose "Provisioning version will be $version"
$output.timestamp = Get-Date
if ($OutputFile) {
Write-Verbose "Will output to file $OutputFile"
$f = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($OutputFile)
$output | ConvertTo-Json -Compress | Out-File -FilePath $f -Encoding utf8
}
else {
$output | ConvertTo-Json -Compress
}
}
<#
.SYNOPSIS
Creates a payload to deprovision HP Sure Recover
.DESCRIPTION
This command creates a payload to deprovision the HP Sure Recover feature. There are three signing options to choose from:
- Signing Key File (and Password) using -SigningKeyFile and -SigningKeyPassword parameters
- Signing Key Certificate using -SigningKeyCertificate parameter
- Remote Signing using -RemoteSigningServiceKeyID and -RemoteSigningServiceURL parameters
Please note that using a Key File with Password in PFX format is recommended over using an X509 Certificate object because a private key in a certificate is not password protected.
This command writes the created payload to the pipeline or to the file specified in the OutputFile parameter. This payload can then be passed to the Set-HPSecurePlatformPayload command.
Security note: Payloads should only be created on secure servers. Once created, the payload may be transferred to a client and applied via the Set-HPSecurePlatformPayload command. Creating the payload and passing it to the Set-HPSecurePlatformPayload command via the pipeline is not a recommended production pattern.
.PARAMETER SigningKeyFile
Specifies the path to the Secure Platform Management signing key as a PFX file. If the PFX file is protected by a password (recommended), the SigningKeyPassword parameter should also be provided.
.PARAMETER SigningKeyPassword
Specifies the Secure Platform Management signing key file password, if required.
.PARAMETER SigningKeyCertificate
Specifies the Secure Platform Management signing key certificate as an X509Certificate object.
.PARAMETER Nonce
Specifies a Nonce. If nonce is specified, the Secure Platform Management subsystem will only accept commands with a nonce greater or equal to the last nonce sent. This approach helps to prevent replay attacks. If not specified, the nonce is inferred from the current local time. The current local time as the nonce works in most cases. However, this approach has a resolution of seconds, so when performing parallel operations or a high volume of operations, it is possible for the same counter to be interpreted for more than one command. In these cases, the caller should use its own nonce derivation and provide it through this parameter.
.PARAMETER RemoveOnly
This parameter allows deprovisioning only specific parts of the Sure Recover subsystem. If not specified, the entire SureRecover is deprovisoned. Possible values are one or more of the following:
- AgentProvisioning - remove the Agent provisioning
- OSImageProvisioning - remove the OS Image provisioning
- ConfigurationData - remove HP SureRecover configuration data
- TriggerRecoveryData - remove the HP Sure Recover trigger definition
- ScheduleRecoveryData - remove the HP Sure Recover schedule definition
.PARAMETER OutputFile
Specifies the file to write output to instead of writing the output to the pipelineing output to the specified file, instead of writing it to the pipeline.
.PARAMETER RemoteSigningServiceKeyID
Specifies the Signing Key ID to be used
.PARAMETER RemoteSigningServiceURL
Specifies the (Key Management Service) KMS server URL (I.e.: https://<KMSAppName>.azurewebsites.net/)
.PARAMETER CacheAccessToken
If specified, the access token is cached in msalcache.dat file and user credentials will not be asked again until the credentials expire.
This parameter should be specified for caching the access token when performing multiple operations on the KMS server.
If access token is not cached, the user must re-enter credentials on each call of this command.
.LINK
[Blog post: HP Secure Platform Management with the HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/hp-secure-platform-management-hp-client-management-script-library)
.LINK
[Blog post: Provisioning and Configuring HP Sure Recover with HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/provisioning-and-configuring-hp-sure-recover-hp-client-management-script-library)
.NOTES
- Requires HP BIOS with HP Sure Recover support
.EXAMPLE
New-HPSureRecoverDeprovisionPayload -SigningKeyFile sk.pfx
#>
function New-HPSureRecoverDeprovisionPayload
{
[CmdletBinding(DefaultParameterSetName = "SF",HelpUri = "https://developers.hp.com/hp-client-management/doc/New-HPSureRecoverDeprovisionPayload")]
param(
[Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 0)]
[System.IO.FileInfo]$SigningKeyFile,
[Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 1)]
[string]$SigningKeyPassword,
[Parameter(ParameterSetName = "SB",Mandatory = $true,Position = 0)]
[System.Security.Cryptography.X509Certificates.X509Certificate2]$SigningKeyCertificate,
[Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 3)]
[Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 3)]
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 0)]
[uint32]$Nonce = [math]::Floor([decimal](Get-Date (Get-Date).ToUniversalTime() -UFormat "%s").Replace(',','.')),
[Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 4)]
[Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 4)]
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 1)]
[DeprovisioningTarget[]]$RemoveOnly,
[Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 5)]
[Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 5)]
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 2)]
[System.IO.FileInfo]$OutputFile,
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $true,Position = 3)]
[string]$RemoteSigningServiceKeyID,
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $true,Position = 4)]
[string]$RemoteSigningServiceURL,
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 5)]
[switch]$CacheAccessToken
)
Write-Verbose "Creating SureRecover deprovisioning payload"
if ($RemoveOnly) {
[byte]$target = 0
$RemoveOnly | ForEach-Object { $target = $target -bor $_ }
Write-Verbose "Will deprovision only $([string]$RemoveOnly)"
}
else
{
[byte]$target = 31 # all five bits
Write-Verbose "No deprovisioning filter specified, will deprovision all SureRecover"
}
$payload = [BitConverter]::GetBytes($nonce) + $target
if ($PSCmdlet.ParameterSetName -eq "RemoteSigning") {
$sig = Invoke-HPPrivateRemoteSignData -Data $payload -CertificateId $RemoteSigningServiceKeyID -KMSUri $RemoteSigningServiceURL -CacheAccessToken:$CacheAccessToken -Verbose:$VerbosePreference
}
else {
$sk = Get-HPPrivateX509CertCoalesce -File $SigningKeyFile -password $SigningKeyPassword -cert $SigningKeycertificate -Verbose:$VerbosePreference
$sig = Invoke-HPPrivateSignData -Data $payload -Certificate $sk.Full -Verbose:$VerbosePreference
}
Write-Verbose "Building output document"
$output = New-Object -TypeName PortableFileFormat
$output.Data = $sig + $payload
$output.purpose = "hp:surerecover:deprovision"
$output.timestamp = Get-Date
if ($OutputFile) {
Write-Verbose "Will output to file $OutputFile"
$f = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($OutputFile)
$output | ConvertTo-Json -Compress | Out-File -FilePath $f -Encoding utf8
}
else {
$output | ConvertTo-Json -Compress
}
}
<#
.SYNOPSIS
Creates a payload to configure the HP Sure Recover schedule
.DESCRIPTION
This command creates a payload to configure a HP Sure Recover schedule. There are three signing options to choose from:
- Signing Key File (and Password) using -SigningKeyFile and -SigningKeyPassword parameters
- Signing Key Certificate using -SigningKeyCertificate parameter
- Remote Signing using -RemoteSigningServiceKeyID and -RemoteSigningServiceURL parameters
Please note that using a Key File with Password in PFX format is recommended over using an X509 Certificate object because a private key in a certificate is not password protected.
This command writes the created payload to the pipeline or to the file specified in the OutputFile parameter. This payload can then be passed to the Set-HPSecurePlatformPayload command.
Security note: Payloads should only be created on secure servers. Once created, the payload may be transferred to a client and applied via the Set-HPSecurePlatformPayload command. Creating the payload and passing it to the Set-HPSecurePlatformPayload command via the pipeline is not a recommended production pattern.
.PARAMETER SigningKeyFile
Specifies the path to the Secure Platform Management signing key, as a PFX file. If the PFX file is protected by a password (recommended),
the SigningKeyPassword parameter should also be provided.
.PARAMETER SigningKeyPassword
Specifies the Secure Platform Management signing key file password, if required.
.PARAMETER SigningKeyCertificate
Specifies the Secure Platform Management signing key certificate, as an X509Certificate object.
.PARAMETER Nonce
Specifies a Nonce. If nonce is specified, the Secure Platform Management subsystem will only accept commands with a nonce greater or equal to the last nonce sent. This approach helps to prevent replay attacks. If not specified, the nonce is inferred from the current local time. The current local time as the nonce works in most cases. However, this approach has a resolution of seconds, so when performing parallel operations or a high volume of operations, it is possible for the same counter to be interpreted for more than one command. In these cases, the caller should use its own nonce derivation and provide it through this parameter.
.PARAMETER DayOfWeek
Specifies the day of the week for the schedule
.PARAMETER Hour
Specifies the hour value for the schedule
.PARAMETER Minute
Specifies the minute of the schedule
.PARAMETER WindowSize
Specifies the windows size for the schedule activation in minutes, in case the exact configured schedule is
missed. By default, the window is zero. The value may not be larger than 240 minutes (4 hours).
.PARAMETER Disable
If specified, this command creates a payload to disable HP Sure Recover schedule.
.PARAMETER OutputFile
Specifies the file to write output to instead of writing the output to the pipelineing output to the specified file, instead of writing it to the pipeline.
.PARAMETER RemoteSigningServiceKeyID
Specifies the Signing Key ID to be used
.PARAMETER RemoteSigningServiceURL
Specifies the (Key Management Service) KMS server URL (I.e.: https://<KMSAppName>.azurewebsites.net/)
.PARAMETER CacheAccessToken
If specified, the access token is cached in msalcache.dat file and user credentials will not be asked again until the credentials expire.
This parameter should be specified for caching the access token when performing multiple operations on the KMS server.
If access token is not cached, the user must re-enter credentials on each call of this command.
.LINK
[Blog post: HP Secure Platform Management with the HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/hp-secure-platform-management-hp-client-management-script-library)
.LINK
[Blog post: Provisioning and Configuring HP Sure Recover with HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/provisioning-and-configuring-hp-sure-recover-hp-client-management-script-library)
.NOTES
- Requires HP BIOS with HP Sure Recover support
.EXAMPLE
New-HPSureRecoverSchedulePayload -SigningKeyFile sk.pfx -DayOfWeek Sunday -Hour 2
.EXAMPLE
New-HPSureRecoverSchedulePayload -SigningKeyFile sk.pfx -Disable
#>
function New-HPSureRecoverSchedulePayload
{
[CmdletBinding(DefaultParameterSetName = "SF",HelpUri = "https://developers.hp.com/hp-client-management/doc/New-HPSureRecoverSchedulePayload")]
param(
[Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 0)]
[Parameter(ParameterSetName = "DisableSF",Mandatory = $true,Position = 0)]
[System.IO.FileInfo]$SigningKeyFile,
[Parameter(ValueFromPipeline,ParameterSetName = "SB",Mandatory = $true,Position = 0)]
[Parameter(ParameterSetName = "DisableSB",Mandatory = $true,Position = 0)]
[System.Security.Cryptography.X509Certificates.X509Certificate2]$SigningKeyCertificate,
[Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 1)]
[Parameter(ParameterSetName = "DisableSF",Mandatory = $false,Position = 1)]
[string]$SigningKeyPassword,
[Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 2)]
[Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 1)]
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 0)]
[Parameter(ParameterSetName = "DisableRemoteSigning",Mandatory = $false,Position = 0)]
[Parameter(ParameterSetName = "DisableSF",Mandatory = $false,Position = 2)]
[Parameter(ParameterSetName = "DisableSB",Mandatory = $false,Position = 1)]
[uint32]$Nonce = [math]::Floor([decimal](Get-Date (Get-Date).ToUniversalTime() -UFormat "%s").Replace(',','.')),
[Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 3)]
[Parameter(ParameterSetName = "SB",Mandatory = $true,Position = 2)]
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $true,Position = 1)]
[surerecover_day_of_week]$DayOfWeek = [surerecover_day_of_week]::Sunday,
[Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 4)]
[Parameter(ParameterSetName = "SB",Mandatory = $true,Position = 3)]
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $true,Position = 2)]
[ValidateRange(0,23)]
[uint32]$Hour = 0,
[Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 5)]
[Parameter(ParameterSetName = "SB",Mandatory = $true,Position = 4)]
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $true,Position = 3)]
[ValidateRange(0,59)]
[uint32]$Minute = 0,
[Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 6)]
[Parameter(ParameterSetName = "SB",Mandatory = $true,Position = 5)]
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $true,Position = 4)]
[ValidateRange(1,240)]
[uint32]$WindowSize = 0,
[Parameter(ParameterSetName = "DisableRemoteSigning",Mandatory = $true,Position = 1)]
[Parameter(ParameterSetName = "DisableSF",Mandatory = $true,Position = 3)]
[Parameter(ParameterSetName = "DisableSB",Mandatory = $true,Position = 2)]
[switch]$Disable,
[Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 7)]
[Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 6)]
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 5)]
[Parameter(ParameterSetName = "DisableRemoteSigning",Mandatory = $false,Position = 2)]
[Parameter(ParameterSetName = "DisableSF",Mandatory = $false,Position = 4)]
[Parameter(ParameterSetName = "DisableSB",Mandatory = $false,Position = 3)]
[System.IO.FileInfo]$OutputFile,
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $true,Position = 6)]
[Parameter(ParameterSetName = "DisableRemoteSigning",Mandatory = $true,Position = 3)]
[string]$RemoteSigningServiceKeyID,
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $true,Position = 7)]
[Parameter(ParameterSetName = "DisableRemoteSigning",Mandatory = $true,Position = 4)]
[string]$RemoteSigningServiceURL,
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 8)]
[Parameter(ParameterSetName = "DisableRemoteSigning",Mandatory = $false,Position = 5)]
[switch]$CacheAccessToken
)
Write-Verbose "Creating SureRecover scheduling payload"
$schedule_data = New-Object -TypeName surerecover_schedule_data_t
Write-Verbose "Will set the SureRecover scheduler"
$schedule_data.day_of_week = $DayOfWeek
$schedule_data.hour = $Hour
$schedule_data.minute = $Minute
$schedule_data.window_size = $WindowSize
$schedule = New-Object -TypeName surerecover_schedule_data_payload_t
$schedule.schedule = $schedule_data
$schedule.Nonce = $Nonce
$cmd = New-Object -TypeName surerecover_schedule_payload_t
$cmd.Data = $schedule
[byte[]]$payload = (Convert-HPPrivateObjectToBytes -obj $schedule -Verbose:$VerbosePreference)[0]
if ($PSCmdlet.ParameterSetName -eq "RemoteSigning" -or $PSCmdlet.ParameterSetName -eq "DisableRemoteSigning") {
$cmd.sig = Invoke-HPPrivateRemoteSignData -Data $payload -CertificateId $RemoteSigningServiceKeyID -KMSUri $RemoteSigningServiceURL -CacheAccessToken:$CacheAccessToken -Verbose:$VerbosePreference
}
else {
$sk = Get-HPPrivateX509CertCoalesce -File $SigningKeyFile -password $SigningKeyPassword -cert $SigningKeycertificate -Verbose:$VerbosePreference
$cmd.sig = Invoke-HPPrivateSignData -Data $payload -Certificate $sk.Full -Verbose:$VerbosePreference
}
Write-Verbose "Building output document"
$output = New-Object -TypeName PortableFileFormat
$output.Data = (Convert-HPPrivateObjectToBytes -obj $cmd -Verbose:$VerbosePreference)[0]
$output.purpose = "hp:surerecover:scheduler"
$output.timestamp = Get-Date
if ($OutputFile) {
Write-Verbose "Will output to file $OutputFile"
$f = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($OutputFile)
$output | ConvertTo-Json -Compress | Out-File -FilePath $f -Encoding utf8
}
else {
$output | ConvertTo-Json -Compress
}
}
<#
.SYNOPSIS
Creates a payload to configure HP Sure Recover
.DESCRIPTION
This command create a payload to configure HP Sure Recover. There are three signing options to choose from:
- Signing Key File (and Password) using -SigningKeyFile and -SigningKeyPassword parameters
- Signing Key Certificate using -SigningKeyCertificate parameter
- Remote Signing using -RemoteSigningServiceKeyID and -RemoteSigningServiceURL parameters
Please note that using a Key File with Password in PFX format is recommended over using an X509 Certificate object because a private key in a certificate is not password protected.
This command writes the created payload to the pipeline or to the file specified in the OutputFile parameter.
This payload can then be passed to the Set-HPSecurePlatformPayload command.
Security note: Payloads should only be created on secure servers. Once created, the payload may be transferred to a client and applied via the Set-HPSecurePlatformPayload command. Creating the payload and passing it to the Set-HPSecurePlatformPayload command via the pipeline is not a recommended production pattern.
.PARAMETER SigningKeyFile
Specifies the path to the Secure Platform Management signing key as a PFX file. If the PFX file is protected by a password (recommended), the SigningKeyPassword parameter should also be provided.
.PARAMETER SigningKeyPassword
Specifies the Secure Platform Management signing key file password, if required.
.PARAMETER SigningKeyCertificate
Specifies the Secure Platform Management signing key certificate as an X509Certificate object.
.PARAMETER SigningKeyModulus
The Secure Platform Management signing key modulus
.PARAMETER Nonce
Specifies a Nonce. If nonce is specified, the Secure Platform Management subsystem will only accept commands with a nonce greater or equal to the last nonce sent. This approach helps to prevent replay attacks. If not specified, the nonce is inferred from the current local time. The current local time as the nonce works in most cases. However, this approach has a resolution of seconds, so when performing parallel operations or a high volume of operations, it is possible for the same counter to be interpreted for more than one command. In these cases, the caller should use its own nonce derivation and provide it through this parameter.
.PARAMETER BIOSFlags
Specifies the imaging flags to set. Please note that this parameter was previously named OSImageFlags.
None = 0
NetworkBasedRecovery = 1 => Enable network based recovery
WiFi = 2 => Enable WiFi
PartitionRecovery = 4 => Enable partition based recovery
SecureStorage = 8 => Enable recovery from secure storage device
SecureEraseUnit = 16 => Secure Erase Unit before recovery
RollbackPrevention = 64 => Enforce rollback prevention
.PARAMETER AgentFlags
Specifies the agent flags to set:
None = 0 => OEM OS release with in-box drivers
DRDVD = 1 => OEM OS release with optimized drivers
CorporateReadyWithoutOffice = 2 => Corporate ready without office
CorporateReadyWithOffice = 4 => Corporate ready with office
InstallManageabilitySuite = 16 => Install current components of the Manageability Suite included on the DRDVD
InstallSecuritySuite = 32 => Install current components of the Security Suite included on the DRDVD
RollbackPrevention = 64 => Enforce rollback prevention
Please note that the Image Type AgentFlags DRDVD, CorporateReadyWithOffice, and CorporateReadyWithoutOffice are mutually exclusive. If you choose to set an Image type flag, you can only set one of the three flags.
.PARAMETER OutputFile
Specifies the file to write output to instead of writing the output to the pipelineing output to the specified file, instead of writing it to the pipeline.
.PARAMETER RemoteSigningServiceKeyID
Specifies the Signing Key ID to be used
.PARAMETER RemoteSigningServiceURL
Specifies the (Key Management Service) KMS server URL (I.e.: https://<KMSAppName>.azurewebsites.net/)
.PARAMETER CacheAccessToken
If specified, the access token is cached in msalcache.dat file and user credentials will not be asked again until the credentials expire.
This parameter should be specified for caching the access token when performing multiple operations on the KMS server.
If access token is not cached, the user must re-enter credentials on each call of this command.
.LINK
[Blog post: HP Secure Platform Management with the HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/hp-secure-platform-management-hp-client-management-script-library)
.LINK
[Blog post: Provisioning and Configuring HP Sure Recover with HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/provisioning-and-configuring-hp-sure-recover-hp-client-management-script-library)
.NOTES
- Requires HP BIOS with HP Sure Recover support
.EXAMPLE
New-HPSureRecoverConfigurationPayload -SigningKeyFile sk.pfx -BIOSFlags WiFi -AgentFlags DRDVD
.EXAMPLE
New-HPSureRecoverConfigurationPayload -SigningKeyFile sk.pfx -BIOSFlags WiFi,SecureStorage -AgentFlags DRDVD,RollbackPrevention
#>
function New-HPSureRecoverConfigurationPayload
{
[CmdletBinding(DefaultParameterSetName = "SF",HelpUri = "https://developers.hp.com/hp-client-management/doc/New-HPSureRecoverConfigurationPayload")]
param(
[Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 0)]
[System.IO.FileInfo]$SigningKeyFile,
[Parameter(ValueFromPipeline,ParameterSetName = "SB",Mandatory = $true,Position = 0)]
[System.Security.Cryptography.X509Certificates.X509Certificate2]$SigningKeyCertificate,
[Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 1)]
[string]$SigningKeyPassword,
[Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 3)]
[Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 3)]
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 0)]
[uint32]$Nonce = [math]::Floor([decimal](Get-Date (Get-Date).ToUniversalTime() -UFormat "%s").Replace(',','.')),
[Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 4)]
[Parameter(ParameterSetName = "SB",Mandatory = $true,Position = 4)]
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $true,Position = 1)]
[Alias("OSImageFlags")]
[surerecover_os_flags_no_reserved]$BIOSFlags, # does not allow setting to reserved values
[Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 5)]
[Parameter(ParameterSetName = "SB",Mandatory = $true,Position = 5)]
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $true,Position = 2)]
[surerecover_re_flags_no_reserved]$AgentFlags, # does not allow setting to reserved values
[Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 6)]
[Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 6)]
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 3)]
[System.IO.FileInfo]$OutputFile,
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $true,Position = 4)]
[string]$RemoteSigningServiceKeyID,
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $true,Position = 5)]
[string]$RemoteSigningServiceURL,
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 6)]
[switch]$CacheAccessToken
)
# Image Type AgentFlags DRDVD, CorporateReadyWithOffice. and CorporateReadyWithoutOffice are all mutually exclusive
# as only one of the three is valid at a time
if ($AgentFlags -band 1 -and ($AgentFlags -band 2 -or $AgentFlags -band 4) -or
$AgentFlags -band 2 -and ($AgentFlags -band 1 -or $AgentFlags -band 4) -or
$AgentFlags -band 4 -and ($AgentFlags -band 1 -or $AgentFlags -band 2)){
throw "Cannot set multiple Image Type AgentFlags: DRDVD, CorporateReadyWithOffice, and CorporateReadyWithoutOffice are mutually exclusive."
}
# surerecover_configuration_payload_t has flags enums with reserved values,
# but since the parameter validation ensures user cannot select reserved values to set,
# we can safely cast the values to uint32 to be used in the payload with reserved values
$data = New-Object -TypeName surerecover_configuration_payload_t
$data.os_flags = [uint32]$BIOSFlags
$data.re_flags = [uint32]$AgentFlags
$data.arp_counter = $Nonce
$cmd = New-Object -TypeName surerecover_configuration_t
$cmd.Data = $data
[byte[]]$payload = (Convert-HPPrivateObjectToBytes -obj $data -Verbose:$VerbosePreference)[0]
if ($PSCmdlet.ParameterSetName -eq "RemoteSigning") {
$cmd.sig = Invoke-HPPrivateRemoteSignData -Data $payload -CertificateId $RemoteSigningServiceKeyID -KMSUri $RemoteSigningServiceURL -CacheAccessToken:$CacheAccessToken -Verbose:$VerbosePreference
}
else {
$sk = Get-HPPrivateX509CertCoalesce -File $SigningKeyFile -password $SigningKeyPassword -cert $SigningKeycertificate
$cmd.sig = Invoke-HPPrivateSignData -Data $payload -Certificate $sk.Full -Verbose:$VerbosePreference
}
Write-Verbose "Building output document"
$output = New-Object -TypeName PortableFileFormat
$output.Data = (Convert-HPPrivateObjectToBytes -obj $cmd -Verbose:$VerbosePreference)[0]
$output.purpose = "hp:surerecover:configure"
$output.timestamp = Get-Date
if ($OutputFile) {
Write-Verbose "Will output to file $OutputFile"
$f = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($OutputFile)
$output | ConvertTo-Json -Compress | Out-File -FilePath $f -Encoding utf8
}
else {
$output | ConvertTo-Json -Compress
}
}
<#
.SYNOPSIS
Creates a payload to configure HP Sure Recover OS or Recovery image failover
.DESCRIPTION
This command creates a payload to configure HP Sure Recover OS or Recovery image failover. There are three signing options to choose from:
- Signing Key File (and Password) using -SigningKeyFile and -SigningKeyPassword parameters
- Signing Key Certificate using -SigningKeyCertificate parameter
- Remote Signing using -RemoteSigningServiceKeyID and -RemoteSigningServiceURL parameters
Please note that using a Key File with Password in PFX format is recommended over using an X509 Certificate object because a private key in a certificate is not password protected.
This command writes the created payload to the pipeline or to the file specified in the OutputFile parameter. This payload can then be passed to the Set-HPSecurePlatformPayload command.
Security note: Payloads should only be created on secure servers. Once created, the payload may be transferred to a client and applied via the Set-HPSecurePlatformPayload command. Creating the payload and passing it to the Set-HPSecurePlatformPayload command via the pipeline is not a recommended production pattern.
.PARAMETER Image
Specifies whether this command will create a configuration payload for a Recovery Agent image or a Recovery OS image. For now, only 'os' is supported.
.PARAMETER SigningKeyFile
Specifies the path to the Secure Platform Management signing key, as a PFX file. If the PFX file is protected by a password (recommended),
the SigningKeyPassword parameter should also be provided.
.PARAMETER SigningKeyPassword
Specifies the Secure Platform Management signing key file password, if required.
.PARAMETER SigningKeyCertificate
Specifies the Secure Platform Management signing key certificate as an X509Certificate object.
.PARAMETER Version
Specifies the operation version. Each new configuration payload must increment the last operation payload version, as available in the Get-HPSureRecoverFailoverConfiguration. If this parameter is not provided, this command will read from current system and increment it automatically.
.PARAMETER Username
Specifies the username for accessing the url specified in the Url parameter, if any.
.PARAMETER Password
Specifies the password for accessing the url specified in the Url parameter, if any.
.PARAMETER Url
Specifies the URL from where to download the image. An empty URL can be specified to deprovision Failover.
.PARAMETER Nonce
Specifies a Nonce. If nonce is specified, the Secure Platform Management subsystem will only accept commands with a nonce greater or equal to the last nonce sent. This approach helps to prevent replay attacks. If not specified, the nonce is inferred from the current local time. The current local time as the nonce works in most cases. However, this approach has a resolution of seconds, so when performing parallel operations or a high volume of operations, it is possible for the same counter to be interpreted for more than one command. In these cases, the caller should use its own nonce derivation and provide it through this parameter.
.PARAMETER OutputFile
Specifies the file to write output to instead of writing the output to the pipelineing output to the specified file, instead of writing it to the pipeline.
.PARAMETER RemoteSigningServiceKeyID
Specifies the Signing Key ID to be used
.PARAMETER RemoteSigningServiceURL
Specifies the (Key Management Service) KMS server URL (I.e.: https://<KMSAppName>.azurewebsites.net/). This URL must be https.
.PARAMETER CacheAccessToken
If specified, the access token is cached in msalcache.dat file and user credentials will not be asked again until the credentials expire.
This parameter should be specified for caching the access token when performing multiple operations on the KMS server.
If access token is not cached, the user must re-enter credentials on each call of this command.
.LINK
[Blog post: HP Secure Platform Management with the HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/hp-secure-platform-management-hp-client-management-script-library)
.NOTES
- Requires HP BIOS with HP Sure Recover support
.EXAMPLE
New-HPSureRecoverFailoverConfigurationPayload -SigningKeyFile sk.pfx -Version 1 -Url ''
.EXAMPLE
New-HPSureRecoverFailoverConfigurationPayload -SigningKeyFile sk.pfx -Image os -Version 1 -Nonce 2 -Url 'http://url.com/' -Username 'user' -Password 123
#>
function New-HPSureRecoverFailoverConfigurationPayload
{
[CmdletBinding(DefaultParameterSetName = "SF",HelpUri = "https://developers.hp.com/hp-client-management/doc/New-HPSureRecoverFailoverConfigurationPayload")]
param(
[Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 0)]
[System.IO.FileInfo]$SigningKeyFile,
[Parameter(ValueFromPipeline,ParameterSetName = "SB",Mandatory = $true,Position = 0)]
[System.Security.Cryptography.X509Certificates.X509Certificate2]$SigningKeyCertificate,
[Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 1)]
[string]$SigningKeyPassword,
[Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 2)]
[Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 1)]
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 0)]
[ValidateSet("os")]
[string]$Image = "os",
[Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 3)]
[Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 2)]
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 1)]
[uint16]$Version,
[Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 3)]
[Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 2)]
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 2)]
[string]$Username,
[Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 3)]
[Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 2)]
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 3)]
[string]$Password,
[Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 3)]
[Parameter(ParameterSetName = "SB",Mandatory = $true,Position = 2)]
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $true,Position = 4)]
[uri]$Url = "",
[Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 3)]
[Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 3)]
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 5)]
[uint32]$Nonce = [math]::Floor([decimal](Get-Date (Get-Date).ToUniversalTime() -UFormat "%s").Replace(',','.')),
[Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 6)]
[Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 6)]
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 6)]
[System.IO.FileInfo]$OutputFile,
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $true,Position = 7)]
[string]$RemoteSigningServiceKeyID,
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $true,Position = 8)]
[string]$RemoteSigningServiceURL,
[Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 9)]
[switch]$CacheAccessToken
)
if (-not $Version) {
try {
$Version = (Get-HPSureRecoverFailoverConfiguration -Image $Image).Version + 1
}
catch {
# It is not possible to get current version if failover is not configured yet, assigning version 1
$Version = 1
}
Write-Verbose "New version number is $version"
}
$opaque = New-Object opaque4096_t
$opaqueLength = 4096
$mi_result = 0
[byte]$index = 1
$cmd = '[DfmNativeSureRecover]::get_surerecover_failover_opaque' + (Test-OSBitness) + '($Nonce, $Version, $index, $Username, $Password, $($Url.ToString()), [ref]$opaque, [ref]$opaqueLength, [ref]$mi_result);'
$result = Invoke-Expression -Command $cmd
Test-HPPrivateCustomResult -result $result -mi_result $mi_result -Category 0x05
[byte[]]$payload = $opaque.raw[0..($opaqueLength - 1)]
if ($PSCmdlet.ParameterSetName -eq "RemoteSigning") {
$sig = Invoke-HPPrivateRemoteSignData -Data $payload -CertificateId $RemoteSigningServiceKeyID -KMSUri $RemoteSigningServiceURL -CacheAccessToken:$CacheAccessToken -Verbose:$VerbosePreference
}
else {
$sk = Get-HPPrivateX509CertCoalesce -File $SigningKeyFile -password $SigningKeyPassword -cert $SigningKeycertificate
$sig = Invoke-HPPrivateSignData -Data $payload -Certificate $sk.Full -Verbose:$VerbosePreference
}
[byte[]]$out = $sig + $payload
Write-Verbose "Building output document"
$output = New-Object -TypeName PortableFileFormat
$output.Data = $out
$output.purpose = "hp:surerecover:failover:os_image"
$output.timestamp = Get-Date
if ($OutputFile) {
Write-Verbose "Will output to file $OutputFile"
$f = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($OutputFile)
$output | ConvertTo-Json -Compress | Out-File -FilePath $f -Encoding utf8
}
else {
$output | ConvertTo-Json -Compress
}
}
<#
.SYNOPSIS
Creates a payload to trigger HP Sure Recover events
.DESCRIPTION
This command creates a payload to trigger HP Sure Recover. There are three signing options to choose from:
- Signing Key File (and Password) using -SigningKeyFile and -SigningKeyPassword parameters
- Signing Key Certificate using -SigningKeyCertificate parameter
- Remote Signing using -RemoteSigningServiceKeyID and -RemoteSigningServiceURL parameters
Please note that using a Key File with Password in PFX format is recommended over using an X509 Certificate object because a private key in a certificate is not password protected.
This command writes the created payload to the pipeline or to the file specified in the OutputFile parameter. This payload can then be passed to the Set-HPSecurePlatformPayload command.
Security note: Payloads should only be created on secure servers. Once created, the payload may be transferred to a client and applied via the Set-HPSecurePlatformPayload command. Creating the payload and passing it to the Set-HPSecurePlatformPayload command via the pipeline is not a recommended production pattern.
.PARAMETER SigningKeyFile
Specifies the path to the Secure Platform Management signing key as a PFX file. If the PFX file is protected by a password (recommended), the SigningKeyPassword parameter should also be provided.
.PARAMETER SigningKeyPassword
Specifies the Secure Platform Management signing key file password, if required.
.PARAMETER SigningKeyCertificate
Specifies the Secure Platform Management signing key certificate as an X509Certificate object
.PARAMETER Nonce
Specifies a Nonce. If nonce is specified, the Secure Platform Management subsystem will only accept commands with a nonce greater or equal to the last nonce sent. This approach helps to prevent replay attacks. If not specified, the nonce is inferred from the current local time. The current local time as the nonce works in most cases. However, this approach has a resolution of seconds, so when performing parallel operations or a high volume of operations, it is possible for the same counter to be interpreted for more than one command. In these cases, the caller should use its own nonce derivation and provide it through this parameter.
.PARAMETER Set
If specified, this command sets the trigger information. This parameter is used by default and optional.
.PARAMETER Cancel
If specified, this command clears any existing trigger definition.
.PARAMETER ForceAfterReboot
Specifies how many reboots to count before applying the trigger. If not specified, the value defaults to 1 (next reboot).
.PARAMETER PromptPolicy
Specifies the prompting policy. If not specified, it will default to prompt before recovery, and on error.
.PARAMETER ErasePolicy
Specifies the erase policy for the imaging process
.PARAMETER OutputFile
Specifies the file to write output to instead of writing the output to the pipelineing output to the specified file, instead of writing it to the pipeline.
.PARAMETER RemoteSigningServiceKeyID
Specifies the Signing Key ID to be used
.PARAMETER RemoteSigningServiceURL
Specifies the (Key Management Service) KMS server URL (I.e.: https://<KMSAppName>.azurewebsites.net/)
.PARAMETER CacheAccessToken
If specified, the access token is cached in msalcache.dat file and user credentials will not be asked again until the credentials expire.
This parameter should be specified for caching the access token when performing multiple operations on the KMS server.
If access token is not cached, the user must re-enter credentials on each call of this command.
.LINK
[Blog post: HP Secure Platform Management with the HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/hp-secure-platform-management-hp-client-management-script-library)
.LINK
[Blog post: Provisioning and Configuring HP Sure Recover with HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/provisioning-and-configuring-hp-sure-recover-hp-client-management-script-library)
.NOTES
- Requires HP BIOS with HP Sure Recover support
.EXAMPLE
New-HPSureRecoverTriggerRecoveryPayload -SigningKeyFile sk.pfx
#>
function New-HPSureRecoverTriggerRecoveryPayload
{
[CmdletBinding(DefaultParameterSetName = "SF_Schedule",HelpUri = "https://developers.hp.com/hp-client-management/doc/New-HPSureRecoverTriggerRecoveryPayload")]
param(
[Parameter(ParameterSetName = "SF_Schedule",Mandatory = $true,Position = 0)]
[Parameter(ParameterSetName = "SF_Cancel",Mandatory = $true,Position = 0)]
[string]$SigningKeyFile,
[Parameter(ParameterSetName = "SF_Schedule",Mandatory = $false,Position = 1)]
[Parameter(ParameterSetName = "SF_Cancel",Mandatory = $false,Position = 1)]
[string]$SigningKeyPassword,
[Parameter(ValueFromPipeline,ParameterSetName = "SB_Schedule",Mandatory = $true,Position = 0)]
[Parameter(ValueFromPipeline,ParameterSetName = "SB_Cancel",Mandatory = $true,Position = 0)]
[byte[]]$SigningKeyCertificate,
[Parameter(ParameterSetName = "SF_Schedule",Mandatory = $false,Position = 3)]
[Parameter(ParameterSetName = "SF_Cancel",Mandatory = $false,Position = 3)]
[Parameter(ParameterSetName = "SB_Schedule",Mandatory = $false,Position = 3)]
[Parameter(ParameterSetName = "SB_Cancel",Mandatory = $false,Position = 3)]
[Parameter(ParameterSetName = "RemoteSigning_Schedule",Mandatory = $false,Position = 0)]
[Parameter(ParameterSetName = "RemoteSigning_Cancel",Mandatory = $false,Position = 0)]
[uint32]$Nonce = [math]::Floor([decimal](Get-Date (Get-Date).ToUniversalTime() -UFormat "%s").Replace(',','.')),
[Parameter(ParameterSetName = "SF_Schedule",Mandatory = $false,Position = 4)]
[Parameter(ParameterSetName = "SB_Schedule",Mandatory = $false,Position = 4)]
[Parameter(ParameterSetName = "RemoteSigning_Schedule",Mandatory = $false,Position = 1)]
[switch]$Set,
[Parameter(ParameterSetName = "SF_Cancel",Mandatory = $true,Position = 4)]
[Parameter(ParameterSetName = "SB_Cancel",Mandatory = $true,Position = 4)]
[Parameter(ParameterSetName = "RemoteSigning_Cancel",Mandatory = $true,Position = 1)]
[switch]$Cancel,
[Parameter(ParameterSetName = "SF_Schedule",Mandatory = $false,Position = 6)]
[Parameter(ParameterSetName = "SB_Schedule",Mandatory = $false,Position = 6)]
[Parameter(ParameterSetName = "RemoteSigning_Schedule",Mandatory = $false,Position = 2)]
[ValidateRange(1,7)]
[byte]$ForceAfterReboot = 1,
[Parameter(ParameterSetName = "SF_Schedule",Mandatory = $false,Position = 7)]
[Parameter(ParameterSetName = "SB_Schedule",Mandatory = $false,Position = 7)]
[Parameter(ParameterSetName = "RemoteSigning_Schedule",Mandatory = $false,Position = 3)]
[surerecover_prompt_policy]$PromptPolicy = "PromptBeforeRecovery,PromptOnError",
[Parameter(ParameterSetName = "SF_Schedule",Mandatory = $false,Position = 8)]
[Parameter(ParameterSetName = "SB_Schedule",Mandatory = $false,Position = 8)]
[Parameter(ParameterSetName = "RemoteSigning_Schedule",Mandatory = $false,Position = 4)]
[surerecover_erase_policy]$ErasePolicy = "None",
[Parameter(ParameterSetName = "SF_Schedule",Mandatory = $false,Position = 9)]
[Parameter(ParameterSetName = "SB_Schedule",Mandatory = $false,Position = 9)]
[Parameter(ParameterSetName = "SF_Cancel",Mandatory = $false,Position = 9)]
[Parameter(ParameterSetName = "SB_Cancel",Mandatory = $false,Position = 9)]
[Parameter(ParameterSetName = "RemoteSigning_Schedule",Mandatory = $false,Position = 5)]
[Parameter(ParameterSetName = "RemoteSigning_Cancel",Mandatory = $false,Position = 2)]
[System.IO.FileInfo]$OutputFile,
[Parameter(ParameterSetName = "RemoteSigning_Schedule",Mandatory = $true,Position = 6)]
[Parameter(ParameterSetName = "RemoteSigning_Cancel",Mandatory = $true,Position = 3)]
[string]$RemoteSigningServiceKeyID,
[Parameter(ParameterSetName = "RemoteSigning_Schedule",Mandatory = $true,Position = 7)]
[Parameter(ParameterSetName = "RemoteSigning_Cancel",Mandatory = $true,Position = 4)]
[string]$RemoteSigningServiceURL,
[Parameter(ParameterSetName = "RemoteSigning_Schedule",Mandatory = $false,Position = 8)]
[Parameter(ParameterSetName = "RemoteSigning_Cancel",Mandatory = $false,Position = 5)]
[switch]$CacheAccessToken
)
$data = New-Object -TypeName surerecover_trigger_payload_t
$data.arp_counter = $Nonce
$data.bios_trigger_flags = 0
$output = New-Object -TypeName PortableFileFormat
if ($Cancel.IsPresent)
{
Write-Verbose "Creating payload to cancel trigger"
$output.purpose = "hp:surerecover:trigger"
$data.bios_trigger_flags = 0
$data.re_trigger_flags = 0
}
else {
Write-Verbose ("Creating payload to set trigger")
$output.purpose = "hp:surerecover:trigger"
$data.bios_trigger_flags = [uint32]$ForceAfterReboot
$data.re_trigger_flags = [uint32]$PromptPolicy
$data.re_trigger_flags = ([uint32]$ErasePolicy -shl 4) -bor $data.re_trigger_flags
}
$cmd = New-Object -TypeName surerecover_trigger_t
$cmd.Data = $data
[byte[]]$payload = (Convert-HPPrivateObjectToBytes -obj $data -Verbose:$VerbosePreference)[0]
if ($PSCmdlet.ParameterSetName -eq "RemoteSigning_Schedule" -or $PSCmdlet.ParameterSetName -eq "RemoteSigning_Cancel") {
$cmd.sig = Invoke-HPPrivateRemoteSignData -Data $payload -CertificateId $RemoteSigningServiceKeyID -KMSUri $RemoteSigningServiceURL -CacheAccessToken:$CacheAccessToken -Verbose:$VerbosePreference
}
else {
$sk = Get-HPPrivateX509CertCoalesce -File $SigningKeyFile -password $SIgningKeyPassword -cert $SigningKeycertificate -Verbose:$VerbosePreference
$cmd.sig = Invoke-HPPrivateSignData -Data $payload -Certificate $sk.Full -Verbose:$VerbosePreference
}
Write-Verbose "Building output document with nonce $([BitConverter]::GetBytes($nonce))"
$output.Data = (Convert-HPPrivateObjectToBytes -obj $cmd -Verbose:$VerbosePreference)[0]
Write-Verbose "Sending document of size $($output.data.length)"
$output.timestamp = Get-Date
if ($OutputFile) {
Write-Verbose "Will output to file $OutputFile"
$f = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($OutputFile)
$output | ConvertTo-Json -Compress | Out-File -FilePath $f -Encoding utf8
}
else {
$output | ConvertTo-Json -Compress
}
}
<#
.SYNOPSIS
Invokes the WMI command to trigger the BIOS to perform a service event on the next boot
.DESCRIPTION
This command invokes the WMI command to trigger the BIOS to perform a service event on the next boot. If the hardware option is not present, this command will throw a NotSupportedException exception.
The BIOS will then compare SR_AED to HP_EAD and agent will compare SR_Image to HP_Image and update as necessary. The CloudRecovery.exe is the tool that performs the actual update.
.LINK
[Blog post: HP Secure Platform Management with the HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/hp-secure-platform-management-hp-client-management-script-library)
.LINK
[Blog post: Provisioning and Configuring HP Sure Recover with HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/provisioning-and-configuring-hp-sure-recover-hp-client-management-script-library)
.NOTES
- Requires HP BIOS with HP Sure Recover support
- Requires Embedded Reimaging device hardware option
.EXAMPLE
Invoke-HPSureRecoverTriggerUpdate
#>
function Invoke-HPSureRecoverTriggerUpdate
{
[CmdletBinding(HelpUri = "https://developers.hp.com/hp-client-management/doc/Invoke-HPSureRecoverTriggerUpdate")]
param()
$mi_result = 0
$cmd = '[DfmNativeSureRecover]::raise_surerecover_service_event_opaque' + (Test-OSBitness) + '($null, $null, [ref]$mi_result);'
$result = Invoke-Expression -Command $cmd
Test-HPPrivateCustomResult -result $result -mi_result $mi_result -Category 0x05
}
# SIG # Begin signature block
# MIIoHgYJKoZIhvcNAQcCoIIoDzCCKAsCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCQkiFCsZwSXYri
# RHyXXjE+2EaSRgip2+A0HDZ4e+ry/6CCDYowggawMIIEmKADAgECAhAIrUCyYNKc
# TJ9ezam9k67ZMA0GCSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK
# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNV
# BAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0yMTA0MjkwMDAwMDBaFw0z
# NjA0MjgyMzU5NTlaMGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwg
# SW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcg
# UlNBNDA5NiBTSEEzODQgMjAyMSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
# ggIKAoICAQDVtC9C0CiteLdd1TlZG7GIQvUzjOs9gZdwxbvEhSYwn6SOaNhc9es0
# JAfhS0/TeEP0F9ce2vnS1WcaUk8OoVf8iJnBkcyBAz5NcCRks43iCH00fUyAVxJr
# Q5qZ8sU7H/Lvy0daE6ZMswEgJfMQ04uy+wjwiuCdCcBlp/qYgEk1hz1RGeiQIXhF
# LqGfLOEYwhrMxe6TSXBCMo/7xuoc82VokaJNTIIRSFJo3hC9FFdd6BgTZcV/sk+F
# LEikVoQ11vkunKoAFdE3/hoGlMJ8yOobMubKwvSnowMOdKWvObarYBLj6Na59zHh
# 3K3kGKDYwSNHR7OhD26jq22YBoMbt2pnLdK9RBqSEIGPsDsJ18ebMlrC/2pgVItJ
# wZPt4bRc4G/rJvmM1bL5OBDm6s6R9b7T+2+TYTRcvJNFKIM2KmYoX7BzzosmJQay
# g9Rc9hUZTO1i4F4z8ujo7AqnsAMrkbI2eb73rQgedaZlzLvjSFDzd5Ea/ttQokbI
# YViY9XwCFjyDKK05huzUtw1T0PhH5nUwjewwk3YUpltLXXRhTT8SkXbev1jLchAp
# QfDVxW0mdmgRQRNYmtwmKwH0iU1Z23jPgUo+QEdfyYFQc4UQIyFZYIpkVMHMIRro
# OBl8ZhzNeDhFMJlP/2NPTLuqDQhTQXxYPUez+rbsjDIJAsxsPAxWEQIDAQABo4IB
# WTCCAVUwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUaDfg67Y7+F8Rhvv+
# YXsIiGX0TkIwHwYDVR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0P
# AQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMDMHcGCCsGAQUFBwEBBGswaTAk
# BggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAC
# hjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9v
# dEc0LmNydDBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5j
# b20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNybDAcBgNVHSAEFTATMAcGBWeBDAED
# MAgGBmeBDAEEATANBgkqhkiG9w0BAQwFAAOCAgEAOiNEPY0Idu6PvDqZ01bgAhql
# +Eg08yy25nRm95RysQDKr2wwJxMSnpBEn0v9nqN8JtU3vDpdSG2V1T9J9Ce7FoFF
# UP2cvbaF4HZ+N3HLIvdaqpDP9ZNq4+sg0dVQeYiaiorBtr2hSBh+3NiAGhEZGM1h
# mYFW9snjdufE5BtfQ/g+lP92OT2e1JnPSt0o618moZVYSNUa/tcnP/2Q0XaG3Ryw
# YFzzDaju4ImhvTnhOE7abrs2nfvlIVNaw8rpavGiPttDuDPITzgUkpn13c5Ubdld
# AhQfQDN8A+KVssIhdXNSy0bYxDQcoqVLjc1vdjcshT8azibpGL6QB7BDf5WIIIJw
# 8MzK7/0pNVwfiThV9zeKiwmhywvpMRr/LhlcOXHhvpynCgbWJme3kuZOX956rEnP
# LqR0kq3bPKSchh/jwVYbKyP/j7XqiHtwa+aguv06P0WmxOgWkVKLQcBIhEuWTatE
# QOON8BUozu3xGFYHKi8QxAwIZDwzj64ojDzLj4gLDb879M4ee47vtevLt/B3E+bn
# KD+sEq6lLyJsQfmCXBVmzGwOysWGw/YmMwwHS6DTBwJqakAwSEs0qFEgu60bhQji
# WQ1tygVQK+pKHJ6l/aCnHwZ05/LWUpD9r4VIIflXO7ScA+2GRfS0YW6/aOImYIbq
# yK+p/pQd52MbOoZWeE4wggbSMIIEuqADAgECAhAJvPMqSNxAYhV5FFpsbzOhMA0G
# CSqGSIb3DQEBCwUAMGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwg
# SW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcg
# UlNBNDA5NiBTSEEzODQgMjAyMSBDQTEwHhcNMjQwMjE1MDAwMDAwWhcNMjUwMjE4
# MjM1OTU5WjBaMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTESMBAG
# A1UEBxMJUGFsbyBBbHRvMRAwDgYDVQQKEwdIUCBJbmMuMRAwDgYDVQQDEwdIUCBJ
# bmMuMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEApbF6fMFy6zhGVra3
# SZN418Cp2O8kjihQCU9tqPO9tkzbMyTsgveLJVnXPJNG9kQPMGUNp+wEHcoUzlRc
# YJMEL9fhfzpWPeSIIezGLPCdrkMmS3fdRUwFqEs7z/C6Ui2ZqMaKhKjBJTIWnipe
# rRfzGB7RoLepQcgqeF5s0DBy4oG83dqcRHo3IJRTBg39tHe3mD5uoGHn5n366abX
# vC+k53BVyD8w8XLppFVH5XuNlXMq/Ohf613i7DRb/+u92ZiAPVPXXnlxUE26cuDb
# OfJKN/bXPmvnWcNW3YHVp9ztPTQZhX4yWYXHrAI2Cv6HxUpO6NzhFoRoBTkcYNbA
# 91pf1Vagh/MNcA2BfQYT975/Vlvj9cfEZ/NwZthZuHa3rdrvCKhhjw7YU2QUeaTJ
# 0uaX4g6B9PFNqAASYLach3CDJiLmYEfus/utPh57mk0q27yL25fXo/PaMDXiDNIi
# 7Wuz7A+sPsbtdiY8zvEIRQ+XJXtKAlD4tqG9YzlTO6ZoQX/rAgMBAAGjggIDMIIB
# /zAfBgNVHSMEGDAWgBRoN+Drtjv4XxGG+/5hewiIZfROQjAdBgNVHQ4EFgQURH4F
# u5yEAuElYWUbyGRYkNLLrA8wPgYDVR0gBDcwNTAzBgZngQwBBAEwKTAnBggrBgEF
# BQcCARYbaHR0cDovL3d3dy5kaWdpY2VydC5jb20vQ1BTMA4GA1UdDwEB/wQEAwIH
# gDATBgNVHSUEDDAKBggrBgEFBQcDAzCBtQYDVR0fBIGtMIGqMFOgUaBPhk1odHRw
# Oi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmlu
# Z1JTQTQwOTZTSEEzODQyMDIxQ0ExLmNybDBToFGgT4ZNaHR0cDovL2NybDQuZGln
# aWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0Q29kZVNpZ25pbmdSU0E0MDk2U0hB
# Mzg0MjAyMUNBMS5jcmwwgZQGCCsGAQUFBwEBBIGHMIGEMCQGCCsGAQUFBzABhhho
# dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wXAYIKwYBBQUHMAKGUGh0dHA6Ly9jYWNl
# cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNB
# NDA5NlNIQTM4NDIwMjFDQTEuY3J0MAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQAD
# ggIBAFiCyuI6qmaQodDyMNpp0l7eIXFgJ4JI59o59PleFj4rcyd/+F4iI7u5if8G
# rV5Kn3s3tK9vfJO8SpqtEh7lL4e69z6v3ohcy4uy2hsjKQ/fFcDo9pQYDGmDVjCa
# D5qSVEIBlJHBe5NKEJAgUE0kaMjLzbi2+8DKJlNtvZ+hatuPl9fMnmU+VbQh7JhZ
# yJdz8Ay0tcQ9lC8HAX5Ah/pU+Vtv+c8gMSxjS1aWXoGCa1869IVi2O6qx7MuX12U
# 1eIpB9XxYr7HSebvg2G7Gz6nCh7u+4k7m3hJu9EStUIN2JII5260+E60uDWoHEhx
# tHbdueFQxJrTKnhplOSaaPFCVBDkWG83ZzN9N3z/45w1pBUNBiPJdRQJ58MhBYQe
# Zl90heMBL8QNQk2i0E5gHNT9pJiCR9+mvJkRxEVgUn+16ZpVnI6kzhThV9qBaWVF
# h83X4UWc/nwHKIuu+4x4fmkYc79A3MrsHflZIO8jOy0GC/xBnZTQ8s5b9Tb2UkHk
# w692Ypl7War3W7M37JCAPC/A7M4CwQYjdjG43zs5m36auYVaTvRLKtZVLzcj8oZX
# 4vqhlZ8+jCPXFiuDfoBXiTckTLpv/eHQ6q7Aoda+qARWPPE1U2v5r/lpKVqIx7B4
# PdFZAUf5MtG/Bj7LVXvXjW8ABIJv7L4cI2akn6Es0dmvd6PsMYIZ6jCCGeYCAQEw
# fTBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNV
# BAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgQ29kZSBTaWduaW5nIFJTQTQwOTYgU0hB
# Mzg0IDIwMjEgQ0ExAhAJvPMqSNxAYhV5FFpsbzOhMA0GCWCGSAFlAwQCAQUAoHww
# EAYKKwYBBAGCNwIBDDECMAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYK
# KwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIK7rSRA2
# OYEjdWGHpMD20gxTgU0u0wedJEYSyxdL23pRMA0GCSqGSIb3DQEBAQUABIIBgIV9
# 4Y6nlq6OXMQ0GJkw9b3r1Az3NKSXu2FRFMEb7ZfVfB/HS2b4Ij9O8yFUFQtp4Drd
# BPdVctRbntFE/hxV1S4oGhHz5QP/L/8+1KKEDmSCjsVRhd2Y4g2BPqQsX8tESDz9
# 00y8UEGlAyBQPltIj/MqmlwUUNMcak3tHljoeoiH7pu5ksZL/P5lRtCkK8TeqCIB
# sYqviy4Gn7PDjZvWpFhsw4fQSSqHgID9fYWbPuFyODjmrWYx8t7b4Uc3jgZzCmPr
# x2tzMH5ZX2V8SDB37hhNajHgC/dJ95Bl2Rc2Su/4+puQr77lOXjw/Y/kuooAmrIk
# u+0OldvIZxFep2gwOLzlEPeKkg6y5LBjg7uee/P7YIXND/CFPw8wEVe6Y7TwEmlS
# ced8Bt06dHHTYn0zLRG/ATKRFcYuNlN3slgX85Ceelcl7cXmXhtiJahfizXdGugv
# Bjta6CFbM0S8Z/IZalXX4wj1fZJOzZ0pb1AY/mangTE0htBiz6gQxVGhYOAYzaGC
# F0Awghc8BgorBgEEAYI3AwMBMYIXLDCCFygGCSqGSIb3DQEHAqCCFxkwghcVAgED
# MQ8wDQYJYIZIAWUDBAIBBQAweAYLKoZIhvcNAQkQAQSgaQRnMGUCAQEGCWCGSAGG
# /WwHATAxMA0GCWCGSAFlAwQCAQUABCD3n4+oF0eKlg2EtGPVyYW9MS1eiHYcOOmG
# FC6dB2FjYAIRANdyh1JGOO/ufeQTocv57rQYDzIwMjQwODI3MTY1NTUwWqCCEwkw
# ggbCMIIEqqADAgECAhAFRK/zlJ0IOaa/2z9f5WEWMA0GCSqGSIb3DQEBCwUAMGMx
# CzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMy
# RGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcg
# Q0EwHhcNMjMwNzE0MDAwMDAwWhcNMzQxMDEzMjM1OTU5WjBIMQswCQYDVQQGEwJV
# UzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xIDAeBgNVBAMTF0RpZ2lDZXJ0IFRp
# bWVzdGFtcCAyMDIzMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAo1NF
# hx2DjlusPlSzI+DPn9fl0uddoQ4J3C9Io5d6OyqcZ9xiFVjBqZMRp82qsmrdECmK
# HmJjadNYnDVxvzqX65RQjxwg6seaOy+WZuNp52n+W8PWKyAcwZeUtKVQgfLPywem
# MGjKg0La/H8JJJSkghraarrYO8pd3hkYhftF6g1hbJ3+cV7EBpo88MUueQ8bZlLj
# yNY+X9pD04T10Mf2SC1eRXWWdf7dEKEbg8G45lKVtUfXeCk5a+B4WZfjRCtK1ZXO
# 7wgX6oJkTf8j48qG7rSkIWRw69XloNpjsy7pBe6q9iT1HbybHLK3X9/w7nZ9MZll
# R1WdSiQvrCuXvp/k/XtzPjLuUjT71Lvr1KAsNJvj3m5kGQc3AZEPHLVRzapMZoOI
# aGK7vEEbeBlt5NkP4FhB+9ixLOFRr7StFQYU6mIIE9NpHnxkTZ0P387RXoyqq1AV
# ybPKvNfEO2hEo6U7Qv1zfe7dCv95NBB+plwKWEwAPoVpdceDZNZ1zY8SdlalJPrX
# xGshuugfNJgvOuprAbD3+yqG7HtSOKmYCaFxsmxxrz64b5bV4RAT/mFHCoz+8LbH
# 1cfebCTwv0KCyqBxPZySkwS0aXAnDU+3tTbRyV8IpHCj7ArxES5k4MsiK8rxKBMh
# SVF+BmbTO77665E42FEHypS34lCh8zrTioPLQHsCAwEAAaOCAYswggGHMA4GA1Ud
# DwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMI
# MCAGA1UdIAQZMBcwCAYGZ4EMAQQCMAsGCWCGSAGG/WwHATAfBgNVHSMEGDAWgBS6
# FtltTYUvcyl2mi91jGogj57IbzAdBgNVHQ4EFgQUpbbvE+fvzdBkodVWqWUxo97V
# 40kwWgYDVR0fBFMwUTBPoE2gS4ZJaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0Rp
# Z2lDZXJ0VHJ1c3RlZEc0UlNBNDA5NlNIQTI1NlRpbWVTdGFtcGluZ0NBLmNybDCB
# kAYIKwYBBQUHAQEEgYMwgYAwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2lj
# ZXJ0LmNvbTBYBggrBgEFBQcwAoZMaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29t
# L0RpZ2lDZXJ0VHJ1c3RlZEc0UlNBNDA5NlNIQTI1NlRpbWVTdGFtcGluZ0NBLmNy
# dDANBgkqhkiG9w0BAQsFAAOCAgEAgRrW3qCptZgXvHCNT4o8aJzYJf/LLOTN6l0i
# kuyMIgKpuM+AqNnn48XtJoKKcS8Y3U623mzX4WCcK+3tPUiOuGu6fF29wmE3aEl3
# o+uQqhLXJ4Xzjh6S2sJAOJ9dyKAuJXglnSoFeoQpmLZXeY/bJlYrsPOnvTcM2Jh2
# T1a5UsK2nTipgedtQVyMadG5K8TGe8+c+njikxp2oml101DkRBK+IA2eqUTQ+OVJ
# dwhaIcW0z5iVGlS6ubzBaRm6zxbygzc0brBBJt3eWpdPM43UjXd9dUWhpVgmagNF
# 3tlQtVCMr1a9TMXhRsUo063nQwBw3syYnhmJA+rUkTfvTVLzyWAhxFZH7doRS4wy
# w4jmWOK22z75X7BC1o/jF5HRqsBV44a/rCcsQdCaM0qoNtS5cpZ+l3k4SF/Kwtw9
# Mt911jZnWon49qfH5U81PAC9vpwqbHkB3NpE5jreODsHXjlY9HxzMVWggBHLFAx+
# rrz+pOt5Zapo1iLKO+uagjVXKBbLafIymrLS2Dq4sUaGa7oX/cR3bBVsrquvczro
# SUa31X/MtjjA2Owc9bahuEMs305MfR5ocMB3CtQC4Fxguyj/OOVSWtasFyIjTvTs
# 0xf7UGv/B3cfcZdEQcm4RtNsMnxYL2dHZeUbc7aZ+WssBkbvQR7w8F/g29mtkIBE
# r4AQQYowggauMIIElqADAgECAhAHNje3JFR82Ees/ShmKl5bMA0GCSqGSIb3DQEB
# CwUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNV
# BAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQg
# Um9vdCBHNDAeFw0yMjAzMjMwMDAwMDBaFw0zNzAzMjIyMzU5NTlaMGMxCzAJBgNV
# BAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNl
# cnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0EwggIi
# MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDGhjUGSbPBPXJJUVXHJQPE8pE3
# qZdRodbSg9GeTKJtoLDMg/la9hGhRBVCX6SI82j6ffOciQt/nR+eDzMfUBMLJnOW
# bfhXqAJ9/UO0hNoR8XOxs+4rgISKIhjf69o9xBd/qxkrPkLcZ47qUT3w1lbU5ygt
# 69OxtXXnHwZljZQp09nsad/ZkIdGAHvbREGJ3HxqV3rwN3mfXazL6IRktFLydkf3
# YYMZ3V+0VAshaG43IbtArF+y3kp9zvU5EmfvDqVjbOSmxR3NNg1c1eYbqMFkdECn
# wHLFuk4fsbVYTXn+149zk6wsOeKlSNbwsDETqVcplicu9Yemj052FVUmcJgmf6Aa
# RyBD40NjgHt1biclkJg6OBGz9vae5jtb7IHeIhTZgirHkr+g3uM+onP65x9abJTy
# UpURK1h0QCirc0PO30qhHGs4xSnzyqqWc0Jon7ZGs506o9UD4L/wojzKQtwYSH8U
# NM/STKvvmz3+DrhkKvp1KCRB7UK/BZxmSVJQ9FHzNklNiyDSLFc1eSuo80VgvCON
# WPfcYd6T/jnA+bIwpUzX6ZhKWD7TA4j+s4/TXkt2ElGTyYwMO1uKIqjBJgj5FBAS
# A31fI7tk42PgpuE+9sJ0sj8eCXbsq11GdeJgo1gJASgADoRU7s7pXcheMBK9Rp61
# 03a50g5rmQzSM7TNsQIDAQABo4IBXTCCAVkwEgYDVR0TAQH/BAgwBgEB/wIBADAd
# BgNVHQ4EFgQUuhbZbU2FL3MpdpovdYxqII+eyG8wHwYDVR0jBBgwFoAU7NfjgtJx
# XWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUF
# BwMIMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGln
# aWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5j
# b20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNVHR8EPDA6MDigNqA0hjJo
# dHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNy
# bDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwDQYJKoZIhvcNAQEL
# BQADggIBAH1ZjsCTtm+YqUQiAX5m1tghQuGwGC4QTRPPMFPOvxj7x1Bd4ksp+3CK
# Daopafxpwc8dB+k+YMjYC+VcW9dth/qEICU0MWfNthKWb8RQTGIdDAiCqBa9qVbP
# FXONASIlzpVpP0d3+3J0FNf/q0+KLHqrhc1DX+1gtqpPkWaeLJ7giqzl/Yy8ZCaH
# bJK9nXzQcAp876i8dU+6WvepELJd6f8oVInw1YpxdmXazPByoyP6wCeCRK6ZJxur
# JB4mwbfeKuv2nrF5mYGjVoarCkXJ38SNoOeY+/umnXKvxMfBwWpx2cYTgAnEtp/N
# h4cku0+jSbl3ZpHxcpzpSwJSpzd+k1OsOx0ISQ+UzTl63f8lY5knLD0/a6fxZsNB
# zU+2QJshIUDQtxMkzdwdeDrknq3lNHGS1yZr5Dhzq6YBT70/O3itTK37xJV77Qpf
# MzmHQXh6OOmc4d0j/R0o08f56PGYX/sr2H7yRp11LB4nLCbbbxV7HhmLNriT1Oby
# F5lZynDwN7+YAN8gFk8n+2BnFqFmut1VwDophrCYoCvtlUG3OtUVmDG0YgkPCr2B
# 2RP+v6TR81fZvAT6gt4y3wSJ8ADNXcL50CN/AAvkdgIm2fBldkKmKYcJRyvmfxqk
# hQ/8mJb2VVQrH4D6wPIOK+XW+6kvRBVK5xMOHds3OBqhK/bt1nz8MIIFjTCCBHWg
# AwIBAgIQDpsYjvnQLefv21DiCEAYWjANBgkqhkiG9w0BAQwFADBlMQswCQYDVQQG
# EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
# cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcN
# MjIwODAxMDAwMDAwWhcNMzExMTA5MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEVMBMG
# A1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEw
# HwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqGSIb3DQEB
# AQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3yithZwuEp
# pz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1Ifxp4VpX6+
# n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDVySAdYykt
# zuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiODCu3T6cw
# 2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQjdjUN6Qu
# BX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/CNdaSaTC
# 5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCiEhtmmnTK
# 3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADMfRyVw4/3
# IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QYuKZ3AeEP
# lAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXKchYiCd98
# THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t9dmpsh3l
# GwIDAQABo4IBOjCCATYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU7NfjgtJx
# XWRM3y5nP+e6mK4cD08wHwYDVR0jBBgwFoAUReuir/SSy4IxLVGLp6chnfNtyA8w
# DgYDVR0PAQH/BAQDAgGGMHkGCCsGAQUFBwEBBG0wazAkBggrBgEFBQcwAYYYaHR0
# cDovL29jc3AuZGlnaWNlcnQuY29tMEMGCCsGAQUFBzAChjdodHRwOi8vY2FjZXJ0
# cy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3J0MEUGA1Ud
# HwQ+MDwwOqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFz
# c3VyZWRJRFJvb3RDQS5jcmwwEQYDVR0gBAowCDAGBgRVHSAAMA0GCSqGSIb3DQEB
# DAUAA4IBAQBwoL9DXFXnOF+go3QbPbYW1/e/Vwe9mqyhhyzshV6pGrsi+IcaaVQi
# 7aSId229GhT0E0p6Ly23OO/0/4C5+KH38nLeJLxSA8hO0Cre+i1Wz/n096wwepqL
# sl7Uz9FDRJtDIeuWcqFItJnLnU+nBgMTdydE1Od/6Fmo8L8vC6bp8jQ87PcDx4eo
# 0kxAGTVGamlUsLihVo7spNU96LHc/RzY9HdaXFSMb++hUD38dglohJ9vytsgjTVg
# HAIDyyCwrFigDkBjxZgiwbJZ9VVrzyerbHbObyMt9H5xaiNrIv8SuFQtJ37YOtnw
# toeW/VvRXKwYw02fc7cBqZ9Xql4o4rmUMYIDdjCCA3ICAQEwdzBjMQswCQYDVQQG
# EwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0
# IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYgVGltZVN0YW1waW5nIENBAhAFRK/z
# lJ0IOaa/2z9f5WEWMA0GCWCGSAFlAwQCAQUAoIHRMBoGCSqGSIb3DQEJAzENBgsq
# hkiG9w0BCRABBDAcBgkqhkiG9w0BCQUxDxcNMjQwODI3MTY1NTUwWjArBgsqhkiG
# 9w0BCRACDDEcMBowGDAWBBRm8CsywsLJD4JdzqqKycZPGZzPQDAvBgkqhkiG9w0B
# CQQxIgQg1dYmgcj7iRfy+0HoNy8nbKUTVV6TPw8wA/XxDZtua4IwNwYLKoZIhvcN
# AQkQAi8xKDAmMCQwIgQg0vbkbe10IszR1EBXaEE2b4KK2lWarjMWr00amtQMeCgw
# DQYJKoZIhvcNAQEBBQAEggIAdw19FK5nVPiEAbol+u+DMqD0l3sJ7ml2/e4bukwY
# fUT03GT83uQrLRTUThwaX3kuCKX2it0UmX8eJ/tsb1cFRfHOE9SFnqYJQ9Dggf68
# 2ekbPuohIrJqs6PenIuCMcmZPB/MSn9Xr2wgKyWBr4mT3q9Ap+r2xcN+3w0RUEaR
# twaVBq8/5LgZ1rXHuN1MAPqWR3wTecCE2bdS4YRT3R3XQFXmnJsnEan+3k4MTyBL
# fppdWxrmmCENyZY4ENRsep66ZAqX+7TMowZp4OHru5tEtwERl8EzmvzMmsGfYH9S
# 3MT3hJVz79QSnnhf9fihtVFFObtv1llaOEwmG8a5rKt2dBpTjjItjs9dPag3zwND
# zWjbrJ1QDwuRIOe2leT98hNjPNqWRrTt9Py31cJd0LjxxJ2Mv/KKm7mNgykzcIgX
# mzcmhEv9ckrBuLAb+uYY8sUrBvU+DR/UlqjI1vCW3hEOmAn05VT2xD2AH8iMZHwB
# m3VsR1hW7JGEIHcNz8POWG72Vi0ESdav5OCItc55k191Q4P765/Z74idMGLqBr6e
# fMFNOV16srKAhxDyAx9HC4Jxci420DU9D+1X9C1m/TO9vR7kyysqhsWmLZbEgkBn
# frwwrfU9474/pxCR+U+5QbbCXjjskN7gO1z2SHBtj1ZBxc6X6MMzDJkXBA/T7GKU
# rFE=
# SIG # End signature block