internal/xspm/Get-MtXspmUnifiedIdentityInfo.ps1
<#
.SYNOPSIS Check data from various XDR tables to identify users and workload identities with sensitive privileges and apply classification from community project EntraOps. .DESCRIPTION Executes KQL function over Advanced Hunting API to retrieves unified identity information from XDR, including user and workload identities with sensitive privileges. It applies classification from the EntraOps community project to identify critical assets and their roles. .EXAMPLE Get-MtXspmUnifiedIdentityInfo Returns a detailed list of user and workload identities with sensitive privileges, including their roles, classifications, and criticality levels. .LINK https://maester.dev/docs/commands/Get-MtXspmUnifiedIdentityInfo #> function Get-MtXspmUnifiedIdentityInfo { param ( [Parameter()] [switch]$ValidateRequiredTablesOnly = $false ) if (!$ValidateRequiredTablesOnly) { $Query = " // Define the UnifiedIdentityInfo function let Int_PrivilegedIdentityInfo = (UserPrincipalName:string='', ObjectId:string='', EntraRoleDefinitionName:string='', EntraRolePermission:string='', LookbackTimestamp:datetime=datetime(now)) { let SensitiveEntraDirectoryRoles = externaldata(RoleName: string, RoleId: string, isPrivileged: bool, Categories:string, Classification: dynamic, RolePermissions: dynamic)['https://raw.githubusercontent.com/Cloud-Architekt/AzurePrivilegedIAM/main/Classification/Classification_EntraIdDirectoryRoles.json'] with(format='multijson') | project RoleDefinitionName = RoleName, RoleIsPrivileged = isPrivileged, Classification, RoleCategories = Categories, RolePermissions; let IdentityInfoUpdateInterval = -14; let IdentityInfoLookbackWindow = datetime_add('day', IdentityInfoUpdateInterval, LookbackTimestamp); let AllEntraPimRoles = IdentityInfo | where tolower(AccountUpn) contains tolower(UserPrincipalName) and AccountObjectId contains (ObjectId) | where TimeGenerated >(IdentityInfoLookbackWindow) and TimeGenerated <(LookbackTimestamp) | summarize arg_max(TimeGenerated, *) by AccountObjectId | mv-expand parse_json(PrivilegedEntraPimRoles) | extend RoleDefinitionName = tostring(bag_keys(PrivilegedEntraPimRoles)[0]) | where RoleDefinitionName contains (EntraRoleDefinitionName) | extend PimAssignmentExpiration = tostring(PrivilegedEntraPimRoles[RoleDefinitionName][1]) | extend PimAssignmentType = tostring(PrivilegedEntraPimRoles[RoleDefinitionName][0]) | extend RoleAssignmentType = tostring(PrivilegedEntraPimRoles[RoleDefinitionName][2]) | project AccountObjectId, AccountUpn, RoleDefinitionName, RoleAssignmentType, PimAssignmentType, PimAssignmentExpiration | sort by AccountUpn, RoleDefinitionName; let EntraEligibleRoles = AllEntraPimRoles | where PimAssignmentType == 'Eligible' | sort by AccountUpn, RoleDefinitionName; let EntraActiveRoles = IdentityInfo | where tolower(AccountUpn) contains tolower(UserPrincipalName) or AccountObjectId contains (ObjectId) | where TimeGenerated >(IdentityInfoLookbackWindow) and TimeGenerated <(LookbackTimestamp) | summarize arg_max(TimeGenerated, *) by AccountObjectId | where isnotempty(AssignedRoles) | mv-expand parse_json(AssignedRoles) | extend RoleDefinitionName = tostring(AssignedRoles) | where RoleDefinitionName contains (EntraRoleDefinitionName) | join kind = leftouter ( AllEntraPimRoles | where PimAssignmentType == 'Assigned' ) on AccountObjectId, RoleDefinitionName | extend PimAssignmentExpiration = coalesce(PimAssignmentExpiration, 'Unknown') | extend PimAssignmentType = 'Active' | extend RoleAssignmentType = coalesce(RoleAssignmentType, 'Unknown') | project AccountObjectId, AccountUpn, RoleDefinitionName, RoleAssignmentType, PimAssignmentType, PimAssignmentExpiration | sort by AccountObjectId, RoleDefinitionName; let AllEntraRoles = union EntraEligibleRoles, EntraActiveRoles | where tolower(AccountUpn) contains tolower(UserPrincipalName) and AccountObjectId contains (ObjectId) | join kind=inner ( SensitiveEntraDirectoryRoles | where RolePermissions contains (EntraRolePermission) ) on RoleDefinitionName | extend AadDirectoryRoleTierLevels = parse_json(Classification.EAMTierLevelName) | extend Classification = case( AadDirectoryRoleTierLevels contains 'ControlPlane', 'ControlPlane', AadDirectoryRoleTierLevels contains 'ManagementPlane', 'ManagementPlane', AadDirectoryRoleTierLevels contains 'WorkloadPlane', 'WorkloadPlane', AadDirectoryRoleTierLevels contains 'UserAccess', 'UserAccess', 'Unclassified' ) | extend PimAssignmentType = iff(PimAssignmentType == 'Assigned', 'Active', PimAssignmentType) | project RoleAssignments = bag_pack_columns(RoleDefinitionName, RoleAssignmentType, PimAssignmentType, PimAssignmentExpiration, Classification, RoleIsPrivileged, RoleCategories, RolePermissions), AccountObjectId | summarize AssignedEntraRoles = make_set(RoleAssignments) by AccountObjectId; IdentityInfo | where tolower(AccountUpn) contains tolower(UserPrincipalName) and AccountObjectId contains (ObjectId) | where TimeGenerated >(IdentityInfoLookbackWindow) and TimeGenerated <(LookbackTimestamp) | summarize arg_max(TimeGenerated, *) by AccountObjectId | join kind=inner ( AllEntraRoles ) on AccountObjectId | project-away ReportId, AssignedRoles, PrivilegedEntraPimRoles, AccountObjectId1 | sort by AccountName asc | extend Classification = case( AssignedEntraRoles has 'ControlPlane', 'ControlPlane', AssignedEntraRoles has 'ManagementPlane', 'ManagementPlane', AssignedEntraRoles has 'WorkloadPlane', 'WorkloadPlane', AssignedEntraRoles has 'UserAccess', 'UserAccess', 'Unclassified' ) }; let Int_WorkloadIdentityInfoXdr = (ServicePrincipalName:string='', ServicePrincipalObjectId:guid=guid(null)) { let FirstPartyApps = externaldata(AppId: string, AppDisplayName: string, AppOwnerOrganizationId: string, Source:string) ['https://raw.githubusercontent.com/merill/microsoft-info/main/_info/MicrosoftApps.json'] with(format='multijson') | project OAuthAppId = AppId, AppOwnerTenantId = AppOwnerOrganizationId; let SensitiveEntraDirectoryRoles = externaldata(RoleName: string, RoleId: string, isPrivileged: bool, Categories:string, Classification: dynamic, RolePermissions: dynamic) ['https://raw.githubusercontent.com/Cloud-Architekt/AzurePrivilegedIAM/main/Classification/Classification_EntraIdDirectoryRoles.json'] with(format='multijson') | project RoleDefinitionName = RoleName, RoleId, RoleIsPrivileged = isPrivileged, Classification, RoleCategories = Categories, RolePermissions; let SensitiveMsGraphPermissions = externaldata(AppRoleDisplayName: string, AppRoleId: string, AppId: string, EAMTierLevelName: string, Category: string) ['https://raw.githubusercontent.com/Cloud-Architekt/AzurePrivilegedIAM/main/Classification/Classification_AppRoles.json'] with(format='multijson'); let PrivilegedAzureRoles = dynamic(['Owner','Contributor','Access Review Operator Service Role','Azure File Sync Administrator','Role Based Access Control Administrator','User Access Administrator']); let PrivilegedArmOperations = (externaldata(RoleAction:string) [@'https://raw.githubusercontent.com/Cloud-Architekt/AzurePrivilegedIAM/refs/heads/main/PrivilegedOperations/ArmApiRequest.csv'] with (format='csv', ignoreFirstRecord=true) ); let PrivilegedArmOperationsPattern = @'Microsoft\.Authorization/.*/action'; let PrivilegedGroupMinCriticalLevel = 2; IdentityInfo | where Type == 'ServiceAccount' and SourceProvider == 'AzureActiveDirectory' | where tolower(AccountDisplayName) contains tolower(ServicePrincipalName) and AccountObjectId contains tostring(ServicePrincipalObjectId) | where Timestamp >ago(14d) | summarize arg_max(Timestamp, *) by AccountObjectId | project ServicePrincipalName = AccountDisplayName, ServicePrincipalId = AccountObjectId, CriticalityLevel // Lookup for OAuth application details | lookup ( OAuthAppInfo | where Timestamp >ago(30d) | where tolower(AppName) contains tolower(ServicePrincipalName) and ServicePrincipalId contains tostring(ServicePrincipalObjectId) | extend OAuthAppInfoAppDisplayName = AppName | summarize arg_max(Timestamp, *) by ServicePrincipalId, OAuthAppInfoAppDisplayName ) on ServicePrincipalId // Lookup for Graph API Classification | lookup ( OAuthAppInfo | where Timestamp >ago(30d) | where tolower(AppName) contains tolower(ServicePrincipalName) and ServicePrincipalId contains tostring(ServicePrincipalObjectId) | summarize arg_max(Timestamp, *) by ServicePrincipalId | mv-expand parse_json(Permissions) | extend AppId = tostring(parse_json(Permissions)['TargetAppId']) | extend AppDisplayName = tostring(parse_json(Permissions)['TargetAppDisplayName']) | extend AppRoleDisplayName = tostring(parse_json(Permissions)['PermissionValue']) | extend PermissionType = tostring(parse_json(Permissions)['PermissionType']) | extend InUse = tostring(parse_json(Permissions)['InUse']) | extend PrivilegeLevel = tostring(parse_json(Permissions)['PrivilegeLevel']) | join kind = leftouter ( SensitiveMsGraphPermissions ) on AppId, AppRoleDisplayName | project-rename Classification = EAMTierLevelName | extend ApiPermission = bag_pack_columns(AppId, AppDisplayName, AppRoleId, AppRoleDisplayName, InUse, PrivilegeLevel, Category, Classification) | summarize ApiPermissions = make_set(ApiPermission) by ServicePrincipalId ) on ServicePrincipalId | project-away Permissions // Lookup for First Party App Status | join kind=leftouter ( FirstPartyApps ) on OAuthAppId, AppOwnerTenantId // Lookup for Permanent or Active Entra ID Roles with Classification to EntraOps | join kind=leftouter ( IdentityInfo | where Type == 'ServiceAccount' and SourceProvider == 'AzureActiveDirectory' | where Timestamp >ago(14d) | summarize arg_max(Timestamp, *) by AccountObjectId | where isnotempty(AssignedRoles) | mv-expand parse_json(AssignedRoles) | extend RoleDefinitionName = tostring(AssignedRoles) | join kind=inner ( SensitiveEntraDirectoryRoles ) on RoleDefinitionName | extend AadDirectoryRoleTierLevels = parse_json(Classification.EAMTierLevelName) | extend Classification = case( AadDirectoryRoleTierLevels contains 'ControlPlane', 'ControlPlane', AadDirectoryRoleTierLevels contains 'ManagementPlane', 'ManagementPlane', AadDirectoryRoleTierLevels contains 'WorkloadPlane', 'WorkloadPlane', AadDirectoryRoleTierLevels contains 'UserAccess', 'UserAccess', 'Unclassified' ) | extend PimAssignmentType = 'Active' // Details not available in IdentityInfo for Active/Permanent Assignments on SPs | extend PimAssignmentExpiration = 'Unknown' | extend RoleAssignmentType = 'Unknown' | project RoleAssignments = bag_pack_columns(RoleDefinitionName, RoleAssignmentType, PimAssignmentType, PimAssignmentExpiration, Classification, RoleIsPrivileged, RoleCategories, RolePermissions), ServicePrincipalId = AccountObjectId | summarize AssignedEntraRoles = make_set(RoleAssignments) by ServicePrincipalId ) on ServicePrincipalId // Lookup for Critical asset and Graph node details | join kind=leftouter ( ExposureGraphNodes | where NodeLabel == @'serviceprincipal' or NodeLabel == @'managedidentity' // AppId on some GraphNodes not available | extend AppId = parse_json(NodeProperties)['rawData']['appId'] // Fallback to ObjectId | mv-expand parse_json(EntityIds) | where parse_json(EntityIds).type == 'AadObjectId' | extend EntityId = tostring(parse_json(EntityIds).id) | extend ServicePrincipalId = tostring(extract('objectid=([\\w-]+)', 1, EntityId)) | extend ServicePrincipalType = tostring(parse_json(NodeProperties)['rawData']['servicePrincipalType']) | extend XspmCriticalAssetDetails = parse_json(NodeProperties)['rawData']['criticalityLevel'] | extend XspmGraphNodeDetails = bag_pack_columns(NodeId, NodeName, NodeLabel) | project ServicePrincipalId, ServicePrincipalType, XspmGraphNodeId = NodeId, XspmGraphNodeDetails, XspmCriticalAssetDetails ) on ServicePrincipalId // Lookup for Graph node details of OAuth App | join kind=leftouter ( ExposureGraphNodes | where NodeLabel == @'Microsoft Entra OAuth App' | mv-expand parse_json(EntityIds) | where parse_json(EntityIds).type == 'AadApplicationId' | extend OAuthAppId = tostring(parse_json(EntityIds).id) | extend XspmGraphOAuthAppNodeDetails = bag_pack_columns(NodeId, NodeName, NodeLabel) | project XspmGraphOAuthAppNodeDetails, OAuthAppId ) on OAuthAppId // Lookup for Azure roles from Graph edges | join kind=leftouter ( ExposureGraphEdges | where SourceNodeLabel == 'managedidentity' or SourceNodeLabel == 'serviceprincipal' | where EdgeLabel == @'has role on' | where parse_json(TargetNodeCategories) contains 'environmentAzure' | mv-expand parse_json(EdgeProperties)['rawData']['permissions']['roles'] | extend RoleDefinitionName = parse_json(EdgeProperties_rawData_permissions_roles)['name'] | extend RoleDefinitionId = parse_json(EdgeProperties_rawData_permissions_roles)['id'] | extend RoleAssignmentId = parse_json(EdgeProperties_rawData_permissions_roles)['roleAssignmentId'] | extend RoleActions = parse_json(EdgeProperties_rawData_permissions_roles)['actions'] | extend RoleIsPrivileged = iff(( RoleActions matches regex (PrivilegedArmOperationsPattern) or RoleActions has_any (PrivilegedArmOperations)) == true or RoleDefinitionName in~ (PrivilegedAzureRoles) or RoleActions[0] == '*', 'true', 'false') | extend IsOverProvisioned = parse_json(EdgeProperties)['rawData']['isOverProvisioned'] | extend IsIdentityInactive = parse_json(EdgeProperties)['rawData']['isIdentityInactive'] | project RoleAssignments = bag_pack_columns(RoleDefinitionName, RoleDefinitionId, RoleIsPrivileged, IsOverProvisioned, IsIdentityInactive), XspmGraphNodeId = SourceNodeId | summarize AssignedAzureRoles = make_set(RoleAssignments) by XspmGraphNodeId ) on XspmGraphNodeId // Lookup for Security Group assignments from Graph edges | join kind=leftouter ( ExposureGraphEdges | where SourceNodeLabel == 'managedidentity' or SourceNodeLabel == 'serviceprincipal' | where EdgeLabel == @'member of' | where TargetNodeLabel == @'group' | join kind=inner ( ExposureGraphNodes | mv-expand parse_json(EntityIds) | where parse_json(EntityIds).type == 'AadObjectId' | extend EntityId = tostring(parse_json(EntityIds).id) | extend GroupDisplayName = NodeName | extend GroupObjectId = tostring(extract('objectid=([\\w-]+)', 1, EntityId)) | extend XspmCriticalAssetDetails = parse_json(NodeProperties)['rawData']['criticalityLevel'] ) on `$left.TargetNodeId == `$right.NodeId | extend GroupIsPrivileged = iff( parse_json(XspmCriticalAssetDetails)['criticalityLevel'] <= PrivilegedGroupMinCriticalLevel or parse_json(XspmCriticalAssetDetails)['ruleBasedCriticalityLevel'] <= PrivilegedGroupMinCriticalLevel, 'true', 'false' ) | project RoleAssignments = bag_pack_columns(GroupDisplayName, GroupObjectId, GroupIsPrivileged), XspmGraphNodeId = SourceNodeId | summarize AssignedGroupMembership = make_set(RoleAssignments) by XspmGraphNodeId ) on XspmGraphNodeId // Lookup for Nodes with 'can authenticate as' relation from Graph edges (App Registration or Azure Resources with Managed Identities) | join kind=leftouter ( ExposureGraphEdges | where EdgeLabel == @'can authenticate as' | where TargetNodeLabel == @'managedidentity' or TargetNodeLabel == @'serviceprincipal' | join kind=leftouter ( ExposureGraphNodes | project SourceNodeId = NodeId, EntityIds ) on SourceNodeId | extend NodeId = SourceNodeId, NodeName = SourceNodeName, NodeLabel = SourceNodeLabel | extend AuthenticatedBy = bag_pack_columns(NodeId, NodeName, NodeLabel, EntityIds) | summarize AuthenticatedBy = make_set(AuthenticatedBy) by TargetNodeId ) on `$left.XspmGraphNodeId == `$right.TargetNodeId // Lookup for Ownership (currently limited to Application Objects) | extend XspmGraphOAuthAppNodeId = tostring(XspmGraphOAuthAppNodeDetails.NodeId) | join kind=leftouter ( ExposureGraphEdges | where EdgeLabel == @'has role on' // Currently limited to OAuth App edges | where TargetNodeLabel == 'Microsoft Entra OAuth App' | extend RolePermissions = parse_json(EdgeProperties)['rawData']['roles']['rolePermissions'] | mv-expand parse_json(RolePermissions) | where RolePermissions.['roleValue'] startswith 'Owner' | join kind=leftouter ( ExposureGraphNodes | project SourceNodeId = NodeId, EntityIds ) on SourceNodeId | extend NodeId = SourceNodeId, NodeName = SourceNodeName, NodeLabel = SourceNodeLabel | extend OwnedBy = bag_pack_columns(NodeId, NodeName, NodeLabel, EntityIds) | project-rename XspmGraphOAuthAppNodeId = TargetNodeId | summarize OwnedBy = make_set(OwnedBy) by XspmGraphOAuthAppNodeId ) on XspmGraphOAuthAppNodeId | extend CriticalityLevel = toint(parse_json(XspmCriticalAssetDetails)['criticalityLevel']) | project-away XspmGraphNodeId, XspmGraphNodeId1, ServicePrincipalId1, ServicePrincipalId2, XspmGraphNodeId1, XspmGraphNodeId2, TargetNodeId, XspmGraphOAuthAppNodeId, XspmGraphOAuthAppNodeId1 | extend ServicePrincipalName = coalesce(ServicePrincipalName, OAuthAppInfoAppDisplayName) | extend ServicePrincipalName = coalesce(ServicePrincipalName, ServicePrincipalId) | sort by ServicePrincipalName asc | project Timestamp, TimeGenerated, ServicePrincipalName, ServicePrincipalId, OAuthAppId, CriticalityLevel, AddedOnTime, LastModifiedTime, AppStatus, VerifiedPublisher, IsAdminConsented, AppOrigin, AppOwnerTenantId, ApiPermissions, AssignedAzureRoles, AssignedEntraRoles, AuthenticatedBy, OwnedBy | extend Classification = case( AssignedEntraRoles has 'ControlPlane' or ApiPermissions has 'ControlPlane', 'ControlPlane', AssignedEntraRoles has 'ManagementPlane' or ApiPermissions has 'ManagementPlane', 'ManagementPlane', AssignedEntraRoles has 'WorkloadPlane' or ApiPermissions has 'WorkloadPlane', 'WorkloadPlane', AssignedEntraRoles has 'UserAccess' or ApiPermissions has 'UserAccess', 'UserAccess', 'Unclassified' ) | sort by OAuthAppId }; let UnifiedIdentityInfoXdr = (ObjectName:string, ObjectId:guid, LookbackTimestamp:datetime=datetime(now)) { let PrivilegedUsers = Int_PrivilegedIdentityInfo(UserPrincipalName=tolower(ObjectName),ObjectId=tostring(ObjectId)) | where TimeGenerated > ago(14d) | where Type == 'User' | where tolower(AccountDisplayName) contains tolower(ObjectName) and AccountObjectId contains tostring(ObjectId) | extend OnPremSynchronized = iff(isnotempty(OnPremObjectId), 'true', 'false') | extend IsDeleted = iff(isnotempty(DeletedDateTime), 'true', 'false'); let AllWorkloads = Int_WorkloadIdentityInfoXdr(ServicePrincipalName=tolower(ObjectName),ServicePrincipalObjectId=tostring(ObjectId)) | extend Type = 'Workload' | project-rename AccountObjectId = ServicePrincipalId, AccountDisplayName = ServicePrincipalName; let IdentityInfoUpdateInterval = -14; let IdentityInfoLookbackWindow = datetime_add('day', IdentityInfoUpdateInterval, LookbackTimestamp); let AllUsers = IdentityInfo | where TimeGenerated >(IdentityInfoLookbackWindow) and TimeGenerated <(LookbackTimestamp) | summarize arg_max(TimeGenerated, *) by AccountObjectId | where Type == 'User' | where tolower(AccountDisplayName) contains tolower(ObjectName) and AccountObjectId contains tostring(ObjectId) | summarize arg_max(TimeGenerated, *) by AccountObjectId | join kind=anti (PrivilegedUsers | where TimeGenerated > ago(14d)) on AccountObjectId | extend OnPremSynchronized = iff(isnotempty(OnPremObjectId), 'true', 'false') | extend IsDeleted = iff(isnotempty(DeletedDateTime), 'true', 'false') | project-away ReportId, AssignedRoles, PrivilegedEntraPimRoles; union AllUsers, PrivilegedUsers, AllWorkloads | extend AppId = OAuthAppId | extend Classification = case( isnotempty(Classification), Classification, TenantMembershipType == 'Member', 'UserAccess', TenantMembershipType == 'Guest' or AccountUpn contains '#EXT#@', 'ExternalAccess', 'Unclassified' ) | join kind = leftouter ( ExposureGraphNodes | mv-expand EntityIds | extend EntityType = parse_json(EntityIds) | where EntityType['type'] == 'AadObjectId' or EntityType['type'] == 'AzureResourceId' | mv-expand CriticalityData = parse_json(NodeProperties)['rawData']['criticalityLevel']['ruleNames'] | extend CriticalityLevel = tostring(parse_json(NodeProperties)['rawData']['criticalityLevel']['criticalityLevel']) | extend RuleName = tostring(CriticalityData) | extend ObjectId = iff(EntityType['type'] == 'AadObjectId', tolower(tostring(extract('objectid=([\\w-]+)', 1, tostring(parse_json(EntityIds)['id'])))), tolower(tostring(EntityType['id']))) | extend CrticialAssetDetail = bag_pack_columns(CriticalityLevel, RuleName) | summarize CrticialAssetDetails = make_set_if(CrticialAssetDetail, tostring(CrticialAssetDetail) !contains '') by AccountObjectId = ObjectId ) on AccountObjectId | project-reorder AccountObjectId, AccountDisplayName, Type, CriticalityLevel, CrticialAssetDetails, Classification, AssignedAzureRoles, AssignedEntraRoles, ApiPermissions; }; // Lookback feature is limited to user identities only UnifiedIdentityInfoXdr(ObjectName='',ObjectId='',LookbackTimestamp=datetime(now)) " $XspmUnifiedIdentityInfoResult = Invoke-MtGraphSecurityQuery -Query $Query -Timespan "P14D" if ( $XspmUnifiedIdentityInfoResult ) { return $XspmUnifiedIdentityInfoResult } } else { Write-Verbose "Checking prerequisites for Test-MtXspmAppRegWithPrivilegedApiAndOwners" $AdvancedIdentityAvailable = ((Invoke-MtGraphRequest -ApiVersion "beta" -RelativeUri "security/runHuntingQuery" -Method POST ` -ErrorAction SilentlyContinue ` -Body (@{"Query" = "IdentityInfo | getschema | where ColumnName == 'PrivilegedEntraPimRoles'" } | ConvertTo-Json) ` -OutputType PSObject).results.ColumnName -eq "PrivilegedEntraPimRoles") $OAuthAppInfoAvailable = ((Invoke-MtGraphRequest -ApiVersion "beta" -RelativeUri "security/runHuntingQuery" -Method POST ` -ErrorAction SilentlyContinue ` -Body (@{"Query" = "OAuthAppInfo | getschema" } | ConvertTo-Json) ` -OutputType PSObject).results.ColumnName -contains "OAuthAppId") $UnifiedIdentityInfoExecutable = $AdvancedIdentityAvailable -and $OAuthAppInfoAvailable Write-Verbose "UnifiedIdentityInfoExecutable is $UnifiedIdentityInfoExecutable (IdentityInfo is $AdvancedIdentityAvailable, $OAuthAppInfoAvailable)" return $UnifiedIdentityInfoExecutable } } # SIG # Begin signature block # MIIu5QYJKoZIhvcNAQcCoIIu1jCCLtICAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBYRn6fAN25P2O6 # i0IV/LKFBOTn9GP3LVbyh9JYWDncPKCCE5EwggWQMIIDeKADAgECAhAFmxtXno4h # MuI5B72nd3VcMA0GCSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNV # BAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0xMzA4MDExMjAwMDBaFw0z # ODAxMTUxMjAwMDBaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ # bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0 # IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB # AL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3EMB/z # G6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKyunWZ # anMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsFxl7s # Wxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU15zHL # 2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJBMtfb # BHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObURWBf3 # JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6nj3c # AORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxBYKqx # YxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5SUUd0 # viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+xq4aL # T8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjQjBAMA8GA1Ud # EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTs1+OC0nFdZEzf # Lmc/57qYrhwPTzANBgkqhkiG9w0BAQwFAAOCAgEAu2HZfalsvhfEkRvDoaIAjeNk # aA9Wz3eucPn9mkqZucl4XAwMX+TmFClWCzZJXURj4K2clhhmGyMNPXnpbWvWVPjS # PMFDQK4dUPVS/JA7u5iZaWvHwaeoaKQn3J35J64whbn2Z006Po9ZOSJTROvIXQPK # 7VB6fWIhCoDIc2bRoAVgX+iltKevqPdtNZx8WorWojiZ83iL9E3SIAveBO6Mm0eB # cg3AFDLvMFkuruBx8lbkapdvklBtlo1oepqyNhR6BvIkuQkRUNcIsbiJeoQjYUIp # 5aPNoiBB19GcZNnqJqGLFNdMGbJQQXE9P01wI4YMStyB0swylIQNCAmXHE/A7msg # dDDS4Dk0EIUhFQEI6FUy3nFJ2SgXUE3mvk3RdazQyvtBuEOlqtPDBURPLDab4vri # RbgjU2wGb2dVf0a1TD9uKFp5JtKkqGKX0h7i7UqLvBv9R0oN32dmfrJbQdA75PQ7 # 9ARj6e/CVABRoIoqyc54zNXqhwQYs86vSYiv85KZtrPmYQ/ShQDnUBrkG5WdGaG5 # nLGbsQAe79APT0JsyQq87kP6OnGlyE0mpTX9iV28hWIdMtKgK1TtmlfB2/oQzxm3 # i0objwG2J5VT6LaJbVu8aNQj6ItRolb58KaAoNYes7wPD1N1KarqE3fk3oyBIa0H # EEcRrYc9B9F1vM/zZn4wggawMIIEmKADAgECAhAIrUCyYNKcTJ9ezam9k67ZMA0G # CSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ # bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0 # IFRydXN0ZWQgUm9vdCBHNDAeFw0yMTA0MjkwMDAwMDBaFw0zNjA0MjgyMzU5NTla # MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE # AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz # ODQgMjAyMSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDVtC9C # 0CiteLdd1TlZG7GIQvUzjOs9gZdwxbvEhSYwn6SOaNhc9es0JAfhS0/TeEP0F9ce # 2vnS1WcaUk8OoVf8iJnBkcyBAz5NcCRks43iCH00fUyAVxJrQ5qZ8sU7H/Lvy0da # E6ZMswEgJfMQ04uy+wjwiuCdCcBlp/qYgEk1hz1RGeiQIXhFLqGfLOEYwhrMxe6T # SXBCMo/7xuoc82VokaJNTIIRSFJo3hC9FFdd6BgTZcV/sk+FLEikVoQ11vkunKoA # FdE3/hoGlMJ8yOobMubKwvSnowMOdKWvObarYBLj6Na59zHh3K3kGKDYwSNHR7Oh # D26jq22YBoMbt2pnLdK9RBqSEIGPsDsJ18ebMlrC/2pgVItJwZPt4bRc4G/rJvmM # 1bL5OBDm6s6R9b7T+2+TYTRcvJNFKIM2KmYoX7BzzosmJQayg9Rc9hUZTO1i4F4z # 8ujo7AqnsAMrkbI2eb73rQgedaZlzLvjSFDzd5Ea/ttQokbIYViY9XwCFjyDKK05 # huzUtw1T0PhH5nUwjewwk3YUpltLXXRhTT8SkXbev1jLchApQfDVxW0mdmgRQRNY # mtwmKwH0iU1Z23jPgUo+QEdfyYFQc4UQIyFZYIpkVMHMIRroOBl8ZhzNeDhFMJlP # /2NPTLuqDQhTQXxYPUez+rbsjDIJAsxsPAxWEQIDAQABo4IBWTCCAVUwEgYDVR0T # AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHwYD # VR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMG # A1UdJQQMMAoGCCsGAQUFBwMDMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYY # aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2Fj # ZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNV # HR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRU # cnVzdGVkUm9vdEc0LmNybDAcBgNVHSAEFTATMAcGBWeBDAEDMAgGBmeBDAEEATAN # BgkqhkiG9w0BAQwFAAOCAgEAOiNEPY0Idu6PvDqZ01bgAhql+Eg08yy25nRm95Ry # sQDKr2wwJxMSnpBEn0v9nqN8JtU3vDpdSG2V1T9J9Ce7FoFFUP2cvbaF4HZ+N3HL # IvdaqpDP9ZNq4+sg0dVQeYiaiorBtr2hSBh+3NiAGhEZGM1hmYFW9snjdufE5Btf # Q/g+lP92OT2e1JnPSt0o618moZVYSNUa/tcnP/2Q0XaG3RywYFzzDaju4ImhvTnh # OE7abrs2nfvlIVNaw8rpavGiPttDuDPITzgUkpn13c5UbdldAhQfQDN8A+KVssIh # dXNSy0bYxDQcoqVLjc1vdjcshT8azibpGL6QB7BDf5WIIIJw8MzK7/0pNVwfiThV # 9zeKiwmhywvpMRr/LhlcOXHhvpynCgbWJme3kuZOX956rEnPLqR0kq3bPKSchh/j # wVYbKyP/j7XqiHtwa+aguv06P0WmxOgWkVKLQcBIhEuWTatEQOON8BUozu3xGFYH # Ki8QxAwIZDwzj64ojDzLj4gLDb879M4ee47vtevLt/B3E+bnKD+sEq6lLyJsQfmC # XBVmzGwOysWGw/YmMwwHS6DTBwJqakAwSEs0qFEgu60bhQjiWQ1tygVQK+pKHJ6l # /aCnHwZ05/LWUpD9r4VIIflXO7ScA+2GRfS0YW6/aOImYIbqyK+p/pQd52MbOoZW # eE4wggdFMIIFLaADAgECAhAP1Kd7fuviGgjvj8ZCqpTVMA0GCSqGSIb3DQEBCwUA # MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE # AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz # ODQgMjAyMSBDQTEwHhcNMjUwNDEwMDAwMDAwWhcNMjgwNzA2MjM1OTU5WjBNMQsw # CQYDVQQGEwJERTEQMA4GA1UEBxMHSGFtYnVyZzEVMBMGA1UEChMMRmFiaWFuIEJh # ZGVyMRUwEwYDVQQDEwxGYWJpYW4gQmFkZXIwggIiMA0GCSqGSIb3DQEBAQUAA4IC # DwAwggIKAoICAQCJI0Z1dyHcnutVp/vdHkC2p3oq9xB8JqGYqLRMR/SoBLgI5i+V # 3AWxu45/ue9MKtlBRlV5d7UAgVoFd9E/aB/aExr0Oj69sPmuI+O2zPozn6UMc9ci # tp8L2JRHNpN9KWuA06dmUD/VYPRgqmNtGQFW57XaEJ8klHPDxGuigxzudqJveifK # QjRoRlSileoVhyjlt6tEyorfRgd1VVWFxkso1qVEjn3ucml+DzrA+ZKiDp//C8+N # TMu9qMecEsXWPk4qhCla7MO1XpDJb8NE/4WY+PYFrwpxSwiBisWlpA8cgf7i7dhI # 4P9kTMZz8Cl5OB8/DrsZuv0Fxwmmu88b4uo7nI3HwzfnU/wkNO92g8cywdXHgMDp # IT++srZXnSQG+Pc4TFAQ8dHHBHxabqTSoZpNYQXQySVSvbpavpcAOhgBg4x2gefD # Y7Y+iEoLXxwFMIQE908pFHj6+iLlmiKHWLt5eSXtwXoJ83XykFlUXTQ9WW+eo9YI # lB0GZrwq/4g6nx7mWVG3lIcbfF7oDLUt1d7FhqhWHboYTlRMfkVpOz3TCjma9PY3 # R34n7ejn6cF+kkBK6EX3otlmBtb2sXdPModfceLJbfoU0X1la5tExpQjDHbQ8p/5 # HZLFQ0aGe7BDqBKW3HvIQjw81KMUXBToYvODHXiTNlQl1AZHpZCAf/YnKQIDAQAB # o4ICAzCCAf8wHwYDVR0jBBgwFoAUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHQYDVR0O # BBYEFM+bqr/hMxUPyRKDe3JjUSSVDqK/MD4GA1UdIAQ3MDUwMwYGZ4EMAQQBMCkw # JwYIKwYBBQUHAgEWG2h0dHA6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAOBgNVHQ8B # Af8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwgbUGA1UdHwSBrTCBqjBToFGg # T4ZNaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0Q29k # ZVNpZ25pbmdSU0E0MDk2U0hBMzg0MjAyMUNBMS5jcmwwU6BRoE+GTWh0dHA6Ly9j # cmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNB # NDA5NlNIQTM4NDIwMjFDQTEuY3JsMIGUBggrBgEFBQcBAQSBhzCBhDAkBggrBgEF # BQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMFwGCCsGAQUFBzAChlBodHRw # Oi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRDb2RlU2ln # bmluZ1JTQTQwOTZTSEEzODQyMDIxQ0ExLmNydDAJBgNVHRMEAjAAMA0GCSqGSIb3 # DQEBCwUAA4ICAQBKBhy38Rsh6QNW5pFN6JD9MFjRO9NBJGtwVo1J4/DGrtBVQuyV # wQC9eB1LFgUsKcUWb0hjnS2/J0W3sC9Tt9LHVvhyh+g0Vba+kq3hE284I0C33gaG # P0Orfepx03oSOX/js0OK3+M5f47bSpeOP4t30ms7STRQKK4KQIAN2MBv3uZ0zO/5 # 695DjB9N1chLPEm82Vn6jtdrq3IJTpPBfksd3V8Ex215LiJLeU2E5EuIfiu/PI22 # M8L4zpXkXlZRUXCfppQA7vjQtzFudl2PqqVVb4+4gyAu/bWRNkVx+D6lAN0hMewh # PiFwKDoPwO+cycQ5I6IaFEHONcEEANov6XoaCxQoIoXMd3tm3VEl5Wr9yXEEL+hn # CpcPmGE1d1iloJC0/Uf/TCsf1dSYd2vY4aRdess1GAidk2T27SrkmoHpdvZdYdNA # ts2doFCTyI6sV2c/jYMpL2NJOYWbhq5AxOuu+DLiw1kDsc/KPmrTuSzBGb7nBuJs # 0QHR4toabNeYUGyKzMJGeibhy434gfyXXLKOWaik8NceybN4M1kROqHL/+PtB5zf # Z1me2ygRrKtaP6RJXGvc8EcP5CEdlQOL6tiCg2ARMTYNxnsiLN9mRU9hkzo9BSJ4 # Vm+C6RKABzZj0whAObyqL/PceLKuAqvGoXbhGx8fXhKEgbnSoJ3VsqROFjGCGqow # ghqmAgEBMH0waTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMu # MUEwPwYDVQQDEzhEaWdpQ2VydCBUcnVzdGVkIEc0IENvZGUgU2lnbmluZyBSU0E0 # MDk2IFNIQTM4NCAyMDIxIENBMQIQD9Sne37r4hoI74/GQqqU1TANBglghkgBZQME # AgEFAKCBhDAYBgorBgEEAYI3AgEMMQowCKACgAChAoAAMBkGCSqGSIb3DQEJAzEM # BgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMC8GCSqG # SIb3DQEJBDEiBCDsvhtbHSsmdrwsg+D2kZ8cGbd+c0vgRhuA+wEMIboDHDANBgkq # hkiG9w0BAQEFAASCAgBwWqenIThBQQH913YTG0M9vJySXAs5j91IqGQfL9Ow5faj # qL6JwpnnpLvLt8l0httgL4tljy5zEnQg8gXwhf3VvimnAfRN3QTNYB1JvholbG/Y # LhgmJ7toZUwzykrHFNoh2smSBA5Hj2FlW+TKYXhZfjYGUt3pdGw+Z19tckMkN3Fq # Pcd90ol516VU82NHgbJhQ5M6Ah0g+/S/W2xVMMVev42jbCn54kZ3NLOuqzftu6tw # uK/95EOSQTZRQwe7GWVQK3OwqqTI0cLgvtQPyJXHhbmXM0EEAQXYT+hy9+T/SwjN # 5sOaGzxGSg3uxRWp9OmdaMZlhn46sFz6X7lYxZxavHl46Inpa0yzQPV7xuX9pX0/ # R27VZBGbXjXvmEG2wx3yPyLyJNO/lKHWEJHDU9+WOxeDafu3AI0Wya68x8m8qK0x # Ev0IKxXPs85wedA7JS/vzd9wH71auOXBpBEzHKTvIaiJzSVB3RZT2hb5+aUByP+1 # TBAnUVprsIcpo2h7T/L9yDM9oWPEMQUFcRnhKrpZlYIwxkYVlPOB/JX4ZzgqonOD # bOy6niMYSRWAhZsWEW4Y2es91VSqhlG2F1xGhQAf4IjBuzba+7sIxD4YW/X6EhcQ # nSGX7egdoYX5pc4LhQUJckJdrKJu/hju3FO8Eq9crdOW1YiuapyBKioov5Hz/aGC # F3cwghdzBgorBgEEAYI3AwMBMYIXYzCCF18GCSqGSIb3DQEHAqCCF1AwghdMAgED # MQ8wDQYJYIZIAWUDBAIBBQAweAYLKoZIhvcNAQkQAQSgaQRnMGUCAQEGCWCGSAGG # /WwHATAxMA0GCWCGSAFlAwQCAQUABCAYYuf3IBDvHBYpX1Gm+32xebBIUCLdTqab # XrT8FxRQBQIRALLbEMGaQaG6wk37fpeNyDwYDzIwMjUwOTE5MjIxMDQ2WqCCEzow # ggbtMIIE1aADAgECAhAKgO8YS43xBYLRxHanlXRoMA0GCSqGSIb3DQEBCwUAMGkx # CzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UEAxM4 # RGlnaUNlcnQgVHJ1c3RlZCBHNCBUaW1lU3RhbXBpbmcgUlNBNDA5NiBTSEEyNTYg # MjAyNSBDQTEwHhcNMjUwNjA0MDAwMDAwWhcNMzYwOTAzMjM1OTU5WjBjMQswCQYD # VQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lD # ZXJ0IFNIQTI1NiBSU0E0MDk2IFRpbWVzdGFtcCBSZXNwb25kZXIgMjAyNSAxMIIC # IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0EasLRLGntDqrmBWsytXum9R # /4ZwCgHfyjfMGUIwYzKomd8U1nH7C8Dr0cVMF3BsfAFI54um8+dnxk36+jx0Tb+k # +87H9WPxNyFPJIDZHhAqlUPt281mHrBbZHqRK71Em3/hCGC5KyyneqiZ7syvFXJ9 # A72wzHpkBaMUNg7MOLxI6E9RaUueHTQKWXymOtRwJXcrcTTPPT2V1D/+cFllESvi # H8YjoPFvZSjKs3SKO1QNUdFd2adw44wDcKgH+JRJE5Qg0NP3yiSyi5MxgU6cehGH # r7zou1znOM8odbkqoK+lJ25LCHBSai25CFyD23DZgPfDrJJJK77epTwMP6eKA0kW # a3osAe8fcpK40uhktzUd/Yk0xUvhDU6lvJukx7jphx40DQt82yepyekl4i0r8OEp # s/FNO4ahfvAk12hE5FVs9HVVWcO5J4dVmVzix4A77p3awLbr89A90/nWGjXMGn7F # QhmSlIUDy9Z2hSgctaepZTd0ILIUbWuhKuAeNIeWrzHKYueMJtItnj2Q+aTyLLKL # M0MheP/9w6CtjuuVHJOVoIJ/DtpJRE7Ce7vMRHoRon4CWIvuiNN1Lk9Y+xZ66laz # s2kKFSTnnkrT3pXWETTJkhd76CIDBbTRofOsNyEhzZtCGmnQigpFHti58CSmvEyJ # cAlDVcKacJ+A9/z7eacCAwEAAaOCAZUwggGRMAwGA1UdEwEB/wQCMAAwHQYDVR0O # BBYEFOQ7/PIx7f391/ORcWMZUEPPYYzoMB8GA1UdIwQYMBaAFO9vU0rp5AZ8esri # kFb2L9RJ7MtOMA4GA1UdDwEB/wQEAwIHgDAWBgNVHSUBAf8EDDAKBggrBgEFBQcD # CDCBlQYIKwYBBQUHAQEEgYgwgYUwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRp # Z2ljZXJ0LmNvbTBdBggrBgEFBQcwAoZRaHR0cDovL2NhY2VydHMuZGlnaWNlcnQu # Y29tL0RpZ2lDZXJ0VHJ1c3RlZEc0VGltZVN0YW1waW5nUlNBNDA5NlNIQTI1NjIw # MjVDQTEuY3J0MF8GA1UdHwRYMFYwVKBSoFCGTmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0 # LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFRpbWVTdGFtcGluZ1JTQTQwOTZTSEEyNTYy # MDI1Q0ExLmNybDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwDQYJ # KoZIhvcNAQELBQADggIBAGUqrfEcJwS5rmBB7NEIRJ5jQHIh+OT2Ik/bNYulCrVv # hREafBYF0RkP2AGr181o2YWPoSHz9iZEN/FPsLSTwVQWo2H62yGBvg7ouCODwrx6 # ULj6hYKqdT8wv2UV+Kbz/3ImZlJ7YXwBD9R0oU62PtgxOao872bOySCILdBghQ/Z # LcdC8cbUUO75ZSpbh1oipOhcUT8lD8QAGB9lctZTTOJM3pHfKBAEcxQFoHlt2s9s # XoxFizTeHihsQyfFg5fxUFEp7W42fNBVN4ueLaceRf9Cq9ec1v5iQMWTFQa0xNqI # tH3CPFTG7aEQJmmrJTV3Qhtfparz+BW60OiMEgV5GWoBy4RVPRwqxv7Mk0Sy4QHs # 7v9y69NBqycz0BZwhB9WOfOu/CIJnzkQTwtSSpGGhLdjnQ4eBpjtP+XB3pQCtv4E # 5UCSDag6+iX8MmB10nfldPF9SVD7weCC3yXZi/uuhqdwkgVxuiMFzGVFwYbQsiGn # oa9F5AaAyBjFBtXVLcKtapnMG3VH3EmAp/jsJ3FVF3+d1SVDTmjFjLbNFZUWMXuZ # yvgLfgyPehwJVxwC+UpX2MSey2ueIu9THFVkT+um1vshETaWyQo8gmBto/m3acaP # 9QsuLj3FNwFlTxq25+T4QwX9xa6ILs84ZPvmpovq90K8eWyG2N01c4IhSOxqt81n # MIIGtDCCBJygAwIBAgIQDcesVwX/IZkuQEMiDDpJhjANBgkqhkiG9w0BAQsFADBi # MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 # d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg # RzQwHhcNMjUwNTA3MDAwMDAwWhcNMzgwMTE0MjM1OTU5WjBpMQswCQYDVQQGEwJV # UzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRy # dXN0ZWQgRzQgVGltZVN0YW1waW5nIFJTQTQwOTYgU0hBMjU2IDIwMjUgQ0ExMIIC # IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtHgx0wqYQXK+PEbAHKx126NG # aHS0URedTa2NDZS1mZaDLFTtQ2oRjzUXMmxCqvkbsDpz4aH+qbxeLho8I6jY3xL1 # IusLopuW2qftJYJaDNs1+JH7Z+QdSKWM06qchUP+AbdJgMQB3h2DZ0Mal5kYp77j # YMVQXSZH++0trj6Ao+xh/AS7sQRuQL37QXbDhAktVJMQbzIBHYJBYgzWIjk8eDrY # hXDEpKk7RdoX0M980EpLtlrNyHw0Xm+nt5pnYJU3Gmq6bNMI1I7Gb5IBZK4ivbVC # iZv7PNBYqHEpNVWC2ZQ8BbfnFRQVESYOszFI2Wv82wnJRfN20VRS3hpLgIR4hjzL # 0hpoYGk81coWJ+KdPvMvaB0WkE/2qHxJ0ucS638ZxqU14lDnki7CcoKCz6eum5A1 # 9WZQHkqUJfdkDjHkccpL6uoG8pbF0LJAQQZxst7VvwDDjAmSFTUms+wV/FbWBqi7 # fTJnjq3hj0XbQcd8hjj/q8d6ylgxCZSKi17yVp2NL+cnT6Toy+rN+nM8M7LnLqCr # O2JP3oW//1sfuZDKiDEb1AQ8es9Xr/u6bDTnYCTKIsDq1BtmXUqEG1NqzJKS4kOm # xkYp2WyODi7vQTCBZtVFJfVZ3j7OgWmnhFr4yUozZtqgPrHRVHhGNKlYzyjlroPx # ul+bgIspzOwbtmsgY1MCAwEAAaOCAV0wggFZMBIGA1UdEwEB/wQIMAYBAf8CAQAw # HQYDVR0OBBYEFO9vU0rp5AZ8esrikFb2L9RJ7MtOMB8GA1UdIwQYMBaAFOzX44LS # cV1kTN8uZz/nupiuHA9PMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEF # BQcDCDB3BggrBgEFBQcBAQRrMGkwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRp # Z2ljZXJ0LmNvbTBBBggrBgEFBQcwAoY1aHR0cDovL2NhY2VydHMuZGlnaWNlcnQu # Y29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcnQwQwYDVR0fBDwwOjA4oDagNIYy # aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5j # cmwwIAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJYIZIAYb9bAcBMA0GCSqGSIb3DQEB # CwUAA4ICAQAXzvsWgBz+Bz0RdnEwvb4LyLU0pn/N0IfFiBowf0/Dm1wGc/Do7oVM # Y2mhXZXjDNJQa8j00DNqhCT3t+s8G0iP5kvN2n7Jd2E4/iEIUBO41P5F448rSYJ5 # 9Ib61eoalhnd6ywFLerycvZTAz40y8S4F3/a+Z1jEMK/DMm/axFSgoR8n6c3nuZB # 9BfBwAQYK9FHaoq2e26MHvVY9gCDA/JYsq7pGdogP8HRtrYfctSLANEBfHU16r3J # 05qX3kId+ZOczgj5kjatVB+NdADVZKON/gnZruMvNYY2o1f4MXRJDMdTSlOLh0HC # n2cQLwQCqjFbqrXuvTPSegOOzr4EWj7PtspIHBldNE2K9i697cvaiIo2p61Ed2p8 # xMJb82Yosn0z4y25xUbI7GIN/TpVfHIqQ6Ku/qjTY6hc3hsXMrS+U0yy+GWqAXam # 4ToWd2UQ1KYT70kZjE4YtL8Pbzg0c1ugMZyZZd/BdHLiRu7hAWE6bTEm4XYRkA6T # l4KSFLFk43esaUeqGkH/wyW4N7OigizwJWeukcyIPbAvjSabnf7+Pu0VrFgoiovR # Diyx3zEdmcif/sYQsfch28bZeUz2rtY/9TCA6TD8dC3JE3rYkrhLULy7Dc90G6e8 # BlqmyIjlgp2+VqsS9/wQD7yFylIz0scmbKvFoW2jNrbM1pD2T7m3XDCCBY0wggR1 # oAMCAQICEA6bGI750C3n79tQ4ghAGFowDQYJKoZIhvcNAQEMBQAwZTELMAkGA1UE # BhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2lj # ZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNzdXJlZCBJRCBSb290IENBMB4X # DTIyMDgwMTAwMDAwMFoXDTMxMTEwOTIzNTk1OVowYjELMAkGA1UEBhMCVVMxFTAT # BgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEh # MB8GA1UEAxMYRGlnaUNlcnQgVHJ1c3RlZCBSb290IEc0MIICIjANBgkqhkiG9w0B # AQEFAAOCAg8AMIICCgKCAgEAv+aQc2jeu+RdSjwwIjBpM+zCpyUuySE98orYWcLh # Kac9WKt2ms2uexuEDcQwH/MbpDgW61bGl20dq7J58soR0uRf1gU8Ug9SH8aeFaV+ # vp+pVxZZVXKvaJNwwrK6dZlqczKU0RBEEC7fgvMHhOZ0O21x4i0MG+4g1ckgHWMp # Lc7sXk7Ik/ghYZs06wXGXuxbGrzryc/NrDRAX7F6Zu53yEioZldXn1RYjgwrt0+n # MNlW7sp7XeOtyU9e5TXnMcvak17cjo+A2raRmECQecN4x7axxLVqGDgDEI3Y1Dek # LgV9iPWCPhCRcKtVgkEy19sEcypukQF8IUzUvK4bA3VdeGbZOjFEmjNAvwjXWkmk # wuapoGfdpCe8oU85tRFYF/ckXEaPZPfBaYh2mHY9WV1CdoeJl2l6SPDgohIbZpp0 # yt5LHucOY67m1O+SkjqePdwA5EUlibaaRBkrfsCUtNJhbesz2cXfSwQAzH0clcOP # 9yGyshG3u3/y1YxwLEFgqrFjGESVGnZifvaAsPvoZKYz0YkH4b235kOkGLimdwHh # D5QMIR2yVCkliWzlDlJRR3S+Jqy2QXXeeqxfjT/JvNNBERJb5RBQ6zHFynIWIgnf # fEx1P2PsIV/EIFFrb7GrhotPwtZFX50g/KEexcCPorF+CiaZ9eRpL5gdLfXZqbId # 5RsCAwEAAaOCATowggE2MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOzX44LS # cV1kTN8uZz/nupiuHA9PMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgP # MA4GA1UdDwEB/wQEAwIBhjB5BggrBgEFBQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0 # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBDBggrBgEFBQcwAoY3aHR0cDovL2NhY2Vy # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNydDBFBgNV # HR8EPjA8MDqgOKA2hjRodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRB # c3N1cmVkSURSb290Q0EuY3JsMBEGA1UdIAQKMAgwBgYEVR0gADANBgkqhkiG9w0B # AQwFAAOCAQEAcKC/Q1xV5zhfoKN0Gz22Ftf3v1cHvZqsoYcs7IVeqRq7IviHGmlU # Iu2kiHdtvRoU9BNKei8ttzjv9P+Aufih9/Jy3iS8UgPITtAq3votVs/59PesMHqa # i7Je1M/RQ0SbQyHrlnKhSLSZy51PpwYDE3cnRNTnf+hZqPC/Lwum6fI0POz3A8eH # qNJMQBk1RmppVLC4oVaO7KTVPeix3P0c2PR3WlxUjG/voVA9/HYJaISfb8rbII01 # YBwCA8sgsKxYoA5AY8WYIsGyWfVVa88nq2x2zm8jLfR+cWojayL/ErhULSd+2DrZ # 8LaHlv1b0VysGMNNn3O3AamfV6peKOK5lDGCA3wwggN4AgEBMH0waTELMAkGA1UE # BhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMUEwPwYDVQQDEzhEaWdpQ2Vy # dCBUcnVzdGVkIEc0IFRpbWVTdGFtcGluZyBSU0E0MDk2IFNIQTI1NiAyMDI1IENB # MQIQCoDvGEuN8QWC0cR2p5V0aDANBglghkgBZQMEAgEFAKCB0TAaBgkqhkiG9w0B # CQMxDQYLKoZIhvcNAQkQAQQwHAYJKoZIhvcNAQkFMQ8XDTI1MDkxOTIyMTA0Nlow # KwYLKoZIhvcNAQkQAgwxHDAaMBgwFgQU3WIwrIYKLTBr2jixaHlSMAf7QX4wLwYJ # KoZIhvcNAQkEMSIEIDCERmn/RaO7toDVSXTGBOZCoFYXmpohhxT3fDmVsC+sMDcG # CyqGSIb3DQEJEAIvMSgwJjAkMCIEIEqgP6Is11yExVyTj4KOZ2ucrsqzP+NtJpqj # NPFGEQozMA0GCSqGSIb3DQEBAQUABIICADNLrbhbR6ywHJD3xk8YOThO/tPpEwJW # Z1QTVOS3vfLyTsqeSA10ZUdHB9goSeZmqtVrrkAX5dp2gkWZUrlTQKaJ00mgd/t2 # CwqzQVknyht82fjBIHISXcUj/nNLipzHTteRpgqRbqaNGzsypSGXEXhoeTh9XRqa # 4jA2iU3bnHB1LL7UCEw9XOe304wHf+OUcYGLq14MavfgNQOXTrmW1PknWpJq9keA # tTYh1E+eybsh1syG0DQyjGKkTK+w/iOqboU17XvqdJh2r/YyPtNeMdYN1+PQCTEk # 9+TzVH/iUr8mKgu843UwT95pRlikNbvClVJr733oVx5S3JyRX2sr3DUzhRUVSILI # 5OMeDpaTSDHDimCrLdbxVNA66K9wlVnMZNNb4e4ng+ojXWF8h20b3KyinfGpjtPh # CHmTPx+w02V7YIsSkmQqNceOFRqPdQaIC32zvJBbq+GodBJ80mm3981+DMCPgB6P # D0ncYS1ZIBXM2sa5qjtqKHPHZ4VPsu370SNBd6LvF+PUrOoF3eJhGG7ic7e4N6xH # PN8jy+P/6k0Dc1JmsTQ1UqspgNak3EqOsr79TRJ8bSG4ZnbQ2FgZPz0O0PUqlwwj # e5glHcKEkC+4Nl3Ata9F6s5YGAHpj8DodUq0a62hD4Iu/M4G6/kOUvpnTgpls/+f # rcuxaVpLD7t9 # SIG # End signature block |