Get-MsIdCrossTenantAccessActivity.ps1
<# .SYNOPSIS Gets cross tenant user sign-in activity .DESCRIPTION Gets user sign-in activity associated with external tenants. By default, shows both connections from local users access an external tenant (outbound), and external users accessing the local tenant (inbound). Has a parameter, -AccessDirection, to further refine results, using the following values: * Outboud - lists sign-in events of external tenant IDs accessed by local users * Inbound - list sign-in events of external tenant IDs of external users accessing local tenant Has a parameter, -ExternalTenantId, to target a single external tenant ID. Has a switch, -SummaryStats, to show summary statistics for each external tenant. This also works when targeting a single tenant. It is best to use this with Format-Table and Out-Gridview to ensure a table is produced. Has a switch, -ResolvelTenantId, to return additional details on the external tenant ID. -Verbose will give insight into the cmdlets activities. Requires AuditLog.Read.All scope, i.e. Connect-MgGraph -Scopes AuditLog.Read.All .EXAMPLE Get-MsIdCrossTenantAccessActivity Gets all available sign-in events for external users accessing resources in the local tenant and local users accessing resources in an external tenant. Lists by external tenant ID. .EXAMPLE Get-MsIdCrossTenantAccessActivity -ResolveTenantId -Verbose Gets all available sign-in events for external users accessing resources in the local tenant and local users accessing resources in an external tenant. Lists by external tenant ID. Attempts to resolve the external tenant ID GUID. Provides verbose output for insight into the cmdlet's execution. .EXAMPLE Get-MsIdCrossTenantAccessActivity -SummaryStats | Format-Table Provides a summary for sign-in information for the external tenant 3ce14667-9122-45f5-bcd4-f618957d9ba1, for both external users accessing resources in the local tenant and local users accessing resources in an external tenant. Use Format-Table to ensure a table is returned. .EXAMPLE Get-MsIdCrossTenantAccessActivity -ExternalTenantId 3ce14667-9122-45f5-bcd4-f618957d9ba1 Gets all available sign-in events for local users accessing resources in the external tenant 3ce14667-9122-45f5-bcd4-f618957d9ba1, and external users from tenant 3ce14667-9122-45f5-bcd4-f618957d9ba1 accessing resources in the local tenant. Lists by targeted external tenant. .EXAMPLE Get-MsIdCrossTenantAccessActivity -AccessDirection Outbound Gets all available sign-in events for local users accessing resources in an external tenant. Lists by unique external tenant. .EXAMPLE Get-MsIdCrossTenantAccessActivity -AccessDirection Outbound -Verbose Gets all available sign-in events for local users accessing resources in an external tenant. Lists by unique external tenant. Provides verbose output for insight into the cmdlet's execution. .EXAMPLE Get-MsIdCrossTenantAccessActivity -AccessDirection Outbound -SummaryStats -ResolveTenantId Provides a summary of sign-ins for local users accessing resources in an external tenant. Attempts to resolve the external tenant ID GUID. .EXAMPLE Get-MsIdCrossTenantAccessActivity -AccessDirection Outbound -ExternalTenantId 3ce14667-9122-45f5-bcd4-f618957d9ba1 Gets all available sign-in events for local users accessing resources in the external tenant 3ce14667-9122-45f5-bcd4-f618957d9ba1. Lists by unique external tenant. .EXAMPLE Get-MsIdCrossTenantAccessActivity -AccessDirection Inbound Gets all available sign-in events for external users accessing resources in the local tenant. Lists by unique external tenant. .EXAMPLE Get-MsIdCrossTenantAccessActivity -AccessDirection Inbound -Verbose Gets all available sign-in events for external users accessing resources in the local tenant. Lists by unique external tenant. Provides verbose output for insight into the cmdlet's execution. .EXAMPLE Get-MsIdCrossTenantAccessActivity -AccessDirection Inbound -SummaryStats | Out-Gridview Provides a summary of sign-ins for external users accessing resources in the local tenant. Use Out-Gridview to display a table in the Out-Gridview window. .EXAMPLE Get-MsIdCrossTenantAccessActivity -AccessDirection Inbound -ExternalTenantId 3ce14667-9122-45f5-bcd4-f618957d9ba1 Gets all available sign-in events for external user from external tenant 3ce14667-9122-45f5-bcd4-f618957d9ba1 accessing resources in the local tenant. Lists by unique external tenant. .NOTES THIS CODE-SAMPLE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. This sample is not supported under any Microsoft standard support program or service. The script is provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the script be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample or documentation, even if Microsoft has been advised of the possibility of such damages, rising out of the use of or inability to use the sample script, even if Microsoft has been advised of the possibility of such damages. #> function Get-MsIdCrossTenantAccessActivity { [CmdletBinding()] param( #Return events based on external tenant access direction, either 'Inbound', 'Outbound', or 'Both' [Parameter(Position = 0)] [ValidateSet('Inbound', 'Outbound')] [string]$AccessDirection, #Return events for the supplied external tenant ID [Parameter(Position = 1)] [guid]$ExternalTenantId, #Show summary statistics by tenant [switch]$SummaryStats, #Atemmpt to resolve the external tenant ID [switch]$ResolveTenantId ) begin { ## Initialize Critical Dependencies $CriticalError = $null try { #Import-Module Microsoft.Graph.Reports -ErrorAction Stop Import-Module Microsoft.Graph.Reports -MinimumVersion 1.9.2 -ErrorAction Stop } catch { Write-Error -ErrorRecord $_ -ErrorVariable CriticalError; return } #Connection and profile check Write-Verbose -Message "$(Get-Date -f T) - Checking connection..." if ($null -eq (Get-MgContext)) { Write-Error "$(Get-Date -f T) - Please connect to MS Graph API with the Connect-MgGraph cmdlet!" -ErrorAction Stop } else { Write-Verbose -Message "$(Get-Date -f T) - Checking profile..." if ((Get-MgProfile).Name -eq 'v1.0') { Write-Error "$(Get-Date -f T) - Current MGProfile is set to v1.0, and some cmdlets may need to use the beta profile. Run 'Select-MgProfile -Name beta' to switch to beta API profile" -ErrorAction Stop } } Write-Verbose -Message "$(Get-Date -f T) - Connection and profile OK" #External Tenant ID check if ($ExternalTenantId) { Write-Verbose -Message "$(Get-Date -f T) - Checking supplied external tenant ID - $ExternalTenantId..." if ($ExternalTenantId -eq (Get-MgContext).TenantId) { Write-Error "$(Get-Date -f T) - Supplied external tenant ID ($ExternalTenantId) cannot match connected tenant ID ($((Get-MgContext).TenantId)))" -ErrorAction Stop } else { Write-Verbose -Message "$(Get-Date -f T) - Supplied external tenant ID OK" } } } process { ## Return Immediately On Critical Error if ($CriticalError) { return } #Get filtered sign-in logs and handle parameters if ($AccessDirection -eq "Outbound") { if ($ExternalTenantId) { Write-Verbose -Message "$(Get-Date -f T) - Access direction 'Outbound' selected" Write-Verbose -Message "$(Get-Date -f T) - Outbound: getting sign-ins for local users accessing external tenant ID - $ExternalTenantId" $SignIns = Get-MgAuditLogSignIn -Filter ("ResourceTenantId eq '{0}'" -f $ExternalTenantId) -All:$True | Group-Object ResourceTenantID } else { Write-Verbose -Message "$(Get-Date -f T) - Access direction 'Outbound' selected" Write-Verbose -Message "$(Get-Date -f T) - Outbound: getting external tenant IDs accessed by local users" $SignIns = Get-MgAuditLogSignIn -Filter ("ResourceTenantId ne '{0}'" -f (Get-MgContext).TenantId) -All:$True | Group-Object ResourceTenantID } } elseif ($AccessDirection -eq 'Inbound') { if ($ExternalTenantId) { Write-Verbose -Message "$(Get-Date -f T) - Access direction 'Inbound' selected" Write-Verbose -Message "$(Get-Date -f T) - Inbound: getting sign-ins for users accessing local tenant from external tenant ID - $ExternalTenantId" $SignIns = Get-MgAuditLogSignIn -Filter ("HomeTenantId eq '{0}' and TokenIssuerType eq 'AzureAD'" -f $ExternalTenantId) -All:$True | Group-Object HomeTenantID } else { Write-Verbose -Message "$(Get-Date -f T) - Access direction 'Inbound' selected" Write-Verbose -Message "$(Get-Date -f T) - Inbound: getting external tenant IDs for external users accessing local tenant" $SignIns = Get-MgAuditLogSignIn -Filter ("HomeTenantId ne '{0}' and TokenIssuerType eq 'AzureAD'" -f (Get-MgContext).TenantId) -All:$True | Group-Object HomeTenantID } } else { if ($ExternalTenantId) { Write-Verbose -Message "$(Get-Date -f T) - Default access direction 'Both'" Write-Verbose -Message "$(Get-Date -f T) - Outbound: getting sign-ins for local users accessing external tenant ID - $ExternalTenantId" $Outbound = Get-MgAuditLogSignIn -Filter ("ResourceTenantId eq '{0}'" -f $ExternalTenantId) -All:$True | Group-Object ResourceTenantID Write-Verbose -Message "$(Get-Date -f T) - Inbound: getting sign-ins for users accessing local tenant from external tenant ID - $ExternalTenantId" $Inbound = Get-MgAuditLogSignIn -Filter ("HomeTenantId eq '{0}' and TokenIssuerType eq 'AzureAD'" -f $ExternalTenantId) -All:$True | Group-Object HomeTenantID } else { Write-Verbose -Message "$(Get-Date -f T) - Default access direction 'Both'" Write-Verbose -Message "$(Get-Date -f T) - Outbound: getting external tenant IDs accessed by local users" $Outbound = Get-MgAuditLogSignIn -Filter ("ResourceTenantId ne '{0}'" -f (Get-MgContext).TenantId) -All:$True | Group-Object ResourceTenantID Write-Verbose -Message "$(Get-Date -f T) - Inbound: getting external tenant IDs for external users accessing local tenant" $Inbound = Get-MgAuditLogSignIn -Filter ("HomeTenantId ne '{0}' and TokenIssuerType eq 'AzureAD'" -f (Get-MgContext).TenantId) -All:$True | Group-Object HomeTenantID } #Combine outbound and inbound results [array]$SignIns = $Outbound $SignIns += $Inbound } #Analyse sign-in logs Write-Verbose -Message "$(Get-Date -f T) - Checking for sign-ins..." if ($SignIns) { Write-Verbose -Message "$(Get-Date -f T) - Sign-ins obtained" Write-Verbose -Message "$(Get-Date -f T) - Iterating Sign-ins..." foreach ($TenantID in $SignIns) { #Handle resolving tenant ID if ($ResolveTenantId) { Write-Verbose -Message "$(Get-Date -f T) - Attempting to resolve external tenant - $($TenantId.Name)" #Nullify $ResolvedTenant value $ResolvedTenant = $null #Attempt to resolve tenant ID try { $ResolvedTenant = Resolve-MSIDTenant -TenantId $TenantId.Name -ErrorAction SilentlyContinue } catch { Write-Verbose -Message "$(Get-Date -f T) - Issue resolving external tenant - $($TenantId.Name)" } if ($ResolvedTenant) { if ($ResolvedTenant.Result -eq 'Resolved') { $ExternalTenantName = $ResolvedTenant.DisplayName $DefaultDomainName = $ResolvedTenant.DefaultDomainName } else { $ExternalTenantName = $ResolvedTenant.Result $DefaultDomainName = $ResolvedTenant.Result } if ($ResolvedTenant.oidcMetadataResult -eq 'Resolved') { $oidcMetadataTenantRegionScope = $ResolvedTenant.oidcMetadataTenantRegionScope } else { $oidcMetadataTenantRegionScope = 'NotFound' } } else { $ExternalTenantName = "NotFound" $DefaultDomainName = "NotFound" $oidcMetadataTenantRegionScope = 'NotFound' } } #Handle access direction if (($AccessDirection -eq 'Inbound') -or ($AccessDirection -eq 'Outbound')) { $Direction = $AccessDirection } else { if ($TenantID.Name -eq $TenantID.Group[0].HomeTenantId) { $Direction = "Inbound" } elseif ($TenantID.Name -eq $TenantID.Group[0].ResourceTenantId) { $Direction = "Outbound" } } #Provide summary if ($SummaryStats) { Write-Verbose -Message "$(Get-Date -f T) - Creating summary stats for external tenant - $($TenantId.Name)" #Handle resolving tenant ID if ($ResolveTenantId) { $Analysis = [pscustomobject]@{ ExternalTenantId = $TenantId.Name ExternalTenantName = $ExternalTenantName ExternalTenantRegionScope = $oidcMetadataTenantRegionScope AccessDirection = $Direction SignIns = ($TenantId).count SuccessSignIns = ($TenantID.Group.Status | Where-Object { $_.ErrorCode -eq 0 } | Measure-Object).count FailedSignIns = ($TenantID.Group.Status | Where-Object { $_.ErrorCode -ne 0 } | Measure-Object).count UniqueUsers = ($TenantID.Group | Select-Object UserId -Unique | Measure-Object).count UniqueResources = ($TenantID.Group | Select-Object ResourceId -Unique | Measure-Object).count } } else { #Build custom output object $Analysis = [pscustomobject]@{ ExternalTenantId = $TenantId.Name AccessDirection = $Direction SignIns = ($TenantId).count SuccessSignIns = ($TenantID.Group.Status | Where-Object { $_.ErrorCode -eq 0 } | Measure-Object).count FailedSignIns = ($TenantID.Group.Status | Where-Object { $_.ErrorCode -ne 0 } | Measure-Object).count UniqueUsers = ($TenantID.Group | Select-Object UserId -Unique | Measure-Object).count UniqueResources = ($TenantID.Group | Select-Object ResourceId -Unique | Measure-Object).count } } Write-Verbose -Message "$(Get-Date -f T) - Adding stats for $($TenantId.Name) to total analysis object" [array]$TotalAnalysis += $Analysis } else { #Get individual events by external tenant Write-Verbose -Message "$(Get-Date -f T) - Getting individual sign-in events for external tenant - $($TenantId.Name)" foreach ($Event in $TenantID.group) { if ($ResolveTenantId) { $CustomEvent = [pscustomobject]@{ ExternalTenantId = $TenantId.Name ExternalTenantName = $ExternalTenantName ExternalDefaultDomain = $DefaultDomainName ExternalTenantRegionScope = $oidcMetadataTenantRegionScope AccessDirection = $Direction UserDisplayName = $Event.UserDisplayName UserPrincipalName = $Event.UserPrincipalName UserId = $Event.UserId UserType = $Event.UserType CrossTenantAccessType = $Event.CrossTenantAccessType AppDisplayName = $Event.AppDisplayName AppId = $Event.AppId ResourceDisplayName = $Event.ResourceDisplayName ResourceId = $Event.ResourceId SignInId = $Event.Id CreatedDateTime = $Event.CreatedDateTime StatusCode = $Event.Status.Errorcode StatusReason = $Event.Status.FailureReason } $CustomEvent } else { $CustomEvent = [pscustomobject]@{ ExternalTenantId = $TenantId.Name AccessDirection = $Direction UserDisplayName = $Event.UserDisplayName UserPrincipalName = $Event.UserPrincipalName UserId = $Event.UserId UserType = $Event.UserType CrossTenantAccessType = $Event.CrossTenantAccessType AppDisplayName = $Event.AppDisplayName AppId = $Event.AppId ResourceDisplayName = $Event.ResourceDisplayName ResourceId = $Event.ResourceId SignInId = $Event.Id CreatedDateTime = $Event.CreatedDateTime StatusCode = $Event.Status.Errorcode StatusReason = $Event.Status.FailureReason } $CustomEvent } } } } } else { Write-Warning "$(Get-Date -f T) - No sign-ins matching the selected criteria found." } #Display summary table if ($SummaryStats) { #Show array of summary objects for each external tenant Write-Verbose -Message "$(Get-Date -f T) - Displaying total analysis object" if (!$AccessDirection) { $TotalAnalysis | Sort-Object ExternalTenantId } else { $TotalAnalysis | Sort-Object SignIns -Descending } } } } # SIG # Begin signature block # MIInugYJKoZIhvcNAQcCoIInqzCCJ6cCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCA22FQ8jNN1Fvqg # s4n9IlqRA2ppXvhSD+R8chj41dOhpqCCDYEwggX/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/BvW1taslScxMNelDNMYIZjzCCGYsCAQEwgZUwfjELMAkG # A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx # HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z # b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAlKLM6r4lfM52wAAAAACUjAN # BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor # BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgeGEF9Kbx # YnRAp5rEJt3T2QMCC5+D/yTyQzPY9IHzCvUwQgYKKwYBBAGCNwIBDDE0MDKgFIAS # AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN # BgkqhkiG9w0BAQEFAASCAQCJlS6C8e5gzTMSwnsYDhRU8yy5p5jW1AxeDzbkwOez # 3jce1EE1IunyrQZHZE9ZSMdBeUGiVQ0djWIdP91t2/T829LUnz5ShZVv6m7iFltQ # lJchdeaYFH8k+RCdH9Z39nd5cpLTz4EdtvANGsC6Jsx2uIRGrQ95NUum28ERxrwC # dZ6CMgc7X9ZiXsqjiZc7NhayArxeXZLOXXuX/rmOxt/WgR8eBtv9VVaVXYKHm5p7 # jJFxrRGwTDv/nepSpzNSix/n5M/Rlhb1rQggJ8nLJBgsyk3PMaTwDC23ZZ5NJEu7 # PEk+JUux1H0INS31xneeZtZyx+IfCU4oaOVnUoNQkVFhoYIXGTCCFxUGCisGAQQB # gjcDAwExghcFMIIXAQYJKoZIhvcNAQcCoIIW8jCCFu4CAQMxDzANBglghkgBZQME # AgEFADCCAVkGCyqGSIb3DQEJEAEEoIIBSASCAUQwggFAAgEBBgorBgEEAYRZCgMB # MDEwDQYJYIZIAWUDBAIBBQAEIMScwhOKqV3npqFqqWrOXpe0m7MzqZIY0A4spwC8 # DMBZAgZiF5dJyMcYEzIwMjIwMzEwMDMxNjIyLjcyNFowBIACAfSggdikgdUwgdIx # CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt # b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xLTArBgNVBAsTJE1p # Y3Jvc29mdCBJcmVsYW5kIE9wZXJhdGlvbnMgTGltaXRlZDEmMCQGA1UECxMdVGhh # bGVzIFRTUyBFU046RkM0MS00QkQ0LUQyMjAxJTAjBgNVBAMTHE1pY3Jvc29mdCBU # aW1lLVN0YW1wIFNlcnZpY2WgghFoMIIHFDCCBPygAwIBAgITMwAAAY5Z20YAqBCU # zAABAAABjjANBgkqhkiG9w0BAQsFADB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMK # V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0 # IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0Eg # MjAxMDAeFw0yMTEwMjgxOTI3NDVaFw0yMzAxMjYxOTI3NDVaMIHSMQswCQYDVQQG # EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG # A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQg # SXJlbGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJjAkBgNVBAsTHVRoYWxlcyBUU1Mg # RVNOOkZDNDEtNEJENC1EMjIwMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFt # cCBTZXJ2aWNlMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAqiMCq6OM # zLa5wrtcf7Bf9f1WXW9kpqbOBzgPJvaGLrZG7twgwqTRWf1FkjpJKBOG5QPIRy7a # 6IFVAy0W+tBaFX4In4DbBf2tGubyY9+hRU+hRewPJH5CYOvpPh77FfGM63+OlwRX # p5YER6tC0WRKn3mryWpt4CwADuGv0LD2QjnhhgtRVidsiDnn9+aLjMuNapUhstGq # Cr7JcQZt0ZrPUHW/TqTJymeU1eqgNorEbTed6UQyLaTVAmhXNQXDChfa526nW7RQ # 7L4tXX9Lc0oguiCSkPlu5drNA6NM8z+UXQOAHxVfIQXmi+Y3SV2hr2dcxby9nlTz # Yvf4ZDr5Wpcwt7tTdRIJibXHsXWMKrmOziliGDToLx34a/ctZE4NOLnlrKQWN9ZG # +Ox5zRarK1EhShahM0uQNhb6BJjp3+c0eNzMFJ2qLZqDp2/3Yl5Q+4k+MDHLTipP # 6VBdxcdVfd4mgrVTx3afO5KNfgMngGGfhSawGraRW28EhrLOspmIxii92E7vjncJ # 2tcjhLCjBArVpPh3cZG5g3ZVy5iiAaoDaswpNgnMFAK5Un1reK+MFhPi9iMnvUPw # tTDDJt5YED5DAT3mBUxp5QH3t7RhZwAJNLWLtpTeGF7ub81sSKYv2ardazAe9XLS # 10tV2oOPrcniGJzlXW7VPvxqQNxe8lCDA20CAwEAAaOCATYwggEyMB0GA1UdDgQW # BBTsQfkz9gT44N/5G8vNHayep+aV5DAfBgNVHSMEGDAWgBSfpxVdAF5iXYP05dJl # pxtTNRnpcjBfBgNVHR8EWDBWMFSgUqBQhk5odHRwOi8vd3d3Lm1pY3Jvc29mdC5j # b20vcGtpb3BzL2NybC9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENBJTIwMjAx # MCgxKS5jcmwwbAYIKwYBBQUHAQEEYDBeMFwGCCsGAQUFBzAChlBodHRwOi8vd3d3 # Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMFRpbWUtU3Rh # bXAlMjBQQ0ElMjAyMDEwKDEpLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoG # CCsGAQUFBwMIMA0GCSqGSIb3DQEBCwUAA4ICAQA1UK9xzIeTlKhSbLn0bekR5gYh # 6bB1XQpluCqCA15skZ37UilaFJw8+GklDLzlNhSP2mOiOzVyCq8kkpqnfUc01ZaB # ezQxg77qevj2iMyg39YJfeiCIhxYOFugwepYrPO8MlB/oue/VhIiDb1eNYTlPSmv # 3palsgtkrb0oo0F0uWmX4EQVGKRo0UENtZetVIxa0J9DpUdjQWPeEh9cEM+RgE26 # 5w5WAVb+WNx0iWiF4iTbCmrWaVEOX92dNqBm9bT1U7nGwN5CygpNAgEaYnrTMx1N # 4AjxObACDN5DdvGlu/O0DfMWVc6qk6iKDFC6WpXQSkMlrlXII/Nhp+0+noU6tfEp # HKLt7fYm9of5i/QomcCwo/ekiOCjYktp393ovoC1O2uLtbLnMVlE5raBLBNSbINZ # 6QLxiA41lXnVVLIzDihUL8MU9CMvG4sdbhk2FX8zvrsP5PeBIw1faenMZuz0V3UX # CtU5Okx5fmioWiiLZSCi1ljaxX+BEwQiinCi+vE59bTYI5FbuR8tDuGLiVu/JSpV # FXrzWMP2Kn11sCLAGEjqJYUmO1tRY29Kd7HcIj2niSB0PQOCjYlnCnywnDinqS1C # XvRsisjVlS1Rp4Tmuks+pGxiMGzF58zcb+hoFKyONuL3b+tgxTAz3sF3BVX9uk9M # 5F+OEoeyLyGfLekNAjCCB3EwggVZoAMCAQICEzMAAAAVxedrngKbSZkAAAAAABUw # DQYJKoZIhvcNAQELBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5n # dG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9y # YXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhv # cml0eSAyMDEwMB4XDTIxMDkzMDE4MjIyNVoXDTMwMDkzMDE4MzIyNVowfDELMAkG # A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx # HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9z # b2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw # ggIKAoICAQDk4aZM57RyIQt5osvXJHm9DtWC0/3unAcH0qlsTnXIyjVX9gF/bErg # 4r25PhdgM/9cT8dm95VTcVrifkpa/rg2Z4VGIwy1jRPPdzLAEBjoYH1qUoNEt6aO # RmsHFPPFdvWGUNzBRMhxXFExN6AKOG6N7dcP2CZTfDlhAnrEqv1yaa8dq6z2Nr41 # JmTamDu6GnszrYBbfowQHJ1S/rboYiXcag/PXfT+jlPP1uyFVk3v3byNpOORj7I5 # LFGc6XBpDco2LXCOMcg1KL3jtIckw+DJj361VI/c+gVVmG1oO5pGve2krnopN6zL # 64NF50ZuyjLVwIYwXE8s4mKyzbnijYjklqwBSru+cakXW2dg3viSkR4dPf0gz3N9 # QZpGdc3EXzTdEonW/aUgfX782Z5F37ZyL9t9X4C626p+Nuw2TPYrbqgSUei/BQOj # 0XOmTTd0lBw0gg/wEPK3Rxjtp+iZfD9M269ewvPV2HM9Q07BMzlMjgK8QmguEOqE # UUbi0b1qGFphAXPKZ6Je1yh2AuIzGHLXpyDwwvoSCtdjbwzJNmSLW6CmgyFdXzB0 # kZSU2LlQ+QuJYfM2BjUYhEfb3BvR/bLUHMVr9lxSUV0S2yW6r1AFemzFER1y7435 # UsSFF5PAPBXbGjfHCBUYP3irRbb1Hode2o+eFnJpxq57t7c+auIurQIDAQABo4IB # 3TCCAdkwEgYJKwYBBAGCNxUBBAUCAwEAATAjBgkrBgEEAYI3FQIEFgQUKqdS/mTE # mr6CkTxGNSnPEP8vBO4wHQYDVR0OBBYEFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMFwG # A1UdIARVMFMwUQYMKwYBBAGCN0yDfQEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly93 # d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTATBgNV # HSUEDDAKBggrBgEFBQcDCDAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNV # HQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo # 0T2UkFvXzpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29m # dC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5j # cmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jv # c29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDAN # BgkqhkiG9w0BAQsFAAOCAgEAnVV9/Cqt4SwfZwExJFvhnnJL/Klv6lwUtj5OR2R4 # sQaTlz0xM7U518JxNj/aZGx80HU5bbsPMeTCj/ts0aGUGCLu6WZnOlNN3Zi6th54 # 2DYunKmCVgADsAW+iehp4LoJ7nvfam++Kctu2D9IdQHZGN5tggz1bSNU5HhTdSRX # ud2f8449xvNo32X2pFaq95W2KFUn0CS9QKC/GbYSEhFdPSfgQJY4rPf5KYnDvBew # VIVCs/wMnosZiefwC2qBwoEZQhlSdYo2wh3DYXMuLGt7bj8sCXgU6ZGyqVvfSaN0 # DLzskYDSPeZKPmY7T7uG+jIa2Zb0j/aRAfbOxnT99kxybxCrdTDFNLB62FD+Cljd # QDzHVG2dY3RILLFORy3BFARxv2T5JL5zbcqOCb2zAVdJVGTZc9d/HltEAY5aGZFr # DZ+kKNxnGSgkujhLmm77IVRrakURR6nxt67I6IleT53S0Ex2tVdUCbFpAUR+fKFh # bHP+CrvsQWY9af3LwUFJfn6Tvsv4O+S3Fb+0zj6lMVGEvL8CwYKiexcdFYmNcP7n # tdAoGokLjzbaukz5m/8K6TT4JDVnK+ANuOaMmdbhIurwJ0I9JZTmdHRbatGePu1+ # oDEzfbzL6Xu/OHBE0ZDxyKs6ijoIYn/ZcGNTTY3ugm2lBRDBcQZqELQdVTNYs6Fw # ZvKhggLXMIICQAIBATCCAQChgdikgdUwgdIxCzAJBgNVBAYTAlVTMRMwEQYDVQQI # EwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3Nv # ZnQgQ29ycG9yYXRpb24xLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJh # dGlvbnMgTGltaXRlZDEmMCQGA1UECxMdVGhhbGVzIFRTUyBFU046RkM0MS00QkQ0 # LUQyMjAxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2WiIwoB # ATAHBgUrDgMCGgMVAD1iK+pPThHqgpa5xsPmiYruWVuMoIGDMIGApH4wfDELMAkG # A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx # HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9z # b2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwDQYJKoZIhvcNAQEFBQACBQDl0+COMCIY # DzIwMjIwMzEwMTAyNzI2WhgPMjAyMjAzMTExMDI3MjZaMHcwPQYKKwYBBAGEWQoE # ATEvMC0wCgIFAOXT4I4CAQAwCgIBAAICCfMCAf8wBwIBAAICEUwwCgIFAOXVMg4C # AQAwNgYKKwYBBAGEWQoEAjEoMCYwDAYKKwYBBAGEWQoDAqAKMAgCAQACAwehIKEK # MAgCAQACAwGGoDANBgkqhkiG9w0BAQUFAAOBgQCV0fbjXR+GPRtsdKGjlEssRwp/ # 41Lw0kVdYj2WckHFh7sfSKNDCbQRkzeZaT4tzFnmIfNLxKxRNfUpQM9EbcIiaDoV # nUrYdG0m5Rq+9PRdOCA4YaRjs7ctScKyMPeV94FupeKeYRD+VJ7fnEokhTrlt6J8 # WO8iUkqhP5QXo+dNHzGCBA0wggQJAgEBMIGTMHwxCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1w # IFBDQSAyMDEwAhMzAAABjlnbRgCoEJTMAAEAAAGOMA0GCWCGSAFlAwQCAQUAoIIB # SjAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwLwYJKoZIhvcNAQkEMSIEIJ/T # Va5KRmxzMX9IAi0vZGLZTCRG1f/EE9iwQVtZibq4MIH6BgsqhkiG9w0BCRACLzGB # 6jCB5zCB5DCBvQQgvQWPITvigaUuV5+f/lWs3BXZwJ/l1mf+yelu5nXmxCUwgZgw # gYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE # BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYD # VQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAY5Z20YAqBCU # zAABAAABjjAiBCDVI1KO+vv1e2Tie6w6iTLvjHDl0pWWHk1Kbm7ZofEWRzANBgkq # hkiG9w0BAQsFAASCAgAM6CV6bz4hygK7ESHSHYrg7jpvP49SXkFlUXwyKPQ3K7hV # QFzUWDwYI6qJsDjAiTJUVb1byuR/pAXVvUKCm+1LpI1uZtp33X3JvBj9cSEl8w9Q # ozVxHUdn7ZcVnpT5A3fu+EMcnRd/ztqy8rV8f/mTFSY232W8VmZjpnJOL48NQ1EK # 0SrtprSli2PeeNm3GaxoEZBxur/4UEaW3z3M4Whi66JSYwVjYl1PeytYyO9+H8Pn # Yru9wJnlDeIFT/k7Hd2xS9XlYPzGaAe9FMz9HY+D0YoVGasPcZnVY1qIgtUsOQcQ # Gbj1wrUxwpNfebnQAF6oVAX9NDpLvVBdmzukdW4VQlNtYWBmY4xdq/7e6+HvHiO2 # 4tGvVNkV9MwuxlDzLXAvo3Iq+b4xy+8ebHyD2sH4BG3St2EC7fvycuwsuMJM45lc # 8qOKlCs9/NwKkA2FYdMVSiEdWayUz/iXVmgLjk3xN7feocJRk12K/AxbV3vY2fxr # Z9K8xxUQz/nEdLfZi1JmISZsus+WTdoeDh5RYzSvkWVoORP89+Ddnqm51vW+xeCi # e91vhudoaarPa+kmkGSke5bSPS+Egh0yTutZ31MOjyYwBPIGQkUnFcp0Y5Vaumr2 # 58oq9/z9w31G2wgpRfBXg3ZE3ARaSaAfZ5had7C5YPF3QpQpCyiMX+jQW5+a7Q== # SIG # End signature block |