AzureValidation/Microsoft.AzureStack.AzureValidation.psm1
$erroractionpreference = 'stop' Import-LocalizedData LocalizedData -BaseDirectory $PSScriptRoot -Filename Microsoft.AzureStack.AzureValidation.Strings.psd1 Import-Module $PSSCriptRoot\Microsoft.AzureStack.AzureValidation.Internal.psm1 -force Import-Module $PSScriptRoot\..\Microsoft.AzureStack.ReadinessChecker.Utilities.psm1 -Force function Invoke-AzsRegistrationValidation { <# .SYNOPSIS Validates Credential and Subscription for Azure Stack Registration. .DESCRIPTION Validate registration before you begin an Azure Stack deployment: Validates the Azure subscription provided is a supported type. Subscriptions must be a Cloud Service Provider (CSP) or Enterprise Agreement (EA). The account provided can sign in to Azure and is a subscription owner. .EXAMPLE PS C:\> Connect-AzAccount -subscription 3f764e1c-d0ab-49e3-99aa-44124d56dd2d PS C:\> Invoke-AzsRegistrationValidation -RegistrationSubscriptionID 3f764e1c-d0ab-49e3-99aa-44124d56dd2d Validates Credential and Subscription for Azure Stack Registration. .PARAMETER Context Specifies Azure PowerShell context representing the context of intended registration account .PARAMETER DeploymentDataJSONPath Specifies the Azure Stack deployment deployment data JSON configuration file. Generally only available to the deployment team. .PARAMETER ForceTLS12 Force the use of TLS 1.2, true by default .PARAMETER OutputPath Specifies custom path to save Readiness JSON report and Verbose log file. .PARAMETER CleanReport Specifies whether to purge the existing report and start again with a clean report. Execution history and validation data is lost for all Readiness Checker validations. .LINK Azure Stack Registration Validation - https://aka.ms/AzsValidateAzureRegistration Azure Stack Readiness Checker - https://aka.ms/AzsReadinessChecker #> [OutputType([Array])] [CmdletBinding()] Param( [Parameter(Mandatory = $true, ParameterSetName = 'RegistrationJSON')] [ValidateScript( {Test-Path $_ -Include *.json})] [string] $deploymentDataJSONPath, [Parameter(Helpmessage = 'Azure PowerShell context representing the context of intended registration account')] [ValidateNotNull()] [Microsoft.Azure.Commands.Common.Authentication.Abstractions.IAzureContext] $Context = (Get-AzContext -ErrorAction Stop), [Parameter(Mandatory = $true, ParameterSetName = 'Registration')] [Parameter(Mandatory = $true, ParameterSetName = 'RegistrationJSON')] [string] $RegistrationSubscriptionID, [Parameter(Mandatory = $false, HelpMessage = "Force the use of TLS 1.2, true by default")] [bool]$ForceTLS12 = $true, [Parameter(HelpMessage = "Directory path for log and report output")] [string]$OutputPath = "$ENV:TEMP\AzsReadinessChecker", [Parameter(HelpMessage = "Remove all previous progress and create a clean report")] [switch]$CleanReport = $false ) try { $thisFunction = $MyInvocation.MyCommand.Name $GLOBAL:OutputPath = $OutputPath Import-Module $PSScriptRoot\..\Microsoft.AzureStack.ReadinessChecker.Reporting.psm1 -Force Import-Module $PSSCriptRoot\AzureADConfiguration.psm1 -Force -Global Write-Header -invocation $MyInvocation -params $PSBoundParameters # Ensure the local machine has Az.Accounts module if (-not (Get-Module -Name 'Az.Accounts' -ListAvailable | Where-Object Version -ge '2.2.8')) { Write-AzsReadinessLog -Message $LocalizedData.NoAzAccounts -Type Error -Function $thisFunction throw $LocalizedData.NoAzAccounts } # Parse DeploymentData JSON if ($PSCmdlet.ParameterSetName -eq 'RegistrationJSON') { $deploymentDataJSON = ConvertTo-DeploymentData -path $deploymentDataJSONPath $AzureEnvironment = $deploymentDataJSON.DeploymentData.InfraAzureEnvironment } # If user specifies custom azure environment, overwrite the AzureEnvironment as the json path # Get/Clean Existing Report $readinessReport = Get-AzsReadinessProgress -clean:$CleanReport $readinessReport = Add-AzsReadinessCheckerJob -report $readinessReport $registrationOutput = @{} # exit immediately if the user hasn't authenticated to Azure if (-not $context){ Write-AzsReadinessLog -Message $LocalizedData.NoAzureContext -Type Error -Function $thisFunction throw $LocalizedData.NoAzureContext } # Force Security Profile to TLS1.2 if ($ForceTLS12) { # Change Security Protocol to TLS1.2 for the session and track for clean up later. $restoreSecurityProtocol = [Net.ServicePointManager]::SecurityProtocol $tempSecurityProtocol = [Net.SecurityProtocolType]::Tls12 Set-SecurityProtocol -securityProtocol $tempSecurityProtocol } Write-Host "Checking Registration Requirements: " -nonewline $tenantId = (Get-AzContext).Tenant.Id if ($null -eq $tenantid) { throw "No TenantId." } else { $registrationSubscription = Get-AzureSubscriptionDetail -tenantid $tenantid -subscriptionid $RegistrationSubscriptionID } ## expand test-azsregistrationaccount to test graph endpoint if (-not $registrationSubscription.errordetails) { $registrationOutput = Test-AzsRegistrationAccount -subscription $registrationSubscription.subscription -subscriptionId $RegistrationSubscriptionID -tenantId $tenantid if ($registrationOutput.result -ne 'OK') { Write-Host "Fail " -foregroundColor Red Write-Host ("Error Details for registration account {0}:" -f (Get-AzContext).Account.Id) $registrationOutput.errorDetails | ForEach-Object {Write-Host "$_" -foregroundcolor Yellow} Write-Host ("Additional help URL {0}" -f "https://aka.ms/AzsRemediateRegistration") } else { Write-Host "OK" -foregroundColor Green } } else { Write-Host "Fail " -foregroundColor Red Write-Host ("Error Details for registration account {0}:" -f (Get-AzContext).Account.Id) $registrationSubscription.errorDetails | ForEach-Object {Write-Host "$_" -foregroundcolor Yellow} Write-Host ("Additional help URL {0}" -f "https://aka.ms/AzsRemediateRegistration") } $registrationOutput.Add('SubscriptionDetail', $registrationSubscription) } catch { Write-Host "Fail " -foregroundColor Red $errorDetail = ("Checking Registration failed with: {0}" -f $_.exception.Message) Write-Host ("Error Details for registration account {0}:" -f (Get-AzContext).Account.Id) $errorDetail | ForEach-Object {Write-Host "$_" -foregroundcolor Yellow} } finally { # Write results to readiness report $readinessReport.AzureValidation.AzureRegistration = $registrationOutput $readinessReport = Close-AzsReadinessCheckerJob -report $readinessReport Write-AzsReadinessProgress -report $readinessReport Write-AzsReadinessReport -report $readinessReport # Remove global variables Remove-Variable -Name OutputPath # Restore TLS back to default if ($ForceTLS12 -and $restoreSecurityProtocol) { Set-SecurityProtocol -securityProtocol $restoreSecurityProtocol } Write-Footer -invocation $MyInvocation } } function Invoke-AzsAzureIdentityValidation { <# .SYNOPSIS Validates Service Administrator and AAD Tenant for Azure Stack Identity .DESCRIPTION Validate identity before you begin an Azure Stack Deployment Validates Service Administrator provided is a Global Administrator of the AAD Tenant directory provided. .EXAMPLE PS C:\> Connect-AzAccount -tenant contoso.onmicrosoft.com PS C:\> Invoke-AzsAzureIdentityValidation -AADDirectoryTenantName contoso.onmicrosoft.com Validates Service Administrator and AAD Tenant for Azure Stack Identity .PARAMETER Context Azure PowerShell context representing the context of intended Service Administrator Account .PARAMETER AADDirectoryTenantName Specifies the Azure Active Directory name intended to be used for Azure Stack deployment. .PARAMETER ForceTLS12 Force the use of TLS 1.2, true by default .PARAMETER OutputPath Specifies custom path to save Readiness JSON report and Verbose log file. .PARAMETER CleanReport Specifies whether to purge the existing report and start again with a clean report. Execution history and validation data is lost for all Readiness Checker validations. .LINK Azure Stack Identity Validation - https://aka.ms/AzsValidateAzureIdentity Azure Stack Readiness Checker - https://aka.ms/AzsReadinessChecker #> [CmdletBinding()] Param( [Parameter(Mandatory = $true, ParameterSetName = 'InstallJSON')] [ValidateScript( {Test-Path $_ -Include *.json})] [string] $deploymentDataJSONPath, [Parameter(HelpMessage = "Azure PowerShell context representing the context of intended Service Administrator Account")] [ValidateNotNull()] [Microsoft.Azure.Commands.Common.Authentication.Abstractions.IAzureContext] $Context = (Get-AzContext -ErrorAction Stop), [Parameter(Mandatory = $true, ParameterSetName = 'Install', HelpMessage = "Enter primary domain name of Azure Tenant Directory")] [string]$AADDirectoryTenantName, [Parameter(Mandatory = $false, HelpMessage = "Force the use of TLS 1.2, true by default")] [bool]$ForceTLS12 = $true, [Parameter(HelpMessage = "Directory path for log and report output")] [string]$OutputPath = "$ENV:TEMP\AzsReadinessChecker", [Parameter(HelpMessage = "Remove all previous progress and create a clean report")] [switch]$CleanReport = $false ) try { $thisFunction = $MyInvocation.MyCommand.Name $GLOBAL:OutputPath = $OutputPath Import-Module $PSScriptRoot\..\Microsoft.AzureStack.ReadinessChecker.Reporting.psm1 -Force Import-Module $PSSCriptRoot\AzureADConfiguration.psm1 -Force -Global Write-Header -invocation $MyInvocation -params $PSBoundParameters # Ensure the local machine has Az.Accounts module if (-not (Get-Module -Name 'Az.Accounts' -ListAvailable | Where-Object Version -ge '2.2.8')) { Write-AzsReadinessLog -Message $LocalizedData.NoAzAccounts -Type Error -Function $thisFunction throw $LocalizedData.NoAzAccounts } if ($PSCmdlet.ParameterSetName -eq 'InstallJSON') { $deploymentDataJSON = ConvertTo-DeploymentData -path $deploymentDataJSONPath $AzureEnvironment = $deploymentDataJSON.DeploymentData.InfraAzureEnvironment $AADDirectoryTenantName = $deploymentDataJSON.DeploymentData.InfraAzureDirectoryTenantName } # Get/Clean Existing Report $readinessReport = Get-AzsReadinessProgress -clean:$CleanReport $readinessReport = Add-AzsReadinessCheckerJob -report $readinessReport $serviceAdministratorOutput = @{} # exit immediately if the user hasn't authenticated to Azure if (-not $context){ Write-AzsReadinessLog -Message $LocalizedData.NoAzureContext -Type Error -Function $thisFunction throw $LocalizedData.NoAzureContext } # Force Security Profile to TLS1.2 if ($ForceTLS12) { # Change Security Protocol to TLS1.2 for the session and track for clean up later. $restoreSecurityProtocol = [Net.ServicePointManager]::SecurityProtocol $tempSecurityProtocol = [Net.SecurityProtocolType]::Tls12 Set-SecurityProtocol -securityProtocol $tempSecurityProtocol } Write-AzsReadinessLog -Message ("Starting Azure Identity Validation`n") -Type Info -Function $thisFunction -toScreen Write-Host "Checking Installation Requirements: " -nonewline $serviceAdministratorOutput = Test-AzsServiceAdministrator -AADDirectoryTenantName $AADDirectoryTenantName if ($serviceAdministratorOutput.result -ne 'OK') { Write-Host "Fail " -foregroundColor Red if ($serviceAdministratorOutput.errorDetails -ne @()) { Write-Host ("Error Details for Service Administrator Account {0}" -f $AADServiceAdministrator.Username) $serviceAdministratorOutput.errorDetails | ForEach-Object {Write-Host "$_" -foregroundcolor Yellow} Write-Host ("Additional help URL {0}" -f "https://aka.ms/AzsRemediateAzureIdentity") } } else { Write-Host "OK" -foregroundColor Green } Write-AzsReadinessLog -Message ("`nFinished Azure Identity Validation") -Type Info -Function $thisFunction -toScreen } catch { Write-Host "Fail " -foregroundColor Red $errorDetail = ("Checking Azure Identity failed with: {0}" -f $_.exception.Message) Write-Host "Error Details for Identity:" $errorDetail | ForEach-Object {Write-Host "$_" -foregroundcolor Yellow} } finally { # Write results to readiness report $readinessReport.AzureValidation.AzureInstallResult = $serviceAdministratorOutput $readinessReport = Close-AzsReadinessCheckerJob -report $readinessReport Write-AzsReadinessProgress -report $readinessReport Write-AzsReadinessReport -report $readinessReport # Remove global variables Remove-Variable -Name OutputPath # Restore TLS back to default if ($ForceTLS12 -and $restoreSecurityProtocol) { Set-SecurityProtocol -securityProtocol $restoreSecurityProtocol } Write-Footer -invocation $MyInvocation } } # SIG # Begin signature block # MIIjhQYJKoZIhvcNAQcCoIIjdjCCI3ICAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCybqL6SvodstPw # Rlh9jo5ssLyekxUgEUr84Q6JNxljv6CCDYEwggX/MIID56ADAgECAhMzAAACUosz # qviV8znbAAAAAAJSMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p # bmcgUENBIDIwMTEwHhcNMjEwOTAyMTgzMjU5WhcNMjIwOTAxMTgzMjU5WjB0MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB # AQDQ5M+Ps/X7BNuv5B/0I6uoDwj0NJOo1KrVQqO7ggRXccklyTrWL4xMShjIou2I # sbYnF67wXzVAq5Om4oe+LfzSDOzjcb6ms00gBo0OQaqwQ1BijyJ7NvDf80I1fW9O # L76Kt0Wpc2zrGhzcHdb7upPrvxvSNNUvxK3sgw7YTt31410vpEp8yfBEl/hd8ZzA # v47DCgJ5j1zm295s1RVZHNp6MoiQFVOECm4AwK2l28i+YER1JO4IplTH44uvzX9o # RnJHaMvWzZEpozPy4jNO2DDqbcNs4zh7AWMhE1PWFVA+CHI/En5nASvCvLmuR/t8 # q4bc8XR8QIZJQSp+2U6m2ldNAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUNZJaEUGL2Guwt7ZOAu4efEYXedEw # UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1 # ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDY3NTk3MB8GA1UdIwQYMBaAFEhu # ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu # bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w # Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3 # Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx # MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAFkk3 # uSxkTEBh1NtAl7BivIEsAWdgX1qZ+EdZMYbQKasY6IhSLXRMxF1B3OKdR9K/kccp # kvNcGl8D7YyYS4mhCUMBR+VLrg3f8PUj38A9V5aiY2/Jok7WZFOAmjPRNNGnyeg7 # l0lTiThFqE+2aOs6+heegqAdelGgNJKRHLWRuhGKuLIw5lkgx9Ky+QvZrn/Ddi8u # TIgWKp+MGG8xY6PBvvjgt9jQShlnPrZ3UY8Bvwy6rynhXBaV0V0TTL0gEx7eh/K1 # o8Miaru6s/7FyqOLeUS4vTHh9TgBL5DtxCYurXbSBVtL1Fj44+Od/6cmC9mmvrti # yG709Y3Rd3YdJj2f3GJq7Y7KdWq0QYhatKhBeg4fxjhg0yut2g6aM1mxjNPrE48z # 6HWCNGu9gMK5ZudldRw4a45Z06Aoktof0CqOyTErvq0YjoE4Xpa0+87T/PVUXNqf # 7Y+qSU7+9LtLQuMYR4w3cSPjuNusvLf9gBnch5RqM7kaDtYWDgLyB42EfsxeMqwK # WwA+TVi0HrWRqfSx2olbE56hJcEkMjOSKz3sRuupFCX3UroyYf52L+2iVTrda8XW # esPG62Mnn3T8AuLfzeJFuAbfOSERx7IFZO92UPoXE1uEjL5skl1yTZB3MubgOA4F # 8KoRNhviFAEST+nG8c8uIsbZeb08SeYQMqjVEmkwggd6MIIFYqADAgECAgphDpDS # AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK # V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0 # IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0 # ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla # MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS # ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT # H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB # AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG # OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S # 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz # y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7 # 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u # M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33 # X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl # XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP # 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB # l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF # RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM # CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ # BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud # DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO # 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0 # LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y # Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p # Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y # Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB # FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw # cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA # XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY # 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj # 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd # d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ # Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf # wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ # aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j # NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B # xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96 # eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7 # r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I # RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVWjCCFVYCAQEwgZUwfjELMAkG # A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx # HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z # b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAlKLM6r4lfM52wAAAAACUjAN # BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor # BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgPtM8026C # E8fjtH9M1CZn21nP2zZdy80CKVgdS6iXcAEwQgYKKwYBBAGCNwIBDDE0MDKgFIAS # AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN # BgkqhkiG9w0BAQEFAASCAQCEiIJ8tGBi1kb3xMOS7anVZhHCi8pE0SICF0Ye2Z3T # BBlRQRHP1teZ/uqX3USYhJ3AVbd4wpmHzR6EGbICCNi/LeuZ/yudT4syTWaEYxTh # HmpLVVVtwJkeAj5Y+m8+OBE6/YNjBwh63dYGmffDkOcrNhNJYFRnJJcmlnOqIsB/ # K/Rt6n7PwTTC+Xd8ojiPAKqyLOSUJg159AUCP4YTNqg9c4FhKgMoHN9rX9NOqEvP # eUSa102VFwvxzDx5ZI75OY9OQE1HVPhx0QQMH8Bknj/33L4iDzwb7B5SG0hNNQYG # 6MgTRdOM1lg9yv+7C4qkoDIn+4x2lxQntxMf0ezwNhnboYIS5DCCEuAGCisGAQQB # gjcDAwExghLQMIISzAYJKoZIhvcNAQcCoIISvTCCErkCAQMxDzANBglghkgBZQME # AgEFADCCAVEGCyqGSIb3DQEJEAEEoIIBQASCATwwggE4AgEBBgorBgEEAYRZCgMB # MDEwDQYJYIZIAWUDBAIBBQAEIM9zUUaFN12z0Wne29NVA1mWhsWIxu5qywhowvGy # x1HFAgZhkuEfJiwYEzIwMjExMTE2MDg0OTQ1LjMxNlowBIACAfSggdCkgc0wgcox # CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt # b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1p # Y3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMxJjAkBgNVBAsTHVRoYWxlcyBUU1Mg # RVNOOjEyQkMtRTNBRS03NEVCMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFt # cCBTZXJ2aWNloIIOOzCCBPEwggPZoAMCAQICEzMAAAFT0oJyRWxX44sAAAAAAVMw # DQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0 # b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh # dGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwHhcN # MjAxMTEyMTgyNjA1WhcNMjIwMjExMTgyNjA1WjCByjELMAkGA1UEBhMCVVMxEzAR # BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p # Y3Jvc29mdCBDb3Jwb3JhdGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2Eg # T3BlcmF0aW9uczEmMCQGA1UECxMdVGhhbGVzIFRTUyBFU046MTJCQy1FM0FFLTc0 # RUIxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2UwggEiMA0G # CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC167Z0B7Mb+bNCAuXC6EGJsFvgVB6i # 30/jl4gmtUwoQG5z3WpxQHNJj+t2I4fpETQQLoxioHSiR+nbJFRnT3WCjc6UwbGB # MnQJgzgzVXofVPHICimiYNEiHy86PvCEpWT8vb6jfFcaOVoMe+4wN2NqblOWA4o6 # wmEQUFmrbpKZB+cRVJF7WE1L6NDfRiPE9XRfRk+zzZd+MJhs3eWRr7jVdG10vVEl # V3hq0YFzfho7guP3L0bMxikRy3pPe4W6g7Qwf5McxDpM0Aatz9CNkscAPyh4jZOF # 0f7diL1BGET/c4vp8iQTlfKqEhCbt3Fi/Hq54cwXjE1aUxzQva5b/ebtAgMBAAGj # ggEbMIIBFzAdBgNVHQ4EFgQUxqKLc0gqqbMwGUC34HBtrDFWRHUwHwYDVR0jBBgw # FoAU1WM6XIoxkPNDe3xGG8UzaFqFbVUwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDov # L2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljVGltU3RhUENB # XzIwMTAtMDctMDEuY3JsMFoGCCsGAQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0 # cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNUaW1TdGFQQ0FfMjAx # MC0wNy0wMS5jcnQwDAYDVR0TAQH/BAIwADATBgNVHSUEDDAKBggrBgEFBQcDCDAN # BgkqhkiG9w0BAQsFAAOCAQEAlGi9eXz6IEQ+xwFzSaJR3JxHsaiegym9DsRXcpfd # 7frlTUZ/5iVkyFq8YXyKoEI+7bVOzJlTf3PF8UdYCy4ysWae6szI+bsz29boYoRl # wSaxdQOg9hwlX1MkfdMnhJ+Iiw35EVYp7rMVjdN9i6aZHldKP/PDQNu+uzEHobKN # LpZsxe+LI/gdxuIiFJDO3O9eTun07xWHfhnIxJ2wS7y5PEHpdxZTQX2nvWR0bjdm # t5r6hy5X0sND1XZiaU2apl1Wb9Ha2bnO4A8lre7wZjS+i8XBVVJaE4LXmcTFeQll # Zldvq8yBmvDo4wvjFOFVckqyBSpCMMJpRqzkodGDxJ06NDCCBnEwggRZoAMCAQIC # CmEJgSoAAAAAAAIwDQYJKoZIhvcNAQELBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRp # ZmljYXRlIEF1dGhvcml0eSAyMDEwMB4XDTEwMDcwMTIxMzY1NVoXDTI1MDcwMTIx # NDY1NVowfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNV # BAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQG # A1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwggEiMA0GCSqGSIb3 # DQEBAQUAA4IBDwAwggEKAoIBAQCpHQ28dxGKOiDs/BOX9fp/aZRrdFQQ1aUKAIKF # ++18aEssX8XD5WHCdrc+Zitb8BVTJwQxH0EbGpUdzgkTjnxhMFmxMEQP8WCIhFRD # DNdNuDgIs0Ldk6zWczBXJoKjRQ3Q6vVHgc2/JGAyWGBG8lhHhjKEHnRhZ5FfgVSx # z5NMksHEpl3RYRNuKMYa+YaAu99h/EbBJx0kZxJyGiGKr0tkiVBisV39dx898Fd1 # rL2KQk1AUdEPnAY+Z3/1ZsADlkR+79BL/W7lmsqxqPJ6Kgox8NpOBpG2iAg16Hgc # sOmZzTznL0S6p/TcZL2kAcEgCZN4zfy8wMlEXV4WnAEFTyJNAgMBAAGjggHmMIIB # 4jAQBgkrBgEEAYI3FQEEAwIBADAdBgNVHQ4EFgQU1WM6XIoxkPNDe3xGG8UzaFqF # bVUwGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud # EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU1fZWy4/oolxiaNE9lJBb186aGMQwVgYD # VR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwv # cHJvZHVjdHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3JsMFoGCCsGAQUFBwEB # BE4wTDBKBggrBgEFBQcwAoY+aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9j # ZXJ0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcnQwgaAGA1UdIAEB/wSBlTCB # kjCBjwYJKwYBBAGCNy4DMIGBMD0GCCsGAQUFBwIBFjFodHRwOi8vd3d3Lm1pY3Jv # c29mdC5jb20vUEtJL2RvY3MvQ1BTL2RlZmF1bHQuaHRtMEAGCCsGAQUFBwICMDQe # MiAdAEwAZQBnAGEAbABfAFAAbwBsAGkAYwB5AF8AUwB0AGEAdABlAG0AZQBuAHQA # LiAdMA0GCSqGSIb3DQEBCwUAA4ICAQAH5ohRDeLG4Jg/gXEDPZ2joSFvs+umzPUx # vs8F4qn++ldtGTCzwsVmyWrf9efweL3HqJ4l4/m87WtUVwgrUYJEEvu5U4zM9GAS # inbMQEBBm9xcF/9c+V4XNZgkVkt070IQyK+/f8Z/8jd9Wj8c8pl5SpFSAK84Dxf1 # L3mBZdmptWvkx872ynoAb0swRCQiPM/tA6WWj1kpvLb9BOFwnzJKJ/1Vry/+tuWO # M7tiX5rbV0Dp8c6ZZpCM/2pif93FSguRJuI57BlKcWOdeyFtw5yjojz6f32WapB4 # pm3S4Zz5Hfw42JT0xqUKloakvZ4argRCg7i1gJsiOCC1JeVk7Pf0v35jWSUPei45 # V3aicaoGig+JFrphpxHLmtgOR5qAxdDNp9DvfYPw4TtxCd9ddJgiCGHasFAeb73x # 4QDf5zEHpJM692VHeOj4qEir995yfmFrb3epgcunCaw5u+zGy9iCtHLNHfS4hQEe # gPsbiSpUObJb2sgNVZl6h3M7COaYLeqN4DMuEin1wC9UJyH3yKxO2ii4sanblrKn # QqLJzxlBTeCG+SqaoxFmMNO7dDJL32N79ZmKLxvHIa9Zta7cRDyXUHHXodLFVeNp # 3lfB0d4wwP3M5k37Db9dT+mdHhk4L7zPWAUu7w2gUDXa7wknHNWzfjUeCLraNtvT # X4/edIhJEqGCAs0wggI2AgEBMIH4oYHQpIHNMIHKMQswCQYDVQQGEwJVUzETMBEG # A1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWlj # cm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBP # cGVyYXRpb25zMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjoxMkJDLUUzQUUtNzRF # QjElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZaIjCgEBMAcG # BSsOAwIaAxUAikpN7ccO1k9PKCGCvaQWKyJ50ZuggYMwgYCkfjB8MQswCQYDVQQG # EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG # A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQg # VGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIFAOU9X54wIhgPMjAy # MTExMTYwNjM3MThaGA8yMDIxMTExNzA2MzcxOFowdjA8BgorBgEEAYRZCgQBMS4w # LDAKAgUA5T1fngIBADAJAgEAAgEFAgH/MAcCAQACAhFEMAoCBQDlPrEeAgEAMDYG # CisGAQQBhFkKBAIxKDAmMAwGCisGAQQBhFkKAwKgCjAIAgEAAgMHoSChCjAIAgEA # AgMBhqAwDQYJKoZIhvcNAQEFBQADgYEATmvyESXbHLXzKcvhWUgOObExLX3IafeK # KeAQawX6fIoDRNkzENMAoyfwP6USSMHE/orwf7VIrCCEloW587yfk4pWAIRGN9LO # b+m5HOF2xcnpo0jTE6kZWPc57ViSyiJK5EVBAuN0bQKoNSGOvFfX1TIgwTQqJQun # ItWzfp69aaExggMNMIIDCQIBATCBkzB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMK # V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0 # IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0Eg # MjAxMAITMwAAAVPSgnJFbFfjiwAAAAABUzANBglghkgBZQMEAgEFAKCCAUowGgYJ # KoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMC8GCSqGSIb3DQEJBDEiBCDzlkvP+UW1 # SiEXMKmGRNZygqWx5wJydCSSZoiBgZM4xzCB+gYLKoZIhvcNAQkQAi8xgeowgecw # geQwgb0EIFDBCo85tCAICfyXoZBDppodLIMcb2wOH2rEBWiNtY8AMIGYMIGApH4w # fDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl # ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMd # TWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAFT0oJyRWxX44sAAAAA # AVMwIgQgl3uKqMQCykGgGYoUA5hTgL739FJU/MI10jnQkcUn6KswDQYJKoZIhvcN # AQELBQAEggEAdsWzeyuN6XxotONJfobhHVFaXPzVSQIPXE33N6FjqUCQrVU+ITbS # LZTg73osmQxxbdF17Aafj6Rg/FhLUoJP1jwdBm6mBIK/zLZA0jnlMeUFn4n4BkK9 # UImoVPfDWZDN4/aNQGNXiTS7v1uEOAqrvKqso+zcKoS36S5ZrxVNZx/HfCv1AaXN # Nz93l+I/qLQUJXpeDTN8CN/wnKH69e+sXZGGJfeGy0Im1eLZskpH2DxsmpKEhnPF # EudjirByEQdKvehVKXPZvsfhsF++jnyUdWGo+XEHB0OT4yqlbrglIZ95/op5YvcO # hO56cej/asjZ9hDxc91JjS5xAq4lqF+RLA== # SIG # End signature block |