AzStackHciSBEHealth/AzStackHci.SBEHealth.psm1
<#############################################################
# # # Copyright (C) Microsoft Corporation. All rights reserved. # # # #############################################################> Import-Module $PSScriptRoot\AzStackHci.SBEHealth.Helpers.psm1 -Force -DisableNameChecking -Global Import-Module $PSScriptRoot\..\AzStackHci.EnvironmentChecker.Utilities.psm1 -Force -DisableNameChecking -Global Import-Module $PSScriptRoot\..\AzStackHci.EnvironmentChecker.Reporting.psm1 -Force -DisableNameChecking -Global Import-LocalizedData -BindingVariable lhwTxt -FileName AzStackHci.SBEHealth.Strings.psd1 function Invoke-AzStackHciSBEHealthValidation { <# .SYNOPSIS Perform AzStackHci SBE Health validation .DESCRIPTION Perform AzStackHci SBE Health validation .EXAMPLE PS C:\> Invoke-AzStackHciSBEHealthValidation -SBESourcePath "C:\SBE" Perform SBE Health validations on localhost .EXAMPLE PS C:\> $Credential = Get-Credential -Message "Credential for RemoteSystem" PS C:\> $RemoteSystemSession = New-PSSession -Computer 10.0.0.4,10.0.0.5 -Credential $Credential PS C:\> Invoke-AzStackHciSBEHealthValidation -SBESourcePath "C:\SBE" -PsSession $RemoteSystemSession Perform SBE Health validations on the localhost and all specified remote PS sessions .PARAMETER PsSession Specify the PsSession(s) used to validation from .PARAMETER Tag Specify the Tag value to be passed to the SolutionExtension module when called .PARAMETER SBESourcePath Specify the full local path to the folder containing the extracted SBE Package .PARAMETER SBEMetadataPath Specify the full local path to the folder containing the SBE Metadata files .PARAMETER PassThru Return PSObject result .PARAMETER OutputPath Directory path for log and report output .PARAMETER CleanReport Remove all previous progress and create a clean report .INPUTS Inputs (if any) .OUTPUTS Output (if any) #> [CmdletBinding()] param ( [Parameter(Mandatory = $false, HelpMessage = "Specify the PsSession(s) used to validation from. If null the local machine will be used.")] [System.Management.Automation.Runspaces.PSSession[]] $PsSession, [Parameter(Mandatory = $false, HelpMessage = "Tag to pass to SolutionExtension module functions.")] [string] $Tag = "Deployment", [Parameter(Mandatory = $true, HelpMessage = "Local path to the folder containing the extracted SBE Package.")] [string] $SBESourcePath, [Parameter(Mandatory = $true, HelpMessage = "Local path to the folder containing the SBE metadata file.")] [string] $SBEMetadataPath, [Parameter(Mandatory = $true, HelpMessage = "Version of the SBE package to use for validation interfaces.")] [string] $SBEVersion, [Parameter(Mandatory = $false, HelpMessage = "Return PSObject result.")] [switch] $PassThru, [Parameter(Mandatory = $false, HelpMessage = "Hardware class: Small, Medium, or Large")] [ValidateSet('Small','Medium','Large')] [String] $HardwareClass = "Medium", [Parameter(Mandatory = $false, HelpMessage = "Directory path for log and report output")] [string]$OutputPath, [Parameter(Mandatory = $false, HelpMessage = "Remove all previous progress and create a clean report")] [switch]$CleanReport = $false, [Parameter(Mandatory = $false, HelpMessage = "Show only failed results on screen.")] [switch]$ShowFailedOnly, [Parameter(Mandatory = $false, HelpMessage = "Skip the SBE file integrity test.")] [switch]$SkipIntegrityTest, [Parameter(Mandatory = $true, HelpMessage = "ECE Params")] [CloudEngine.Configurations.EceInterfaceParameters]$ECEParameters ) try { $script:ErrorActionPreference = 'Stop' Set-AzStackHciOutputPath -Path $OutputPath $allResult = @() Write-AzStackHciHeader -Invocation $MyInvocation -Params $PSBoundParameters -PassThru:$PassThru # Use the SBE role defined local cache path $templatedLocalSBEPath = $ECEParameters.Roles["SBE"].PublicConfiguration.PublicInfo.SBEContentPaths.SBELocalPath $defaultLocalShare = $ECEParameters.Roles["Cloud"].PublicConfiguration.PublicInfo.DefaultInfraStorageLocations.DefaultLocalShare if ($null -eq $defaultLocalShare) { $defaultLocalShare = "D:" Trace-Execution "Older build - using hardcoded path '$defaultLocalShare' to defaultLocalShare" } $sbeLocalPath = $templatedLocalSBEPath.Replace('{DefaultLocalShare}', $defaultLocalShare.TrimEnd('\')) $cacheBase = Join-Path -Path $sbeLocalPath -ChildPath $ECEParameters.Roles["SBE"].PublicConfiguration.PublicInfo.SBEContentPaths.RelativePaths.LocalSBECachePath $sbeWorkingDir = Join-Path -Path $cacheBase -ChildPath $SBEVersion Log-Info -Message "Using '$sbeWorkingDir' to cache SBE content locally." $excludeFromContent = @() if ($SBESourcePath -eq $SBEMetadataPath) { # The update service combines the content and metadata together $sbeMetadataFiles = (Get-ChildItem -Path $SBESourcePath | Where-Object {$PSItem.Name -like "SBE*.xml" -or $PSItem.Name -eq "oemMetadata.xml"}) $sbeZip = Get-ChildItem -Path $SBESourcePath -Filter "SBE*.zip" [array]$excludeFromContent = [array]$sbeMetadataFiles.Name + $sbeZip.Name Log-Info -Message ("Will exclude the following files from local SBE content cache: " + ($excludeFromContent -Join ", " | Out-String)) } Test-ModuleUpdate -PassThru:$PassThru # Call/Initialise reporting $envcheckerReport = Get-AzStackHciEnvProgress -Clean:$CleanReport $envcheckerReport = Add-AzStackHciEnvJob -Report $envcheckerReport Log-Info -Message ("Check partner properties in unattended.json match SBE manifest") -Type Info try { $result = Test-SBEPropertiesValid -ECEParameters $ECEParameters } catch { Log-Info -Message "Error validating partner properties in unattended.json with SBE manifest" -Type Error -ConsoleOut Log-Info -Message ("The exception message was: $($PSItem.Exception.Message)") -Type Error -ConsoleOut $exceptionResult = New-SBEHealthResultObject -TestName 'Test-SBEPropertiesValid' -TargetName $env:ComputerName -Status 'FAILURE' -Severity 'CRITICAL' -Description "Validate partner properties in unattended.json" $detailedMessage = "Found invalid partnerProperties in unattended.json. $($PSItem.Exception.Message)" $exceptionResult.Remediation = "Fix PartnerProperties to be compliant with the JSON schema in the <PartnerProperties> element of the SBE manifest located at c:\SBE\SBE_Discovery*.xml." $exceptionResult.AdditionalData.Detail = $detailedMessage $allResult += $exceptionResult throw $detailedMessage } Log-Info -Message ("Check SBE credentials in secret store match SBE manifest") -Type Info try { $result = Test-SBECredentialsValid -ECEParameters $ECEParameters } catch { Log-Info -Message "Error validating SBE credentials in secret store with SBE manifest" -Type Error -ConsoleOut Log-Info -Message ("The exception message was: $($PSItem.Exception.Message)") -Type Error -ConsoleOut $exceptionResult = New-SBEHealthResultObject -TestName 'Test-SBECredentialsValid' -TargetName $env:ComputerName -Status 'FAILURE' -Severity 'CRITICAL' -Description "Validate SBE credentials in secret store" $detailedMessage = "Found invalid SBE Credentials in secret store. $($PSItem.Exception.Message)" $exceptionResult.Remediation = "Correct issues with the indicated secrets in the Key Vault associated with this cluster and restart your deployment." $exceptionResult.AdditionalData.Detail = $detailedMessage $allResult += $exceptionResult throw $detailedMessage } # Pre-validation checks and preparation Log-Info -Message ("Validate the SolutionExtension module is present and meets the requirements for health testing.") -Type Info try { $result = Test-SolutionExtensionModule -PackagePath $SBESourcePath if ($false -eq $result) { $detailedMessage = "Skipping as the provided SolutionExtension module has not implemented any tests or does not support the HealthServiceIntegration tag." Log-Info -Message $detailedMessage -Type Info $instanceResult = New-SBEHealthResultObject -TestName 'Test-SolutionExtensionModule' -TargetName $env:ComputerName -Status 'SUCCESS' -Description "Validate SolutionExtension module exists and supports health tests" $instanceResult.AdditionalData.Detail = $detailedMessage $allResult += $instanceResult return $allResult } } catch { Log-Info -Message "The SolutionExtension module could not be validated" -Type Error -ConsoleOut Log-Info -Message ("The exception message was: $($PSItem.Exception.Message)") -Type Error -ConsoleOut $exceptionResult = New-SBEHealthResultObject -TestName 'Test-SolutionExtensionModule' -TargetName $env:ComputerName -Status 'FAILURE' -Severity 'CRITICAL' -Description "Validate SolutionExtension module exists and supports health tests" $detailedMessage = "The SolutionExtension module could not be validated. $($PSItem.Exception.Message)" $exceptionResult.Remediation = "https://learn.microsoft.com/en-us/azure-stack/hci/deploy/deployment-tool-troubleshoot#rerun-deployment" $exceptionResult.AdditionalData.Detail = $detailedMessage $allResult += $exceptionResult throw $detailedMessage } # Copy SBE package to local working dir try { $result = Copy-SBEContentLocalToNode -PackagePath $SBESourcePath -SkipNugetCopy:($Tag -ne 'Deployment') -TargetNodeName $env:ComputerName -ExcludeDirs @("IntegratedContent") -ExcludeFiles $excludeFromContent -DestPath $sbeWorkingDir if ($false -eq $result) { throw "An error occurred during the SBE package copy operation. See logs for details." } } catch { Log-Info -Message "An error occurred during the SBE package copy operation" -Type Error -ConsoleOut Log-Info -Message ("The exception message was: $($PSItem.Exception.Message)") -Type Error -ConsoleOut $detailedMessage = $PSItem.Exception.Message $exceptionResult = New-SBEHealthResultObject -TestName 'Copy-SBEContentLocalToNode' -TargetName $env:ComputerName -Status 'FAILURE' -Severity 'CRITICAL' -Description "Copy the SBE Package to working folder on '$($env:ComputerName)'" $exceptionResult.Remediation = "https://learn.microsoft.com/en-us/azure-stack/hci/deploy/deployment-tool-troubleshoot#rerun-deployment" $exceptionResult.AdditionalData.Detail = $detailedMessage $allResult += $exceptionResult throw $detailedMessage } # Validate SBE content integrity of working dir try { if (-not $SkipIntegrityTest) { $result = Invoke-TestSBEContentIntegrity -SBEMetadataPath $SBEMetadataPath -SBEContentPath $sbeWorkingDir if ($false -eq $result) { throw "SBE content integrity check found irregularities in the files at '$($sbeWorkingDir)'. Check the ECE logs for more information." } } } catch { $detailedMessage = "SBE content failed integrity check at '$($sbeWorkingDir)'" Log-Info -Message $detailedMessage -Type Error -ConsoleOut Log-Info -Message ("The exception message was: $($PSItem.Exception.Message)") -Type Error -ConsoleOut $exceptionResult = New-SBEHealthResultObject -TestName 'Test-SBEContentIntegrity' -TargetName $env:ComputerName -Status 'FAILURE' -Severity 'CRITICAL' -Description "Validate SBE content integrity" $exceptionResult.Remediation = "https://learn.microsoft.com/en-us/azure-stack/hci/deploy/deployment-tool-troubleshoot#rerun-deployment" $exceptionResult.AdditionalData.Detail = $detailedMessage $allResult += $exceptionResult throw $detailedMessage } # Import the SolutionExtension module try { $result = Import-SolutionExtensionModule -PackagePath $sbeWorkingDir } catch { $detailedMessage = "Import SolutionExtension module from '$($sbeWorkingDir)' failed. The exception was: $($PSItem.Exception.Message)" Log-Info -Message "Import SolutionExtension module from '$($sbeWorkingDir)' failed." -Type Error -ConsoleOut Log-Info -Message ("The exception message was: $($PSItem.Exception.Message)") -Type Error -ConsoleOut $exceptionResult = New-SBEHealthResultObject -TestName 'Import-SolutionExtensionModule' -TargetName $env:ComputerName -Status 'FAILURE' -Severity 'CRITICAL' -Description "Import SolutionExtension module" $exceptionResult.Remediation = "https://learn.microsoft.com/en-us/azure-stack/hci/deploy/deployment-tool-troubleshoot#rerun-deployment" $exceptionResult.AdditionalData.Detail = $detailedMessage $allResult += $exceptionResult throw $detailedMessage } # Run validation try { $functionName = 'Get-SBEHealthCheckResult' $exceptionResult = $null $instanceResult = @() $functionFound = Get-Command -Module SolutionExtension -Name $functionName -ErrorAction SilentlyContinue if ($null -eq $functionFound) { $detailedMessage = "A function named '$($functionName)' was not found in the SolutionExtension module." Log-Info -Message $detailedMessage -Type Error -ConsoleOut $thisResult = New-SBEHealthResultObject -TestName $functionName -TargetName $env:ComputerName -Status 'FAILURE' -Severity 'CRITICAL' -Description "Invoke $functionName" $thisResult.AdditionalData.Detail = $detailedMessage $instanceResult += $thisResult } else { $solExtVersion = $functionFound.Version.ToString() Log-Info -Message "SolutionExtension version being used: $solExtVersion" -Type Info $params = Get-SBEHealthCheckParams -ECEParameters $ECEParameters -Tag $Tag Log-Info -Message "Invoke $functionName on $($env:ComputerName)" -Type Info [array]$thisResult = & $functionName @params if ($thisResult.Count -eq 0) { Log-Info -Message "'$($functionName)' did not return any test results or no tests have been implemented." -Type Warning $detailedMessage = "'$($functionName)' did not return any test results or no tests have been implemented." $thisResult = New-SBEHealthResultObject -TestName $functionName -TargetName $env:ComputerName -Status 'FAILURE' -Description "Received health check results from $functionName" $thisResult.AdditionalData.Detail = $detailedMessage $instanceResult += $thisResult } else { [array]$assertResult = Assert-ResponseSchemaValid -ResultObject $thisResult if ($assertResult.Count -gt 0) { $instanceResult += $assertResult } } } } catch { # Unexpected exception occurred during partner tests Log-Info -Message "An error occurred during '$($functionName)'" -Type Error -ConsoleOut Log-Info -Message ("The exception message was: $($PSItem.Exception.Message)") -Type Error -ConsoleOut $exceptionResult = New-SBEHealthResultObject -TestName $functionName -TargetName $env:ComputerName -Status 'FAILURE' -Severity 'CRITICAL' -Description "$functionName on $($env:ComputerName)" $exceptionResult.Remediation = "https://learn.microsoft.com/en-us/azure-stack/hci/deploy/deployment-tool-troubleshoot#rerun-deployment" $exceptionResult.AdditionalData.Detail = "An unhandled error occurred: " + ($PSItem | Format-List * | Out-String).Trim() $instanceResult += $exceptionResult $allResult += $instanceResult throw $PSItem } finally { Log-Info -Message "Before adding $($functionName) instances... all count = $($allResult.Count) / instance count = $($instanceResult.Count))" if ($null -ne $instanceResult) { $allResult += $instanceResult } } try { $jobRun = @() $exceptionResult = $null $instanceResult = @() $functionName = 'Get-SBEHealthCheckResultOnNode' $functionFound = Get-Command -Module SolutionExtension -Name $functionName -ErrorAction SilentlyContinue if ($null -eq $functionFound) { # NOTE: The only way this could fail if the SBE was tampered with $detailedMessage = "A function named '$($functionName)' was not found in the SolutionExtension module." Log-Info -Message $detailedMessage -Type Error -ConsoleOut $exceptionResult = New-SBEHealthResultObject -TestName $functionName -TargetName $env:ComputerName -Status 'FAILURE' -Severity 'CRITICAL' -Description "Invoke $functionName" $exceptionResult.Remediation = $detailedMessage + " Please contact product support." $exceptionResult.AdditionalData.Detail = $detailedMessage $allResult += $exceptionResult throw $detailedMessage } else { if ($null -eq $params) { $params = Get-SBEHealthCheckParams -ECEParameters $ECEParameters -Tag $Tag } foreach ($session in $PsSession) { try { $result = Copy-SBEContentToSession -PackagePath $SBESourcePath -SkipNugetCopy:($Tag -ne 'Deployment') -Session $session -ExcludeDirs @("IntegratedContent") -ExcludeFiles $excludeFromContent -DestPath $sbeWorkingDir if ($false -eq $result) { Log-Info -Message "File copy via PsSession to '$($session.ComputerName)' failed. Will try copy to this node via PsDrive." $thisCred = $session.Runspace.ConnectionInfo.Credential $result = Copy-SBEContentLocalToNode -PackagePath $SBESourcePath -SkipNugetCopy:($Tag -ne 'Deployment') -TargetNodeName ($session.ComputerName) -ExcludeDirs @("IntegratedContent") -ExcludeFiles $excludeFromContent -Credential $thisCred -DestPath $sbeWorkingDir if ($false -eq $result) { throw "An error occurred during the SBE package copy operation to '$($session.ComputerName)'. See logs for details." } } } catch { Log-Info -Message "An unhandled error occurred during 'Copy-SBEContentLocalToNode' to '$($session.ComputerName)'" -Type Error -ConsoleOut Log-Info -Message ("The exception message was: $($PSItem.Exception.Message)") -Type Error -ConsoleOut $detailedMessage = $PSItem.Exception.Message $exceptionResult = New-SBEHealthResultObject -TestName $functionName -TargetName $session.ComputerName -Status 'FAILURE' -Severity 'CRITICAL' -Description "Copy-SBEContentLocalToNode to '$($session.ComputerName)'" $exceptionResult.AdditionalData.Detail = $detailedMessage $allResult += $exceptionResult throw $detailedMessage } } try { foreach ($session in $PsSession) { # Verify SBE content integrity if (-not $SkipIntegrityTest) { $result = Invoke-TestSBEContentIntegrity -SBEMetadataPath $SBEMetadataPath -SBEContentPath $sbeWorkingDir -PsSession $session if ($false -eq $result) { throw "SBE content integrity check found irregularities in the files at '$($sbeWorkingDir)' on '$($session.ComputerName)'" } } # Import the SolutionExtension module $result = Import-SolutionExtensionModule -PackagePath $sbeWorkingDir -PsSession $session Log-Info -Message "Invoke $functionName on '$($session.ComputerName)'" -Type Info $sbJob = { if ($null -eq $functionName) { $functionName = $using:functionName } if ($null -eq $params) { $params = $using:params } & $functionName @params } $jobRun += Invoke-Command -Session $session -ScriptBlock $sbJob -AsJob } } catch { Log-Info -Message "An unhandled error occurred on '$($session.ComputerName)' during '$($functionName)'" -Type Error -ConsoleOut Log-Info -Message ("The exception message was: $($PSItem.Exception.Message)") -Type Error -ConsoleOut $detailedMessage = $PSItem.Exception.Message $exceptionResult = New-SBEHealthResultObject -TestName $functionName -TargetName $session.ComputerName -Status 'FAILURE' -Severity 'CRITICAL' -Description "Invoke '$($functionName)' on '$($session.ComputerName)'" $exceptionResult.AdditionalData.Detail = $detailedMessage $allResult += $exceptionResult throw $detailedMessage } # Wait for all jobs to complete with a timeout after 30 minutes Log-Info -Message "Waiting for all '$($functionName)' jobs to complete" -Type Info $waitJob = $true $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() $timeoutMinutes = 30 while ($true -eq $waitJob) { if ($stopwatch.Elapsed.TotalMinutes -ge $timeoutMinutes) { Log-Info -Message "All jobs have not completed in the specified timeout period." -Type Error $stopwatch.Stop() $waitJob = $false } else { $keepWaiting = $false foreach ($job in $jobRun.ChildJobs) { if ($job.State -eq 'Running') { $keepWaiting = $true } } if ($false -eq $keepWaiting) { $stopwatch.Stop() $waitJob = $false } else { Start-Sleep -Seconds 30 } } } foreach ($job in $jobRun.ChildJobs) { $thisComputerName = $job.Location if ($job.State -eq 'Failed') { [string]$detailedMessage = "Error while running '$($functionName)' on '$($thisComputerName)'. Exception message: " + $job.JobStateInfo.Reason.Message Log-Info -Message $detailedMessage -Type Error -ConsoleOut $exceptionResult = New-SBEHealthResultObject -TestName $functionName -TargetName $job.Location -Status 'FAILURE' -Severity 'CRITICAL' -Description "An exception occurred during $functionName" $exceptionResult.AdditionalData.Detail = $detailedMessage $allResult += $exceptionResult } elseif ($job.State -eq 'Running') { Log-Info -Message "'$($functionName)' was still running on '$($thisComputerName)' when the timeout period was hit." -Type Warning $job | Stop-Job } else { Log-Info -Message "Log results for '$($thisComputerName)'" -Type Info [array]$thisOutput = $job.Output if ($thisOutput.Count -gt 0) { $instanceResult += $thisOutput } } } if ($instanceResult.Count -gt 0) { [array]$assertResult = Assert-ResponseSchemaValid -ResultObject $instanceResult if ($assertResult.Count -gt 0) { $instanceResult += $assertResult } } else { Log-Info -Message "'$($functionName)' did not return any test results or no tests have been implemented." -Type Warning $detailedMessage = "'$($functionName)' did not return any test results or no tests have been implemented." $thisResult = New-SBEHealthResultObject -TestName $functionName -TargetName $env:ComputerName -Status 'FAILURE' -Description "Received health check results from $functionName" $thisResult.AdditionalData.Detail = $detailedMessage $instanceResult += $thisResult } } } catch { if ($null -ne $exceptionResult) { Log-Info -Message "'$($functionName)' hit exception - adding result details: $($exceptionResult.AdditionalData.Detail)" -Type Warning $instanceResult += $exceptionResult $allResult += $instanceResult } foreach ($job in $jobRun.ChildJobs) { if ($job.State -eq 'Running') { Log-Info -Message "'$($functionName)' was still running on '$($thisComputerName)' when an exception occurred." -Type Warning $job | Stop-Job } } throw $PSItem } finally { Log-Info -Message "Before adding $($functionName) instances... all count = $($allResult.Count) / instance count = $($instanceResult.Count) )" if ($null -ne $instanceResult) { $allResult += $instanceResult } } Log-Info -Message "Returning with all count = $($allResult.Count)" return $allResult } catch { Log-Info -Message "" -ConsoleOut Log-Info -Message "$($PSItem.Exception.Message)" -ConsoleOut -Type Error Log-Info -Message "$($PSItem.ScriptStackTrace)" -ConsoleOut -Type Error $cmdletException = $PSItem if ($allResult.Count -eq 0) { throw $PSItem } else { Log-Info -Message "Returning with all count = $($allResult.Count)" return $allResult } } finally { Log-Info -Message "Performing clean up" $cleanupScriptBlock = { Get-Module -Name SolutionExtension -ErrorAction SilentlyContinue | Remove-Module -Force -Verbose:$false <# We now depend on deploy and action plans to clean up the cache dirs we leave behind for them if ($null -eq $sbeWorkingDir) { $sbeWorkingDir = $using:sbeWorkingDir } if (Test-Path -Path $sbeWorkingDir) { Write-Output "Remove SBE temporary working folder '$($sbeWorkingDir)' on '$($env:ComputerName)'" Remove-Item -Path $sbeWorkingDir -Recurse -Force } #> } if ($PsSession.Count -gt 0) { $jobClean = Invoke-Command -Session $PsSession -ScriptBlock $cleanupScriptBlock -AsJob $jobClean | Wait-Job | Out-Null foreach ($job in $jobClean.ChildJobs) { if ($job.State -eq 'Failed') { [string]$detailedMessage = "An exception occurred during clean-up on '$($job.Location)'. Exception message: " + $job.JobStateInfo.Reason.Message Log-Info -Message $detailedMessage -Type Warning } else { [string]$output = $job.Output Log-Info -Message $output -Type Info } } } else { Invoke-Command -ScriptBlock $cleanupScriptBlock } $script:ErrorActionPreference = 'SilentlyContinue' # Write result to telemetry channel foreach ($res in $allResult) { Write-ETWResult -Result $res } # Write validation result to report object and close out report $envcheckerReport | Add-Member -MemberType NoteProperty -Name 'SBEHealth' -Value $allResult -Force $envcheckerReport = Close-AzStackHciEnvJob -Report $envcheckerReport Write-AzStackHciEnvReport -Report $envcheckerReport Write-AzStackHciFooter -invocation $MyInvocation -Exception $cmdletException -PassThru:$PassThru } } # SIG # Begin signature block # MIIoQwYJKoZIhvcNAQcCoIIoNDCCKDACAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCApNRZ07C30m7hO # tmT5oTLtdm/QLUEYVUXhcQF2ArpiIqCCDXYwggX0MIID3KADAgECAhMzAAAEBGx0 # Bv9XKydyAAAAAAQEMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p # bmcgUENBIDIwMTEwHhcNMjQwOTEyMjAxMTE0WhcNMjUwOTExMjAxMTE0WjB0MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB # AQC0KDfaY50MDqsEGdlIzDHBd6CqIMRQWW9Af1LHDDTuFjfDsvna0nEuDSYJmNyz # NB10jpbg0lhvkT1AzfX2TLITSXwS8D+mBzGCWMM/wTpciWBV/pbjSazbzoKvRrNo # DV/u9omOM2Eawyo5JJJdNkM2d8qzkQ0bRuRd4HarmGunSouyb9NY7egWN5E5lUc3 # a2AROzAdHdYpObpCOdeAY2P5XqtJkk79aROpzw16wCjdSn8qMzCBzR7rvH2WVkvF # HLIxZQET1yhPb6lRmpgBQNnzidHV2Ocxjc8wNiIDzgbDkmlx54QPfw7RwQi8p1fy # 4byhBrTjv568x8NGv3gwb0RbAgMBAAGjggFzMIIBbzAfBgNVHSUEGDAWBgorBgEE # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQU8huhNbETDU+ZWllL4DNMPCijEU4w # RQYDVR0RBD4wPKQ6MDgxHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEW # MBQGA1UEBRMNMjMwMDEyKzUwMjkyMzAfBgNVHSMEGDAWgBRIbmTlUAXTgqoXNzci # tW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8vd3d3Lm1pY3Jvc29mdC5j # b20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3JsMGEG # CCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDovL3d3dy5taWNyb3NvZnQu # Y29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3J0 # MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAIjmD9IpQVvfB1QehvpC # Ge7QeTQkKQ7j3bmDMjwSqFL4ri6ae9IFTdpywn5smmtSIyKYDn3/nHtaEn0X1NBj # L5oP0BjAy1sqxD+uy35B+V8wv5GrxhMDJP8l2QjLtH/UglSTIhLqyt8bUAqVfyfp # h4COMRvwwjTvChtCnUXXACuCXYHWalOoc0OU2oGN+mPJIJJxaNQc1sjBsMbGIWv3 # cmgSHkCEmrMv7yaidpePt6V+yPMik+eXw3IfZ5eNOiNgL1rZzgSJfTnvUqiaEQ0X # dG1HbkDv9fv6CTq6m4Ty3IzLiwGSXYxRIXTxT4TYs5VxHy2uFjFXWVSL0J2ARTYL # E4Oyl1wXDF1PX4bxg1yDMfKPHcE1Ijic5lx1KdK1SkaEJdto4hd++05J9Bf9TAmi # u6EK6C9Oe5vRadroJCK26uCUI4zIjL/qG7mswW+qT0CW0gnR9JHkXCWNbo8ccMk1 # sJatmRoSAifbgzaYbUz8+lv+IXy5GFuAmLnNbGjacB3IMGpa+lbFgih57/fIhamq # 5VhxgaEmn/UjWyr+cPiAFWuTVIpfsOjbEAww75wURNM1Imp9NJKye1O24EspEHmb # DmqCUcq7NqkOKIG4PVm3hDDED/WQpzJDkvu4FrIbvyTGVU01vKsg4UfcdiZ0fQ+/ # V0hf8yrtq9CkB8iIuk5bBxuPMIIHejCCBWKgAwIBAgIKYQ6Q0gAAAAAAAzANBgkq # hkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x # EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv # bjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 # IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEwOTA5WjB+MQswCQYDVQQG # EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG # A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYDVQQDEx9NaWNyb3NvZnQg # Q29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC # CgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+laUKq4BjgaBEm6f8MMHt03 # a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc6Whe0t+bU7IKLMOv2akr # rnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4Ddato88tt8zpcoRb0Rrrg # OGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+lD3v++MrWhAfTVYoonpy # 4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nkkDstrjNYxbc+/jLTswM9 # sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6A4aN91/w0FK/jJSHvMAh # dCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmdX4jiJV3TIUs+UsS1Vz8k # A/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL5zmhD+kjSbwYuER8ReTB # w3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zdsGbiwZeBe+3W7UvnSSmn # Eyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3T8HhhUSJxAlMxdSlQy90 # lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS4NaIjAsCAwEAAaOCAe0w # ggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRIbmTlUAXTgqoXNzcitW2o # ynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYD # VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBDuRQFTuHqp8cx0SOJNDBa # BgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2Ny # bC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3JsMF4GCCsG # AQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3dy5taWNyb3NvZnQuY29t # L3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3J0MIGfBgNV # HSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEFBQcCARYzaHR0cDovL3d3 # dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1hcnljcHMuaHRtMEAGCCsG # AQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkAYwB5AF8AcwB0AGEAdABl # AG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn8oalmOBUeRou09h0ZyKb # C5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7v0epo/Np22O/IjWll11l # hJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0bpdS1HXeUOeLpZMlEPXh6 # I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/KmtYSWMfCWluWpiW5IP0 # wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvyCInWH8MyGOLwxS3OW560 # STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBpmLJZiWhub6e3dMNABQam # ASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJihsMdYzaXht/a8/jyFqGa # J+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYbBL7fQccOKO7eZS/sl/ah # XJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbSoqKfenoi+kiVH6v7RyOA # 9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sLgOppO6/8MO0ETI7f33Vt # Y5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtXcVZOSEXAQsmbdlsKgEhr # /Xmfwb1tbWrJUnMTDXpQzTGCGiMwghofAgEBMIGVMH4xCzAJBgNVBAYTAlVTMRMw # EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN # aWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNp # Z25pbmcgUENBIDIwMTECEzMAAAQEbHQG/1crJ3IAAAAABAQwDQYJYIZIAWUDBAIB # BQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO # MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEILb4GNqHAqeqEUW83hB3cxYJ # 7vwYxTHQ3UMK/kO0YpdsMEIGCisGAQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8A # cwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEB # BQAEggEAcSBpjqVflbTDS2FQDuYxbRlk8uADc2RMVok/5IxhnrWID8ArMYoe0OR5 # /bam36d2SqDbQ2PfcC++UP1aXI4i4JpL6fyRAZVstlZ/El+Bcz6OnIb3/iv9z16F # oD46o0Sh0ohabi6lfXaPFx1gf511PmQFhfjeoThoEYgGJQ8mJ0h2VqPKAPFM5YZV # JtcxHbiAHq8P1BNZP1bIhG5BRc/jzdegf3AHN15DRPUnCYL1JU+EUfJ6yU6FhDbn # DP0L2+2qIE8VAvO1Q5IbFc4yQO0ovBwM0zMfcfVDt699qyMTqoSLARWV+AouRDtK # WFkWXtM5f0hmnD95/Of16cIsNXbYZaGCF60wghepBgorBgEEAYI3AwMBMYIXmTCC # F5UGCSqGSIb3DQEHAqCCF4YwgheCAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFaBgsq # hkiG9w0BCRABBKCCAUkEggFFMIIBQQIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFl # AwQCAQUABCBtqMkKx9StCMOgWGgu0GB+5PadeQ6MZkUJ2BXB50QHPgIGZ0pekNbx # GBMyMDI0MTIwNDE1MDMzMS40MzRaMASAAgH0oIHZpIHWMIHTMQswCQYDVQQGEwJV # UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE # ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJl # bGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVT # Tjo2NTFBLTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAg # U2VydmljZaCCEfswggcoMIIFEKADAgECAhMzAAAB9ZkJlLzxxlCMAAEAAAH1MA0G # CSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u # MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp # b24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMB4XDTI0 # MDcyNTE4MzEwMVoXDTI1MTAyMjE4MzEwMVowgdMxCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9w # ZXJhdGlvbnMgTGltaXRlZDEnMCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOjY1MUEt # MDVFMC1EOTQ3MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNl # MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAzO90cFQTWd/WP84IT7JM # IW1fQL61sdfgmhlfT0nvYEb2kvkNF073ZwjveuSWot387LjE0TCiG93e6I0HzIFQ # BnbxGP/WPBUirFq7WE5RAsuhNfYUL+PIb9jJq3CwWxICfw5t/pTyIOHjKvo1lQOT # WZypir/psZwEE7y2uWAPbZJTFrKen5R73x2Hbxy4eW1DcmXjym2wFWv10sBH40aj # Jfe+OkwcTdoYrY3KkpN/RQSjeycK0bhjo0CGYIYa+ZMAao0SNR/R1J1Y6sLkiCJO # 3aQrbS1Sz7l+/qJgy8fyEZMND5Ms7C0sEaOvoBHiWSpTM4vc0xDLCmc6PGv03CtW # u2KiyqrL8BAB1EYyOShI3IT79arDIDrL+de91FfjmSbBY5j+HvS0l3dXkjP3Hon8 # b74lWwikF0rzErF0n3khVAusx7Sm1oGG+06hz9XAy3Wou+T6Se6oa5LDiQgPTfWR # /j9FNk8Ju06oSfTh6c03V0ulla0Iwy+HzUl+WmYxFLU0PiaXsmgudNwVqn51zr+B # i3XPJ85wWuy6GGT7nBDmXNzTNkzK98DBQjTOabQXUZ884Yb9DFNcigmeVTYkyUXZ # 6hscd8Nyq45A3D3bk+nXnsogK1Z7zZj6XbGft7xgOYvveU6p0+frthbF7MXv+i5q # cD9HfFmOq4VYHevVesYb6P0CAwEAAaOCAUkwggFFMB0GA1UdDgQWBBRV4Hxb9Uo0 # oHDwJZJe22ixe2B1ATAfBgNVHSMEGDAWgBSfpxVdAF5iXYP05dJlpxtTNRnpcjBf # BgNVHR8EWDBWMFSgUqBQhk5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3Bz # L2NybC9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcmww # bAYIKwYBBQUHAQEEYDBeMFwGCCsGAQUFBzAChlBodHRwOi8vd3d3Lm1pY3Jvc29m # dC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0El # MjAyMDEwKDEpLmNydDAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUF # BwMIMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAgEAcwxmVPaA9xHf # fuom0TOSp2hspuf1G0cHW/KXHAuhnpW8/Svlq5j9aKI/8/G6fGIQMr0zlpau8jy8 # 3I4zclGdJjl5S02SxDlUKawtWvgf7ida06PgjeQM1eX4Lut4bbPfT0FEp77G76hh # ysXxTJNHv5y+fwThUeiiclihZwqcZMpa46m+oV6igTU6I0EnneotMqFs0Q3zHgVV # r4WXjnG2Bcnkip42edyg/9iXczqTBrEkvTz0UlltpFGaQnLzq+No8VEgq0UG7W1E # LZGhmmxFmHABwTT6sPJFV68DfLoC0iB9Qbb9VZ8mvbTV5JtISBklTuVAlEkzXi9L # IjNmx+kndBfKP8dxG/xbRXptQDQDaCsS6ogLkwLgH6zSs+ul9WmzI0F8zImbhnZh # UziIHheFo4H+ZoojPYcgTK6/3bkSbOabmQFf95B8B6e5WqXbS5s9OdMdUlW1gTI1 # r5u+WAwH2KG7dxneoTbf/jYl3TUtP7AHpyck2c0nun/Q0Cycpa9QUH/Dy01k6tQo # mNXGjivg2/BGcgZJ0Hw8C6KVelEJ31xLoE21m9+NEgSKCRoFE1Lkma31SyIaynbd # YEb8sOlZynMdm8yPldDwuF54vJiEArjrcDNXe6BobZUiTWSKvv1DJadR1SUCO/Od # 21GgU+hZqu+dKgjKAYdeTIvi9R2rtLYwggdxMIIFWaADAgECAhMzAAAAFcXna54C # m0mZAAAAAAAVMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UE # CBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9z # b2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZp # Y2F0ZSBBdXRob3JpdHkgMjAxMDAeFw0yMTA5MzAxODIyMjVaFw0zMDA5MzAxODMy # MjVaMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH # EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNV # BAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMIICIjANBgkqhkiG9w0B # AQEFAAOCAg8AMIICCgKCAgEA5OGmTOe0ciELeaLL1yR5vQ7VgtP97pwHB9KpbE51 # yMo1V/YBf2xK4OK9uT4XYDP/XE/HZveVU3Fa4n5KWv64NmeFRiMMtY0Tz3cywBAY # 6GB9alKDRLemjkZrBxTzxXb1hlDcwUTIcVxRMTegCjhuje3XD9gmU3w5YQJ6xKr9 # cmmvHaus9ja+NSZk2pg7uhp7M62AW36MEBydUv626GIl3GoPz130/o5Tz9bshVZN # 7928jaTjkY+yOSxRnOlwaQ3KNi1wjjHINSi947SHJMPgyY9+tVSP3PoFVZhtaDua # Rr3tpK56KTesy+uDRedGbsoy1cCGMFxPLOJiss254o2I5JasAUq7vnGpF1tnYN74 # kpEeHT39IM9zfUGaRnXNxF803RKJ1v2lIH1+/NmeRd+2ci/bfV+AutuqfjbsNkz2 # K26oElHovwUDo9Fzpk03dJQcNIIP8BDyt0cY7afomXw/TNuvXsLz1dhzPUNOwTM5 # TI4CvEJoLhDqhFFG4tG9ahhaYQFzymeiXtcodgLiMxhy16cg8ML6EgrXY28MyTZk # i1ugpoMhXV8wdJGUlNi5UPkLiWHzNgY1GIRH29wb0f2y1BzFa/ZcUlFdEtsluq9Q # BXpsxREdcu+N+VLEhReTwDwV2xo3xwgVGD94q0W29R6HXtqPnhZyacaue7e3Pmri # Lq0CAwEAAaOCAd0wggHZMBIGCSsGAQQBgjcVAQQFAgMBAAEwIwYJKwYBBAGCNxUC # BBYEFCqnUv5kxJq+gpE8RjUpzxD/LwTuMB0GA1UdDgQWBBSfpxVdAF5iXYP05dJl # pxtTNRnpcjBcBgNVHSAEVTBTMFEGDCsGAQQBgjdMg30BATBBMD8GCCsGAQUFBwIB # FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9y # eS5odG0wEwYDVR0lBAwwCgYIKwYBBQUHAwgwGQYJKwYBBAGCNxQCBAweCgBTAHUA # YgBDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU # 1fZWy4/oolxiaNE9lJBb186aGMQwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2Ny # bC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0XzIw # MTAtMDYtMjMuY3JsMFoGCCsGAQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0cDov # L3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXRfMjAxMC0w # Ni0yMy5jcnQwDQYJKoZIhvcNAQELBQADggIBAJ1VffwqreEsH2cBMSRb4Z5yS/yp # b+pcFLY+TkdkeLEGk5c9MTO1OdfCcTY/2mRsfNB1OW27DzHkwo/7bNGhlBgi7ulm # ZzpTTd2YurYeeNg2LpypglYAA7AFvonoaeC6Ce5732pvvinLbtg/SHUB2RjebYIM # 9W0jVOR4U3UkV7ndn/OOPcbzaN9l9qRWqveVtihVJ9AkvUCgvxm2EhIRXT0n4ECW # OKz3+SmJw7wXsFSFQrP8DJ6LGYnn8AtqgcKBGUIZUnWKNsIdw2FzLixre24/LAl4 # FOmRsqlb30mjdAy87JGA0j3mSj5mO0+7hvoyGtmW9I/2kQH2zsZ0/fZMcm8Qq3Uw # xTSwethQ/gpY3UA8x1RtnWN0SCyxTkctwRQEcb9k+SS+c23Kjgm9swFXSVRk2XPX # fx5bRAGOWhmRaw2fpCjcZxkoJLo4S5pu+yFUa2pFEUep8beuyOiJXk+d0tBMdrVX # VAmxaQFEfnyhYWxz/gq77EFmPWn9y8FBSX5+k77L+DvktxW/tM4+pTFRhLy/AsGC # onsXHRWJjXD+57XQKBqJC4822rpM+Zv/Cuk0+CQ1ZyvgDbjmjJnW4SLq8CdCPSWU # 5nR0W2rRnj7tfqAxM328y+l7vzhwRNGQ8cirOoo6CGJ/2XBjU02N7oJtpQUQwXEG # ahC0HVUzWLOhcGbyoYIDVjCCAj4CAQEwggEBoYHZpIHWMIHTMQswCQYDVQQGEwJV # UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE # ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJl # bGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVT # Tjo2NTFBLTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAg # U2VydmljZaIjCgEBMAcGBSsOAwIaAxUAJsAKu48NbR5YRg3WSBQCyjzdkvaggYMw # gYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE # BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYD # VQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQsF # AAIFAOr6y6EwIhgPMjAyNDEyMDQxMjM3NTNaGA8yMDI0MTIwNTEyMzc1M1owdDA6 # BgorBgEEAYRZCgQBMSwwKjAKAgUA6vrLoQIBADAHAgEAAgIi6jAHAgEAAgISjjAK # AgUA6vwdIQIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIB # AAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBCwUAA4IBAQBYhQMogIeFDUrR # IwRU4YMHsPiZCGElvUgmgHgddtSF1sr0JWg6uW+zVTBBOPVsl+IUHxqIx0c72OTL # MYEhF1tr9geRKbk1x7eJmLMBfbipeAwga/pJq6RPG2vnSilmuq/hrp4hqO2vPBYa # Pmiir3aQJKVLJwIjeM7GN/M9nWH0gIiWev64zrGtXt+AyMp6Q3wsJN3xTSZVrHWp # ZduSgBh32boIPCrc4IPPTBbzWEEaGJ0RoC95zkbUd0MF6vT0T9m/FlfiCK3X5l7/ # zSjz3taMFlfojh46I2eEn4MxHWnP/R3Goj+B5qycd5iyGoXYSIJpCodlpF4ISHe+ # QOPU9cJrMYIEDTCCBAkCAQEwgZMwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldh # c2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBD # b3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIw # MTACEzMAAAH1mQmUvPHGUIwAAQAAAfUwDQYJYIZIAWUDBAIBBQCgggFKMBoGCSqG # SIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQxIgQgL3qAgO06nfAh # PeYLH1bScnXzw5gtuGplg5Z0e7eudccwgfoGCyqGSIb3DQEJEAIvMYHqMIHnMIHk # MIG9BCDB1vLSFwh09ISu4kdEv4/tg9eR1Yk8w5x7j5GThqaPNTCBmDCBgKR+MHwx # CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt # b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1p # Y3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAB9ZkJlLzxxlCMAAEAAAH1 # MCIEIJsAF0QtKp+zWOqWDTyk72cE0rYTpB5dhe7Q+cQ+Uo6GMA0GCSqGSIb3DQEB # CwUABIICAC23dmPhOAwqlyZStx/N0JCGgUaoXmeF/y5SvldQNp1rTmWz/vv8YpBi # F1BpIZABDaPgQJ2xpdqU8niiNMOP4zi6J8A9sGb9Kbpv150UEepyO6KlctzMr96X # 2chErUM7NAwxlVgjnuKYal1JyICHRSnX95fJRa9du5tm4n0/juSSzhSC0jkIonV0 # OBKGFghHpLJIUGD469sF9m+JSshFw/mgiChmdQ0WtBE71mA22nUsLbV0iOXzRwYf # 51kzOGH/xtUivnPTa9MaUs2AEZXhWaStFKAPX3TkIRK8GtGUPB1l7bqo1ieJmQrB # NsrpYAbm5HDTeqJ3I6jnMxVssEWEwYdcBIgOosHlZnAyId3NYzJHiPpZVNRoJeGH # oNcSNCZtwY2RibB90izksXETCPb3Kv4FM1REKUwavc2YL1eFxMPL3N34BtBeYbKO # kzwh+e6F82/xurUgMeYm3rf/Mp0LojaIe2LRA6fll3ZvkEtyWavak/GluIzmpsrB # IthLsVdXdF77oX+bjyS/YH/Tqtj8uCmulccOqsddK+KAhQ4U2u+aIUTO1tepaxIb # iQ+zHc898WEIizocDnhjuOr8yvCLm2fUcgN+NTvNaB4mbCcp5w4qRXJplC9+k/Ef # ozAK3uBvxILpjjygS52egiY6lvWl/oIsa1tY9oLP2ewqEixds9BI # SIG # End signature block |