AzureValidation/Microsoft.AzureStack.AzureValidation.psm1
#Requires -RunAsAdministrator <############################################################# # # # Copyright (C) Microsoft Corporation. All rights reserved. # # # #############################################################> <# .SYNOPSIS This script is intended to be given to the customer along with their deploymentdata.json in order to validate the Azure Active Directory assets required for Azure Stack deployment. .DESCRIPTION The script checks the following: AADServiceAdministrator is correctly provisioned and matches deploymentdata.json for install Registration Account is correct type and owners of the subscriptionID provided. .EXAMPLE #Install Checker $serviceAdminCredential = Get-Credential (serviceadmin@contoso.onmicrosoft.com) -Message "Enter Credentials for Service Administrator of Azure Active Directory Tenant" .\AADHelper.ps1 -AADServiceAdministrator $serviceAdminCredential -deploymentDataJSONPath .\deploymentData.json #Registration Checker $registrationCredential = Get-Credential (subscriptionowner@contoso.onmicrosoft.com) -Message "Enter Credentials for Subscription Owner" $subscriptionID = "f7c26209-cd2d-4625-86ba-724ebeece794" .\AADHelper.ps1 -RegistrationAccount $registrationCredential -RegistrationSubscriptionID $subscriptionID -deploymentDataJSONPath .\deploymentData.json .NOTES .LINK #> function Invoke-AzureStackAzureValidation { [OutputType([Array])] [CmdletBinding()] Param( [Parameter(Mandatory=$true, ParameterSetName='Install')] [Parameter(Mandatory=$true, ParameterSetName='InstallJSON')] [pscredential] $AADServiceAdministrator, [Parameter(Mandatory=$true, ParameterSetName='InstallJSON')] [Parameter(Mandatory=$true, ParameterSetName='RegistrationJSON')] [ValidateScript({Test-Path $_ -Include *.json})] [string] $deploymentDataJSONPath, [Parameter(Mandatory=$true, ParameterSetName='Install')] [Parameter(Mandatory=$true, ParameterSetName='Registration')] [ValidateSet('AzureCloud','AzureChinaCloud','AzureGermanCloud')] [string] $AzureEnvironment, [Parameter(Mandatory=$true,ParameterSetName='Install',HelpMessage="Enter primary domain name of Azure Tenant Directory")] [string]$AADDirectoryTenantName, [Parameter(Mandatory=$true, ParameterSetName='RegistrationJSON')] [Parameter(Mandatory=$true, ParameterSetName='Registration')] [pscredential] $RegistrationAccount, [Parameter(Mandatory=$true, ParameterSetName='Registration')] [Parameter(Mandatory=$true, ParameterSetName='RegistrationJSON')] [string] $RegistrationSubscriptionID ) $erroractionpreference = 'stop' Import-LocalizedData LocalizedData -BaseDirectory $PSScriptRoot -Filename Microsoft.AzureStack.AzureValidation.Strings.psd1 $null = Import-Module $PSSCriptRoot\Microsoft.AzureStack.AzureValidation.Internal.psm1 -force # Check Azure Module exist and prompt to install if not if (-not ((Get-Module AzureRM* -ListAvailable) -AND (Get-Module *AzureStack* -ListAvailable))) { Write-Log -message ($LocalizedData.MissingAzureRMPSModules) -function $thisFunction -type Error throw $LocalizedData.MissingAzureRMPSModules } $null = Import-Module $PSSCriptRoot\AzureADConfiguration.psm1 -Force -Global $thisFunction = $MyInvocation.MyCommand.Name $paramToString = ($PSBoundParameters.GetEnumerator() | ForEach-Object { "$($_.Key)=$($_.Value)" }) -join ';' Write-Log -message ('AadHelper Started with: {0}' -f $paramToString) -function $thisFunction Write-Log -message ('AadHelper Started with parameter set {0}' -f ($PSCmdlet.ParameterSetName -join ',')) -function $thisFunction if ($PSCmdlet.ParameterSetName -match 'RegistrationJSON|InstallJSON') { # Make sure JSON is good try { $deploymentDataJSON = Get-Content $deploymentDataJSONPath | ConvertFrom-Json Write-Log -message ("Deployment JSON read from {0}" -f $deploymentDataJSONPath) -function $thisFunction } catch { if ($_.exception -like '*Invalid JSON primitive*') { Write-Log -message ($LocalizedData.InvalidJSON -f $deploymentDataJSONPath) -function $thisFunction -type Error throw $LocalizedData.InvalidJSON } } $AzureEnvironment = $deploymentDataJSON.DeploymentData.InfraAzureEnvironment $AADDirectoryTenantName = $deploymentDataJSON.DeploymentData.InfraAzureDirectoryTenantName } # Check install criteria if ($PSCmdlet.ParameterSetName -like 'Install*') { $serviceAdministratorOutput = @{} $loginResult = Test-AzureRMAccountWrapper -credential $AADServiceAdministrator -AzureEnvironment $AzureEnvironment -AADDirectoryTenantName $AADDirectoryTenantName if ($loginResult.result -eq 'OK') { Write-Host "Checking Installation Requirements: " -nonewline $serviceAdministratorOutput = Test-AzsServiceAdministrator -AADServiceAdministrator $AADServiceAdministrator -AzureEnvironment $AzureEnvironment -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} } } else { Write-Host "OK" -foregroundColor Green } } $serviceAdministratorOutput.Add('AzureAccountLogon',($loginResult | Where-Object {$_.Assets.credential -eq $AADServiceAdministrator.UserName})) $serviceAdministratorOutput } # Check registration criteria if ($PSCmdlet.ParameterSetName -like 'Registration*') { try { $registrationOutput = @{} $loginResult = Test-AzureRMAccountWrapper -credential $RegistrationAccount -AzureEnvironment $AzureEnvironment if ($loginResult.result -eq 'OK') { Write-Host "Checking Registration Requirements: " -nonewline $tenantid = $loginResult.Assets.AADDirectoryTenantName $registrationSubscription = Get-AzureSubscriptionDetail -tenantid $tenantid -subscriptionid $RegistrationSubscriptionID -credential $RegistrationAccount -AzureEnvironment $AzureEnvironment if (-not $registrationSubscription.errordetails) { $registrationOutput = Test-AzsRegistrationAccount -subscription $registrationSubscription.subscription -subscriptionId $RegistrationSubscriptionID if ($registrationOutput.result -ne 'OK') { Write-Host "Fail " -foregroundColor Red Write-Host ("Error Details for registration account {0}:" -f $registrationAccount.Username) $registrationOutput.errorDetails | ForEach-Object {Write-Host "$_" -foregroundcolor Yellow} } else { Write-Host "OK" -foregroundColor Green } } else { Write-Host "Fail " -foregroundColor Red Write-Host ("Error Details for registration account {0}:" -f $registrationAccount.Username) $registrationSubscription.errorDetails | ForEach-Object {Write-Host "$_" -foregroundcolor Yellow} } } $registrationOutput.Add('AzureAccountLogon',($loginResult | Where-Object {$_.Assets.credential -eq $RegistrationAccount.UserName})) $registrationOutput.Add('SubscriptionDetail',$registrationSubscription) $registrationOutput } catch { $errorDetail = ("Checking Registration failed with: {0}" -f $_.exception) Write-Host ("Error Details for registration account {0}:" -f $registrationAccount.Username) $errorDetail | ForEach-Object {Write-Host "$_" -foregroundcolor Yellow} } } } # SIG # Begin signature block # MIIdqAYJKoZIhvcNAQcCoIIdmTCCHZUCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU+vSyAtSvUpDS8uZISrcU57K1 # q3ygghhUMIIEwjCCA6qgAwIBAgITMwAAAMDeLD0HlORJeQAAAAAAwDANBgkqhkiG # 9w0BAQUFADB3MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4G # A1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSEw # HwYDVQQDExhNaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EwHhcNMTYwOTA3MTc1ODUw # WhcNMTgwOTA3MTc1ODUwWjCBsjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp # bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw # b3JhdGlvbjEMMAoGA1UECxMDQU9DMScwJQYDVQQLEx5uQ2lwaGVyIERTRSBFU046 # N0FCNS0yREYyLURBM0YxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNl # cnZpY2UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDoiKVSfklVAB4E # Oc9+r95kl32muXNITYcTbaRtuJl+MQzEnD0eU2JUXx2mI06ONnTfFW39ZQPF1pvU # WkHBrS6m8oKy7Em4Ol91RJ5Knwy1VvY2Tawqh+VxwdARRgOeFtFm0S+Pa+BrXtVU # hTtGl0BGMsKGEQKdDNGJD259Iq47qPLw3CmllE3/YFw1GGoJ9C3ry+I7ntxIjJYB # LXA122vw93OOD/zWFh1SVq2AejPxcjKtHH2hjoeTKwkFeMNtIekrUSvhbuCGxW5r # 54KW0Yus4o8392l9Vz8lSEn2j/TgPTqD6EZlzkpw54VSwede/vyqgZIrRbat0bAh # b8doY8vDAgMBAAGjggEJMIIBBTAdBgNVHQ4EFgQUFf5K2jOJ0xmF1WRZxNxTQRBP # tzUwHwYDVR0jBBgwFoAUIzT42VJGcArtQPt2+7MrsMM1sw8wVAYDVR0fBE0wSzBJ # oEegRYZDaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMv # TWljcm9zb2Z0VGltZVN0YW1wUENBLmNybDBYBggrBgEFBQcBAQRMMEowSAYIKwYB # BQUHMAKGPGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljcm9z # b2Z0VGltZVN0YW1wUENBLmNydDATBgNVHSUEDDAKBggrBgEFBQcDCDANBgkqhkiG # 9w0BAQUFAAOCAQEAGeJAuzJMR+kovMi8RK/LtfrKazWlR5Lx02hM9GFmMk1zWCSc # pfVY6xqfzWFllCFHBtOaJZqLiV97jfNCLpG0PULz24CWSkG7jJ+mZaCSicZ7ZC3b # WDh1zpc54llYVyyTkRVYx/mtc9GujqbS8CBZgjaT/JsECnvGAPUcLYuSGt53CU1b # UuiNwuzAhai4glcYyq3/7qMmmAtbnbCZhR5ySoMy7BwdzN70drLtafCJQncfAHXV # O5r6SX4U/2J2zvWhA8lqhZu9SRulFGRvf81VTf+k5rJ2TjL6dYtSchooJ5YVvUk6 # i7bfV0VBN8xpaUhk8jbBnxhDPKIvDvnZlhPuJjCCBgEwggPpoAMCAQICEzMAAADE # 6Yn4eoFQ6f8AAAAAAMQwDQYJKoZIhvcNAQELBQAwfjELMAkGA1UEBhMCVVMxEzAR # BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p # Y3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9zb2Z0IENvZGUgU2ln # bmluZyBQQ0EgMjAxMTAeFw0xNzA4MTEyMDIwMjRaFw0xODA4MTEyMDIwMjRaMHQx # CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt # b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xHjAcBgNVBAMTFU1p # Y3Jvc29mdCBDb3Jwb3JhdGlvbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC # ggEBAIiKuCTDB4+agHkV/CZg/HKILPr0o5eIlka3o8tfiS86My4ekXj6fKkfggG1 # essavAPKRuvFmff7BB3yhQr/Im6h8mc9xScY5Sgf9QSUQWPs47oVjO0TmjXeOHBU # bzvsrUUJMEnBvo8wmQzLdsn3c5UWd9GLu5THCIUg7R6oNfFxwuB0AEuK0tyR69Z4 # /o36rWCIPb25H65il7/FhLGQrtavK9NU+zXazXGS5h7/7HFry38IdnTgEFFI1PEA # yEhMowc15VkN/XycyOZa44X11poPH46m5IQXwdbKnx0Bx/1IpxOSM5chSDL4wiSi # ALK+U8qDbilbge84boDzu+wTC+sCAwEAAaOCAYAwggF8MB8GA1UdJQQYMBYGCisG # AQQBgjdMCAEGCCsGAQUFBwMDMB0GA1UdDgQWBBTL1mKEz2A56v9nwlzSyLurt8MT # mDBSBgNVHREESzBJpEcwRTENMAsGA1UECxMETU9QUjE0MDIGA1UEBRMrMjMwMDEy # K2M4MDRiNWVhLTQ5YjQtNDIzOC04MzYyLWQ4NTFmYTIyNTRmYzAfBgNVHSMEGDAW # gBRIbmTlUAXTgqoXNzcitW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8v # d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIw # MTEtMDctMDguY3JsMGEGCCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDov # L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDEx # XzIwMTEtMDctMDguY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB # AAYWH9tXwlDII0+iUXjX7fj9zb3VwPH5G1btU8hpRwXVxMvs4vyZW5VfETgowAVF # E+CaeYi8Zqvbu+sCVSO3PSN4QW2u+PEAWpSZihzMCZXQmhxEMKmlFse6R1v1KzSL # n49YN8NOHK8iyhDN2IIQqTXwriLIjySmgYvfJxzkZh2JPi7/VwNNwW6DoDLrtLMv # UFZdBrEVjMgdY7dzDOPWeiYPKpZFpzKDPpY+V0l3I4n+sRDHiuUIFVHFK1oxWzlq # lqikiGuWKG/xxK7qvUUXzGJOgbVUGkeOmKVtwG4nxvgnH8jtIKkLsfHOC5qU4mqd # aYOhNtdtIP6F1f/DuJc2Cf49FMGYFKnAhszvgsGrVSRDGLVIhXiG0PnSnT8Z2RSJ # 542faCSIaDupx4BOJucIIUxj/ZyTFU0ztVZgT9dKuTiO/y7dsV+kQ2vJeM+xu2uP # g2yHcqrqpfuf3RrWOfxkyW0+COV8g7GtvKO6e8+WVqR6WMsSR2LSIe/8PMQxC/cv # PmSlN29gUD+3RJBPoAuLvn5Y9sdnh2HbnpjEyIzLb0fhwC6U7bH2sDBt7GpJqOmW # dsi9CMT+O/WuczcGslbPGdS79ZTKhxzygGoBT7YbgXOz01siPzpYGN+I7mfESacv # 3CWLPV7Q7DREkR28kQx2gj7vxNgtoQQCjkj5790CzwOiMIIGBzCCA++gAwIBAgIK # YRZoNAAAAAAAHDANBgkqhkiG9w0BAQUFADBfMRMwEQYKCZImiZPyLGQBGRYDY29t # MRkwFwYKCZImiZPyLGQBGRYJbWljcm9zb2Z0MS0wKwYDVQQDEyRNaWNyb3NvZnQg # Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDcwNDAzMTI1MzA5WhcNMjEw # NDAzMTMwMzA5WjB3MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQ # MA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9u # MSEwHwYDVQQDExhNaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EwggEiMA0GCSqGSIb3 # DQEBAQUAA4IBDwAwggEKAoIBAQCfoWyx39tIkip8ay4Z4b3i48WZUSNQrc7dGE4k # D+7Rp9FMrXQwIBHrB9VUlRVJlBtCkq6YXDAm2gBr6Hu97IkHD/cOBJjwicwfyzMk # h53y9GccLPx754gd6udOo6HBI1PKjfpFzwnQXq/QsEIEovmmbJNn1yjcRlOwhtDl # KEYuJ6yGT1VSDOQDLPtqkJAwbofzWTCd+n7Wl7PoIZd++NIT8wi3U21StEWQn0gA # SkdmEScpZqiX5NMGgUqi+YSnEUcUCYKfhO1VeP4Bmh1QCIUAEDBG7bfeI0a7xC1U # n68eeEExd8yb3zuDk6FhArUdDbH895uyAc4iS1T/+QXDwiALAgMBAAGjggGrMIIB # pzAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQjNPjZUkZwCu1A+3b7syuwwzWz # DzALBgNVHQ8EBAMCAYYwEAYJKwYBBAGCNxUBBAMCAQAwgZgGA1UdIwSBkDCBjYAU # DqyCYEBWJ5flJRP8KuEKU5VZ5KShY6RhMF8xEzARBgoJkiaJk/IsZAEZFgNjb20x # GTAXBgoJkiaJk/IsZAEZFgltaWNyb3NvZnQxLTArBgNVBAMTJE1pY3Jvc29mdCBS # b290IENlcnRpZmljYXRlIEF1dGhvcml0eYIQea0WoUqgpa1Mc1j0BxMuZTBQBgNV # HR8ESTBHMEWgQ6BBhj9odHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9w # cm9kdWN0cy9taWNyb3NvZnRyb290Y2VydC5jcmwwVAYIKwYBBQUHAQEESDBGMEQG # CCsGAQUFBzAChjhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01p # Y3Jvc29mdFJvb3RDZXJ0LmNydDATBgNVHSUEDDAKBggrBgEFBQcDCDANBgkqhkiG # 9w0BAQUFAAOCAgEAEJeKw1wDRDbd6bStd9vOeVFNAbEudHFbbQwTq86+e4+4LtQS # ooxtYrhXAstOIBNQmd16QOJXu69YmhzhHQGGrLt48ovQ7DsB7uK+jwoFyI1I4vBT # Fd1Pq5Lk541q1YDB5pTyBi+FA+mRKiQicPv2/OR4mS4N9wficLwYTp2Oawpylbih # OZxnLcVRDupiXD8WmIsgP+IHGjL5zDFKdjE9K3ILyOpwPf+FChPfwgphjvDXuBfr # Tot/xTUrXqO/67x9C0J71FNyIe4wyrt4ZVxbARcKFA7S2hSY9Ty5ZlizLS/n+YWG # zFFW6J1wlGysOUzU9nm/qhh6YinvopspNAZ3GmLJPR5tH4LwC8csu89Ds+X57H21 # 46SodDW4TsVxIxImdgs8UoxxWkZDFLyzs7BNZ8ifQv+AeSGAnhUwZuhCEl4ayJ4i # IdBD6Svpu/RIzCzU2DKATCYqSCRfWupW76bemZ3KOm+9gSd0BhHudiG/m4LBJ1S2 # sWo9iaF2YbRuoROmv6pH8BJv/YoybLL+31HIjCPJZr2dHYcSZAI9La9Zj7jkIeW1 # sMpjtHhUBdRBLlCslLCleKuzoJZ1GtmShxN1Ii8yqAhuoFuMJb+g74TKIdbrHk/J # mu5J4PcBZW+JC33Iacjmbuqnl84xKf8OxVtc2E0bodj6L54/LlUWa8kTo/0wggd6 # MIIFYqADAgECAgphDpDSAAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQG # EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG # A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQg # Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDla # Fw0yNjA3MDgyMTA5MDlaMH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5n # dG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9y # YXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEw # ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS6 # 8rZYIZ9CGypr6VpQqrgGOBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15 # ZId+lGAkbK+eSZzpaF7S35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+er # CFDPs0S3XdjELgN1q2jzy23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVc # eaVJKecNvqATd76UPe/74ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGM # XeiJT4Qa8qEvWeSQOy2uM1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/ # U7qcD60ZI4TL9LoDho33X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwj # p6lm7GEfauEoSZ1fiOIlXdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwC # gl/bwBWzvRvUVUvnOaEP6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1J # MKerjt/sW5+v/N2wZuLBl4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3co # KPHtbcMojyyPQDdPweGFRInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfe # nk70lrC8RqBsmNLg1oiMCwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAw # HQYDVR0OBBYEFEhuZOVQBdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoA # UwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQY # MBaAFHItOgIxkEO5FAVO4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6 # Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1 # dDIwMTFfMjAxMV8wM18yMi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAC # hkJodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1 # dDIwMTFfMjAxMV8wM18yMi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4D # MIGDMD8GCCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3Bz # L2RvY3MvcHJpbWFyeWNwcy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBs # AF8AcABvAGwAaQBjAHkAXwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcN # AQELBQADggIBAGfyhqWY4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjD # ctFtg/6+P+gKyju/R6mj82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw # /WvjPgcuKZvmPRul1LUdd5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkF # DJvtaPpoLpWgKj8qa1hJYx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3z # Dq+ZKJeYTQ49C/IIidYfwzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEn # Gn+x9Cf43iw6IGmYslmJaG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1F # p3blQCplo8NdUmKGwx1jNpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0Qax # dR8UvmFhtfDcxhsEvt9Bxw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AAp # xbGbpT9Fdx41xtKiop96eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//W # syNodeav+vyL6wuA6mk7r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqx # P/uozKRdwaGIm1dxVk5IRcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIEvjCC # BLoCAQEwgZUwfjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAO # BgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEo # MCYGA1UEAxMfTWljcm9zb2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAMTp # ifh6gVDp/wAAAAAAxDAJBgUrDgMCGgUAoIHSMBkGCSqGSIb3DQEJAzEMBgorBgEE # AYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMCMGCSqGSIb3DQEJ # BDEWBBT4vmRAIS/8IDranoAH3YuKiLOmITByBgorBgEEAYI3AgEMMWQwYqBIgEYA # TQBpAGMAcgBvAHMAbwBmAHQAIABBAHoAdQByAGUAUwB0AGEAYwBrACAAUABhAHIA # dABuAGUAcgBUAG8AbwBsAGsAaQB0oRaAFGh0dHA6Ly9Db2RlU2lnbkluZm8gMA0G # CSqGSIb3DQEBAQUABIIBADE4AW6qIVSEkK9OtkJ8y6zUAbnMBqglWCptGdLAbhfB # ZcAY//X0EOoxeSP7UZS+hvD/EjQEt8655CSP4/7f0AGAxKFKVFHTwWtyfYWFrW/n # m/pBdsArXEXWlZe4VwynXwV+9NLilx5fyLleZ7SPb1kH3NEa45DEnTYXDU6F+Yv/ # qLhGrymQYQYcxGsc40iAGQbYQ81NV9ZsWjhK07uWzRJXDltuu76G5dk4KxTjlBlA # 1NrcBlydfiEnmNs/SasyPauQkaiGKcZNckQewHr/ckmPwq9hFkFOAZSb7Y2eMFGc # yS7Akr8r8jL2UMAGkmdYyY3rF14JyiBx2pmVgPj5sA+hggIoMIICJAYJKoZIhvcN # AQkGMYICFTCCAhECAQEwgY4wdzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp # bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw # b3JhdGlvbjEhMB8GA1UEAxMYTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBAhMzAAAA # wN4sPQeU5El5AAAAAADAMAkGBSsOAwIaBQCgXTAYBgkqhkiG9w0BCQMxCwYJKoZI # hvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xODA0MjcwOTI5MzBaMCMGCSqGSIb3DQEJ # BDEWBBS0OtVD2uSyXUwX8eJO+3+rE7oC3jANBgkqhkiG9w0BAQUFAASCAQBsvz12 # L9yQG7UkF4fGsbxl1HMS+DP0gFFI9sZ4SdQlTS/E0CNXTHuKd1qht+uR6UPHUmPm # zDNvOtN6pSLOQ4Ew/fApNKHNOwZdhWaiNKG4R16VVNwYKo5cMMre/kBrjQ5qyqWx # gI+ZyOZeXVmC9TUmNIwvk7GWQ7ZCTDayTJAQDK31gtbbsCNN3VoTbu7WTymlyqfp # /NooSXqUNaYZW1FSEQV3ZH2RZcEi2t2klHwAC3ZBkEyjhsSo8u9SXx6g7y02dLOg # EtndbAG4o0IpCj7YmJPK6hbBbC8LWZ85wPNkdNUZEnOu9KVv9N1mW0JYEXMmpJYV # mayyeohs75serHFM # SIG # End signature block |