Microsoft.FastTrack.Migration.psm1
$location = (gci $($SCRIPT:MyInvocation.MyCommand.Path)).DirectoryName Import-Module $location\Microsoft.FastTrack.Migration.Security.dll -WarningAction:Continue [array] $importedModules = "FastTrack-GDPR-RequestDsr","FastTrack-TransactionQuery","FastTrack-RecipientManagement","FastTrack-ScheduleManagement","FastTrack-KeyVaultRequests","FastTrack-CsiManagement" $SelectedAuthorizationRole = "Production" $DevApplicationID = "47bbabd4-d4ef-4842-922f-835839488d7c" $UatApplicationID = "606a4358-ad5a-42fc-b178-603ed0e1740a" $ProdApplicationID = "a6f3096b-d6ba-4b0c-b73b-b5b0e358285b" $DevResourceUri = "https://microsoft.com/2505d69d-c321-44f1-a6ac-4ea35139d37a" $UatResourceUri = "https://microsoft.com/60798afa-9459-421f-864f-93faf9956111" $ProdResourceUri = "https://microsoft.com/5c0ba7b1-60bb-4b68-b7e8-1fe485344d5a" $global:CsiApiBaseUriFormat = "https://msft-{0}-{1}.azurewebsites.net/api/{2}" $global:MsftApiKey = "" $global:MsftAccessToken = "" $global:MsoAdminProperties = @{} $global:MsoSovereignCloud = "AzureCloud" $global:MsoComOrGov = "Commercial" $global:UseVerbose = $false $global:v2FeatureFlag = $false Function VersionCheck { if( $SCRIPT:SelectedAuthorizationRole.Equals("Production", [System.StringComparison]::CurrentCultureIgnoreCase) -ne $true){ Write-Host "Checking module's published version for ALPHA..." -ForegroundColor Cyan $publishedVersion = Find-Module -Name "Microsoft.FastTrack.Migration" -AllowPrerelease Write-Host "Checking module's installed version for ALPHA..." -ForegroundColor Cyan $currentVersion = Get-InstalledModule -Name "Microsoft.FastTrack.Migration" -AllowPrerelease } else{ Write-Host "Checking module's published version..." -ForegroundColor Cyan $publishedVersion = Find-Module -Name "Microsoft.FastTrack.Migration" Write-Host "Checking module's installed version..." -ForegroundColor Cyan $currentVersion = Get-InstalledModule -Name "Microsoft.FastTrack.Migration" } if($publishedVersion.Version -gt $currentVersion.Version){ Write-Warning "The current installed version [ $($currentVersion.Version) ] is older than the published version [ $($publishedVersion.Version) ]!" Write-Warning "It is required that you update to the current published version before continuing" Write-Warning "Please close this PowerShell session and restart in administrator mode then call `"Update-Module Microsoft.FastTrack.Migration`"" $false } else { $true } } Function SetAccessTokenHash { param ( [string] $ApiKey, [string] $TenantID ) $StringBuilder = [System.Text.StringBuilder]::new() [System.Security.Cryptography.HashAlgorithm]::Create("SHA512").ComputeHash([System.Text.Encoding]::UTF8.GetBytes($TenantId + $ApiKey)) | %{ [Void] $StringBuilder.Append($_.ToString("x2")) } return $StringBuilder.ToString().ToUpper() } Function SetAzureEnvironmentProperties { <# .SYNOPSIS Set environment for user .DESCRIPTION The Set-FastTrackEnvironment cmdlet sets the properties for the cloud environment in which to connect. The default environment is AzureCloud. If your organization is within another Azure environment, use the -Environment switch and select the appropriate environment. .PARAMETER Azure Environment to utilize for all API calls and program environment specific requirements. .EXAMPLE SetAzureEnvironmentProperties -AzureEnvironment $AzureEnvironment .INPUTS System.String .OUTPUTS None .LINK #> param ( [string] $AzureEnvironment ) switch ( $AzureEnvironment ) { "AzureCloud" { $global:MsoSovereignCloud = 'AzureCloud' $global:MsoComOrGov = "Commercial" } "AzureGermanCloud" { $global:MsoSovereignCloud = 'AzureGermanyCloud' $global:MsoComOrGov = "AzureGermanyCloud" } } } Function Login-FastTrackAccount { <# .SYNOPSIS Connect to Azure with an authenticated account for use with FastTrack Customer Service cmdlet requests. .DESCRIPTION The Login-FasttrackAccount cmdlet connects to Azure with an authenticated account for use with FastTrack Customer Service cmdlet requests. The default Azure environment is AzureCloud. If your organization is within another Azure environment, use the -Environment switch and select the appropriate environment. .PARAMETER Environment Specifies the organizations Azure Cloud environment. "AzureCloud" is the default. Valid options: AzureCloud | AzureGermanCloud System.String .OUTPUTS System.Management.Automation.PSObject This cmdlet generates a System.Management.Automation.PSObject. .EXAMPLE Login-FastTrackAccount .LINK Set-FastTrackEnvironment #> param ( [Parameter(Mandatory=$false,ValueFromPipeline=$true)] [string] $Environment = "AzureCloud" ) [array]$environments = "AzureCloud","AzureGermanCloud" $ApiKey = "0000000000" $isCurrent = VersionCheck if($isCurrent -ne $true){ return; } if($global:MsoAdminProperties.Count -gt 0) { Write-Warning "Unable to authenticate for Office 365 credentials!" Write-Warning "You must first remove the current PowerShell session before attempting another login..." return } if ($Environment -ne $null) { if ($environments.Contains($Environment)) { SetAzureEnvironmentProperties -AzureEnvironment $Environment } else { Write-Warning "Invalid [Environment] provided." Write-Warning "Please use one of the following options [AzureCloud | AzureGermanCloud]" return } } InitiateAzureADConnect if($global:MsoAdminProperties.Count -eq 0) { Write-Warning "Unable to retrieve Office 365 credentials!" Write-Warning "If you are attempting to login to an alternate Azure cloud environment, you must first call function [Set-FastTrackEnvironment]" } else { if($global:v2FeatureFlag -eq $true) { $ApiKey = "0000000000" } $global:MsftApiKey = $ApiKey $global:MsftAccessToken = (SetAccessTokenHash -ApiKey: $ApiKey -TenantID: $global:MsoAdminProperties["MSO-CompanyTenantInfo"]) $emailId=$MsoAdminProperties["MSO-LoggedOnUser"].Account if($SCRIPT:SelectedAuthorizationRole -eq "Development" -or $SCRIPT:SelectedAuthorizationRole -eq "UserAcceptanceTesting") { $global:roleBasedFeatureFlag = Get-FastTrackFeatureFlag ` -LdClientSdkKey "sdk-8cc4425d-ba53-4867-a53c-2d1bf1c4702d" ` -LdClientFeatureFlagKey "role-based-multitenancy" ` -LdClientFeatureFlagUser "$emailId" } else { $global:roleBasedFeatureFlag = Get-FastTrackFeatureFlag ` -LdClientSdkKey "sdk-11c6282a-5e6d-41e5-b8b8-7437740ba0b2" ` -LdClientFeatureFlagKey "role-based-multitenancy" ` -LdClientFeatureFlagUser "$emailId" } if($global:roleBasedFeatureFlag -eq $true) { Select-FastTrackAuthorizedTenant } Write-Host -ForegroundColor:Green "You have successfully logged into Office 365 as Tenant: $($global:MsoAdminProperties["MSO-CompanyInfo"].DisplayName)" Write-Host -ForegroundColor:Green "Run the following command to see a list of available functions." Write-Host -ForegroundColor:Green " Get-Command *FastTrack*" } } Function Set-FastTrackAuthorizationRole { <# .SYNOPSIS Set the Azure Active Directory corresponding to environment - DEFAULT is production .DESCRIPTION The default environment is Production. If you are wanting to test within another DEV or UAT, use the -AuthorizationRole switch and select the appropriate role. .PARAMETER AuthorizationRole Specifies the AuthorizationRole. "Production" is the default. Valid options: Development | UserAcceptanceTesting | Production .INPUTS System.String .OUTPUTS void .EXAMPLE Set-FastTrackAuthorizationRole .LINK Login-FastTrackAccount #> param( [Parameter(Mandatory=$false,ValueFromPipeline=$true)] [ValidateSet("Development","UserAcceptanceTesting", "Production")] [string] $AuthorizationRole = "Production" ) $SCRIPT:SelectedAuthorizationRole = $AuthorizationRole Write-Host "The Authorization Role has been set to [$SCRIPT:SelectedAuthorizationRole]" -ForegroundColor:Green } Function Set-FastTrackEnvironment { <# .SYNOPSIS Set the Azure cloud corresponding to your subscription .DESCRIPTION The Set-FastTrackEnvironment cmdlet sets the properties for the cloud environment in which to connect. The default environment is AzureCloud. If your organization is within another Azure environment, use the -Environment switch and select the appropriate environment. .PARAMETER AzureEnvironment Specifies the organizations Azure Cloud environment. "AzureCloud" is the default. Valid options: AzureCloud | AzureGermanCloud .INPUTS System.String .OUTPUTS System.Management.Automation.PSObject This cmdlet generates a System.Management.Automation.PSObject object that represents the Transaction ID. .EXAMPLE Set-FastTrackEnvironment .LINK Login-FastTrackAccount #> param( [Parameter(Mandatory=$false,ValueFromPipeline=$true)] [ValidateSet("AzureCloud","AzureGermanCloud")] [string] $AzureEnvironment = "AzureCloud" ) SetAzureEnvironmentProperties -AzureEnvironment $AzureEnvironment } function InitiateAzureADConnect { <# .SYNOPSIS Login for Azure AD .DESCRIPTION The InitiateAzureADConnect cmdlet performs login operations for Azure AD. .PARAMETER Credential used for Azure login and requires username and password information .EXAMPLE InitiateAzureADConnect -Credential $credentials .INPUTS PScredential .OUTPUTS None .LINK #> param ( [Parameter(Mandatory=$false,ValueFromPipeline=$true)] [pscredential] $Credential ) $CatchError = "" try { $resourceUri = "" $applicationId = "" switch($SCRIPT:SelectedAuthorizationRole) { "Development" { $resourceUri = $DevResourceUri $applicationId = $DevApplicationID } "UserAcceptanceTesting" { $resourceUri = $UatResourceUri $applicationId = $UatApplicationID } "Production" { $resourceUri = $ProdResourceUri $applicationId = $ProdApplicationID } } if($SCRIPT:SelectedAuthorizationRole -eq "Development" -or $SCRIPT:SelectedAuthorizationRole -eq "UserAcceptanceTesting") { $global:v2FeatureFlag = Get-FastTrackFeatureFlag ` -LdClientSdkKey "sdk-8cc4425d-ba53-4867-a53c-2d1bf1c4702d" ` -LdClientFeatureFlagKey "power-shell-multi-tenancy" ` -LdClientFeatureFlagUser "powershell-dev-uat" ` -Verbose:$global:UseVerbose $apiVersion = "" if($global:v2FeatureFlag -eq $true){ $apiVersion = "v2/"} if($SCRIPT:SelectedAuthorizationRole -eq "Development") { $global:CsiApiBaseUriFormat = [System.String]::Format($global:CsiApiBaseUriFormat, "cssp", "dev",$apiVersion) } else { $global:CsiApiBaseUriFormat = [System.String]::Format($global:CsiApiBaseUriFormat, "csi", "uat",$apiVersion) } } else { $global:v2FeatureFlag = Get-FastTrackFeatureFlag ` -LdClientSdkKey "sdk-11c6282a-5e6d-41e5-b8b8-7437740ba0b2" ` -LdClientFeatureFlagKey "power-shell-multi-tenancy" ` -LdClientFeatureFlagUser "powershell-prod" ` -Verbose:$global:UseVerbose $apiVersion = "" if($global:v2FeatureFlag -eq $true){ $apiVersion = "v2/"} $global:CsiApiBaseUriFormat = [System.String]::Format($global:CsiApiBaseUriFormat, "cssp", "prod",$apiVersion) } if($global:v2FeatureFlag -eq $true) { $multiTenantAuth = Connect-FastTrackLogin ` -ResourceUri $resourceUri ` -ApplicationReplyUrl:"https://login.live.com/oauth20_desktop.srf" ` -ApplicationID $applicationId ` -Verbose: $global:UseVerbose #We need to solve for GOV here still... $tenantInfo = $multiTenantAuth.UserInfo.IdentityProvider.Split("/")[$multiTenantAuth.UserInfo.IdentityProvider.Split("/").Count -2] $companyInfo = (New-Object PSObject | Add-Member -PassThru NoteProperty DisplayName ($multiTenantAuth.UserInfo.DisplayableId.Split("@".ToCharArray())[1])) $adminUser = $multiTenantAuth.UserInfo.DisplayableId $global:MsoAdminProperties.Add("AuthorizationResult", $multiTenantAuth) $global:MsoAdminProperties.Add("MSO-CompanyInfo",$companyInfo) $global:MsoAdminProperties.Add("MSO-CompanyTenantInfo",$tenantInfo.ToString().ToUpper()) $global:MsoAdminProperties.Add("MSO-AdminUser",$adminUser) $global:MsoAdminProperties.Add("MSO-LoggedOnUser", (New-Object PSObject | Add-Member -PassThru NoteProperty Account $multiTenantAuth.UserInfo.DisplayableId )) } else { Import-Module AzureAD $loggedOnUser = Connect-AzureAD -AzureEnvironmentName:$MsoSovereignCloud $AzureSkuInfo = Get-AzureADSubscribedSku -ErrorAction: SilentlyContinue if($AzureSkuInfo -ne $null -and $AzureSkuInfo.Where( { $_.SkuPartNumber.EndsWith("_GOV") }, 'First').Count -gt 0) { $global:MsoComOrGov = "Government" } else { $global:MsoComOrGov = "Commercial" } $tenantInfo = $loggedOnUser.TenantId $companyInfo = Get-AzureAdTenantDetail $role = Get-AzureADDirectoryRole | Where-Object { $_.DisplayName -eq "Company Administrator"} $adminUser = Get-AzureADDirectoryRoleMember -ObjectId $role.ObjectId | Where-Object { $_.UserPrincipalName -eq $loggedOnUser.Account } $global:MsoAdminProperties.Add("MSO-CompanyInfo",$companyInfo) $global:MsoAdminProperties.Add("MSO-CompanyTenantInfo",$tenantInfo.ToString().ToUpper()) $global:MsoAdminProperties.Add("MSO-AdminUser",$adminUser) $global:MsoAdminProperties.Add("MSO-LoggedOnUser", $loggedOnUser) } } catch { #Swallow exception - let parent method handle... } } # SIG # Begin signature block # MIIjhgYJKoZIhvcNAQcCoIIjdzCCI3MCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCA/HODlxwfNjXqx # EcGi1Kf5AUDrmrqkXGte3rPzVy6jUKCCDYEwggX/MIID56ADAgECAhMzAAABA14l # HJkfox64AAAAAAEDMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p # bmcgUENBIDIwMTEwHhcNMTgwNzEyMjAwODQ4WhcNMTkwNzI2MjAwODQ4WjB0MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB # AQDRlHY25oarNv5p+UZ8i4hQy5Bwf7BVqSQdfjnnBZ8PrHuXss5zCvvUmyRcFrU5 # 3Rt+M2wR/Dsm85iqXVNrqsPsE7jS789Xf8xly69NLjKxVitONAeJ/mkhvT5E+94S # nYW/fHaGfXKxdpth5opkTEbOttU6jHeTd2chnLZaBl5HhvU80QnKDT3NsumhUHjR # hIjiATwi/K+WCMxdmcDt66VamJL1yEBOanOv3uN0etNfRpe84mcod5mswQ4xFo8A # DwH+S15UD8rEZT8K46NG2/YsAzoZvmgFFpzmfzS/p4eNZTkmyWPU78XdvSX+/Sj0 # NIZ5rCrVXzCRO+QUauuxygQjAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUR77Ay+GmP/1l1jjyA123r3f3QP8w # UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1 # ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDM3OTY1MB8GA1UdIwQYMBaAFEhu # ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu # bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w # Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3 # Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx # MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAn/XJ # Uw0/DSbsokTYDdGfY5YGSz8eXMUzo6TDbK8fwAG662XsnjMQD6esW9S9kGEX5zHn # wya0rPUn00iThoj+EjWRZCLRay07qCwVlCnSN5bmNf8MzsgGFhaeJLHiOfluDnjY # DBu2KWAndjQkm925l3XLATutghIWIoCJFYS7mFAgsBcmhkmvzn1FFUM0ls+BXBgs # 1JPyZ6vic8g9o838Mh5gHOmwGzD7LLsHLpaEk0UoVFzNlv2g24HYtjDKQ7HzSMCy # RhxdXnYqWJ/U7vL0+khMtWGLsIxB6aq4nZD0/2pCD7k+6Q7slPyNgLt44yOneFuy # bR/5WcF9ttE5yXnggxxgCto9sNHtNr9FB+kbNm7lPTsFA6fUpyUSj+Z2oxOzRVpD # MYLa2ISuubAfdfX2HX1RETcn6LU1hHH3V6qu+olxyZjSnlpkdr6Mw30VapHxFPTy # 2TUxuNty+rR1yIibar+YRcdmstf/zpKQdeTr5obSyBvbJ8BblW9Jb1hdaSreU0v4 # 6Mp79mwV+QMZDxGFqk+av6pX3WDG9XEg9FGomsrp0es0Rz11+iLsVT9qGTlrEOla # P470I3gwsvKmOMs1jaqYWSRAuDpnpAdfoP7YO0kT+wzh7Qttg1DO8H8+4NkI6Iwh # SkHC3uuOW+4Dwx1ubuZUNWZncnwa6lL2IsRyP64wggd6MIIFYqADAgECAgphDpDS # 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/BvW1taslScxMNelDNMYIVWzCCFVcCAQEwgZUwfjELMAkG # A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx # HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z # b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAQNeJRyZH6MeuAAAAAABAzAN # BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor # BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgsZTNhANu # MMcjQTPYQReh+UsSFm35oOdd9YBFJ3r0lVMwQgYKKwYBBAGCNwIBDDE0MDKgFIAS # AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN # BgkqhkiG9w0BAQEFAASCAQAnKv8t4KmRJiIvmZgVkcP8vuF+ijzoim0UffnhEaaH # 4Penx2VQwqvetzrBZ1hA+zvseL7uYNVwc3yY/zZhMwiEkPDj6E4Mf/kYAnAR6cIq # OLvwrHtJ9B/aQHGpKRj5FCjNnr3orCNY2J+5Ylvgz3p0sNQZc7O9kkziWT/f1gYw # TJTykLeSWEaHtlRE3RIkRNi1NBQ+4YwrmbeQLx6fq86vqGiVTjUbFg/jeF+lWl8A # 45XOn7TxQLtvFAU2KcdOR67vUKRQGfcPdZR3tDSsJJs9uUvJs2IR9gNEPtnXQYBu # Eu6j5YyMqh7Ok+7e57QAUV+7enQv7SsR1JWMNSGxatxcoYIS5TCCEuEGCisGAQQB # gjcDAwExghLRMIISzQYJKoZIhvcNAQcCoIISvjCCEroCAQMxDzANBglghkgBZQME # AgEFADCCAVEGCyqGSIb3DQEJEAEEoIIBQASCATwwggE4AgEBBgorBgEEAYRZCgMB # MDEwDQYJYIZIAWUDBAIBBQAEIO+7Uv9FvXWAV5ChuA2ksXg3W3zvLoqdxSNUSbVT # 3TfVAgZcclcvOJ4YEzIwMTkwMzE5MjEzNTM1Ljk2M1owBIACAfSggdCkgc0wgcox # CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt # b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1p # Y3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMxJjAkBgNVBAsTHVRoYWxlcyBUU1Mg # RVNOOjEyQkMtRTNBRS03NEVCMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFt # cCBTZXJ2aWNloIIOPDCCBPEwggPZoAMCAQICEzMAAAD4wl8z0LWPFQQAAAAAAPgw # DQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0 # b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh # dGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwHhcN # MTgxMDI0MjExNDI5WhcNMjAwMTEwMjExNDI5WjCByjELMAkGA1UEBhMCVVMxEzAR # BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p # Y3Jvc29mdCBDb3Jwb3JhdGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2Eg # T3BlcmF0aW9uczEmMCQGA1UECxMdVGhhbGVzIFRTUyBFU046MTJCQy1FM0FFLTc0 # RUIxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2UwggEiMA0G # CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCWG4/+N8O+D28f14jQFJ4IelzVpAdF # yEORF2758iUItiMKXth0ydPSWoBcQOEG43o5VZyAIwKwxDnIlusmJvrvej1qWpMb # zw3x7DoZeiunALXxIUOXFDgUt7eMRG2LvAnpm8Df0Y3CNaKpWtBy5Loww48Fa0hs # 9VhNog6pXOEPuvBUf2nDM6s6NB9yDNVzoRVy25PkgbDakOG9XDII1IyiOZM1w4o1 # KBK6Ury8orZx5n/az2kb+HLc6WkoSK/ewrqyfToM2qLeX8hxeaI8nLMUvfspRKLe # q6tyUelFBZWBRE2Id42W03YHZpeuR5PGyU1jAeW1iXd2ZvQ03cfrzH4/AgMBAAGj # ggEbMIIBFzAdBgNVHQ4EFgQU7Jd2aCn+E0/NdMYlGPIAfNp916cwHwYDVR0jBBgw # FoAU1WM6XIoxkPNDe3xGG8UzaFqFbVUwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDov # L2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljVGltU3RhUENB # XzIwMTAtMDctMDEuY3JsMFoGCCsGAQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0 # cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNUaW1TdGFQQ0FfMjAx # MC0wNy0wMS5jcnQwDAYDVR0TAQH/BAIwADATBgNVHSUEDDAKBggrBgEFBQcDCDAN # BgkqhkiG9w0BAQsFAAOCAQEAqGTwfiwoXv5slFtdMIP9ESeh5btzNOZyD63KsYTd # WnUE+P7pQvo1Geg6IHAONJrSBZ4lpttMf78MzoTItciD7GAeOgAoIPFjKWv7ambS # WHN1bn3pmR1QYUpxar6Q5KoHyo1g24Lx+693JpRi98MFdEMmnLVTT3LA50mQZJXU # Y6gRqqHhTbu/AD/px4Lof5tue0U7R9FD3PL4FYUJOl+bpuAugeWOtCFJTvIEZR3Q # ym+xNTCimTu9VIYnkL1q9SRjjcN2os5ya6noSXf/frAGpbDIU7u6cFCeyPtJhjYC # NGwu6Fv4KYJxNhS+2sTD7McIhAz9b2pSzzhs+ebv4vq6tDCCBnEwggRZoAMCAQIC # 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/edIhJEqGCAs4wggI3AgEBMIH4oYHQpIHNMIHKMQswCQYDVQQGEwJVUzETMBEG # A1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWlj # cm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBP # cGVyYXRpb25zMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjoxMkJDLUUzQUUtNzRF # QjElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZaIjCgEBMAcG # BSsOAwIaAxUA+nMNJAAghSaP1+UmH9+BnvMDG5mggYMwgYCkfjB8MQswCQYDVQQG # EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG # A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQg # VGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIFAOA70GowIhgPMjAx # OTAzMjAwNDMyNDJaGA8yMDE5MDMyMTA0MzI0MlowdzA9BgorBgEEAYRZCgQBMS8w # LTAKAgUA4DvQagIBADAKAgEAAgIdZwIB/zAHAgEAAgISdjAKAgUA4D0h6gIBADA2 # BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIBAAIDB6EgoQowCAIB # AAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBAIdnKFqGo9CJuO+VnM2igczQexGU1xTi # L0XSYr5feqROdECz5SBCKtKRNDfqk97HCrnjjKnQRBmc/r8f2SBr3is3Xx0tnu/X # IXXIN94p/x8t57+FYclch/x2C4GYYC/N9Lj4ubmYs2lK0aeXpGUmsWACGcY+Qdmj # 8Ro1arxAEO4nMYIDDTCCAwkCAQEwgZMwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgT # Cldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29m # dCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENB # IDIwMTACEzMAAAD4wl8z0LWPFQQAAAAAAPgwDQYJYIZIAWUDBAIBBQCgggFKMBoG # CSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQxIgQgMaUm+g41 # URQlX0mdRoVctnOAvOccr2YFqS+eObA7CuUwgfoGCyqGSIb3DQEJEAIvMYHqMIHn # MIHkMIG9BCB0JO0yGE8zWtffR/JEnox2OlsEDxZrOHB9U6eRbXOcDjCBmDCBgKR+ # MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS # ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMT # HU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAA+MJfM9C1jxUEAAAA # AAD4MCIEIFL6Y+iRA4rV0JlwVH80vnF37WWHc0p5/wWBFYs1Gl7/MA0GCSqGSIb3 # DQEBCwUABIIBAJH8RnnBCAPurPNSHOxRgA+cnX6b17H80nYX4tlvmmLe+NjTJGCS # +Jy1JjvHYToKJurlDwhAFye6iUZkcFAAOt5Qb5GQffMq+tOAPwuzubIwxhnaDiRk # 7osLLWcP+ufJ4OqNa0UF/SCUXz5/sV/uHPnTUOQLwCAT9yZTJJH79AdY4RWlCzGl # gxO6HZbtAHQYLJjV0GGE20X+yzQ5iO6XFgJB13uuWxuA9OhcRBHTtCTT5siaDRMB # n2MT/5PAxCSR7CD8YTHn2LSdteWrQM/NeCbpCtq+YUYVjy1EGoOtj/dY7LNhwZ+h # hqg66wq3GK9yhCSkbI4kksXPvDJfPmllfMo= # SIG # End signature block |