Add-AaddsResourceForestTrust.ps1

<#PSScriptInfo
 
.VERSION 2.0.0
 
.GUID f554e230-0ef6-4e57-8555-16064d86ebd4
 
.AUTHOR aaddsfb@microsoft.com
 
.COMPANYNAME Microsoft Corporation
 
.COPYRIGHT (c) Microsoft Corporation
 
.TAGS Microsoft-Entra-Domain-Services ForestTrust
 
.LICENSEURI
 
.PROJECTURI
 
.ICONURI
 
.EXTERNALMODULEDEPENDENCIES
 
.REQUIREDSCRIPTS
 
.EXTERNALSCRIPTDEPENDENCIES
 
.RELEASENOTES
    07/19/2020 - Initial release
    01/09/2024 - Rebrand to Microsoft Entra Domain Services
    06/24/2025 - Adding new trust direction parameter, that allows one to create a inbound, outbound or bidirectional trust.
               - Updating Entra Domain Services resource API to use the latest version.
#>


<#
 
.SYNOPSIS
    Adds a trusts to a Microsoft Entra Domain Services resource forest.
 
.DESCRIPTION
    Adds a trusts to a Microsoft Entra Domain Services resource forest.
 
.PARAMETER ManagedDomainFqdn [MANADATORY]
    The fqdn of the managed domain (e.g aadds.corp.contoso.com).
 
.PARAMETER TrustFriendlyName [MANDATORY]
    The friendly name of the trust relationship.
 
.PARAMETER TrustFqdn [MANADATORY]
    The FQDN of the trusted forest.
 
.PARAMETER TrustDirection [MANDATORY]
    The direction of the trust relationship (Inbound, Outbound, Bidirectional).
 
.PARAMETER TrustDnsIps [MANDATORY]
    A comma delimited list DNS servers for the
    trusted domain listed as IPv4 addresses.
 
.PARAMETER TrustPassword [MANDATORY]
    The complex password the trust relationship uses.
 
.PARAMETER Credential [OPTIONAL]
    The credentials used to authenticate to Azure.
#>

[CmdletBinding()]
Param (

    [Parameter(
        Mandatory = $true,
        Position = 0)]
    [string]
    $ManagedDomainFqdn,

    [Parameter(
        Mandatory = $true,
        Position = 1)]
    [string]
    $TrustFqdn,

    [Parameter(
        Mandatory = $true,
        Position = 2)]
    [string]
    $TrustFriendlyName,

    [Parameter(
        Mandatory = $true,
        Position = 3,
        HelpMessage = "Specify the direction of the trust relationship. Valid options are: Bidirectional, Inbound, Outbound."
    )]
    [ValidateSet("Bidirectional", "Inbound", "Outbound")]
    [string]
    $TrustDirection,

    [Parameter(
        Mandatory = $true,
        Position = 4)]
    [string]
    $TrustDnsIps,

    [Parameter(
        Mandatory = $true,
        Position = 5)]
    [string]
    $TrustPassword,

    [Parameter(
        Mandatory = $false,
        Position = 6)]
    [pscredential]
    $Credentials
)
Process {
    # Create empty trust settings
    $TrustSettingsValue = [System.Collections.ArrayList]@()
    $azProfile = $null

    Write-Host ([string]::Empty)
    Write-Host ([string]::Empty)
    Write-Host "Authenticating to Azure... " -NoNewline

    # Collect credentials from the user for authentication
    if ($null -ne $creds)
    {
        $creds = Get-Credential -ErrorAction SilentlyContinue
        $azProfile = Connect-AzAccount -Credential $creds -ErrorAction SilentlyContinue
    }
    else
    {
        $azProfile = Connect-AzAccount -ErrorAction SilentlyContinue
    }

    if ($null -eq $azProfile)
    {
        # Authentication failed
        Write-Host -ForegroundColor Red "[Failed!]"
        Write-Host -ForegroundColor Red "ERROR: Could not authenticate to Azure. Check your credentials and try again."

        Return
    }

    Write-Host -ForegroundColor Green "[Success!]"
    Write-Host "INFO: Authenticated to Azure as $($azProfile.Account.Id)..."

    Write-Host "Getting Entra Domain Services instance..." -NoNewline
    $aadds = Get-AzResource -Name $ManagedDomainFqdn -ExpandProperties -ErrorAction SilentlyContinue | Where-Object { $_.ResourceType -eq "Microsoft.AAD/domainServices" }

    if ($null -eq $aadds)
    {
        Write-Host -ForegroundColor Red "[Failed!]"
        Write-Host -ForegroundColor Red "ERROR: Could not find an Entra Domain Services resource with the name $ManagedDomainFqdn."

        Return
    }

    Write-Host -ForegroundColor Green "[Success!]"

    #region PREREQ CHECKS
    Write-Host ([string]::Empty)
    Write-Host "Checking prerequisites..."

    Write-Host "Validating service status..." -NoNewline
    if ($null -ne $aadds.Properties.ReplicaSets)
    {
        $replicaSetCount = $aadds.Properties.ReplicaSets.Count
    }
    else
    {
        $replicaSetCount = 0
    }

    $serviceStatus = $null
    if ($replicaSetCount -eq 1)
    {
        $serviceStatus = $aadds.Properties.ReplicaSets[0].serviceStatus
    }
    elseif ($replicaSetCount -gt 1)
    {
        $syncOwner = $aadds.Properties.SyncOwner
        $primaryReplicaSet = $aadds.Properties.ReplicaSets | Where-Object { $_.ReplicaSetId -eq $syncOwner }
        $serviceStatus = $primaryReplicaSet.serviceStatus
    }

    if ($serviceStatus -ne "Running")
    {
        $pass = $false
        Write-Host -ForegroundColor Red "[Failed!]"
        Write-Host -ForegroundColor Red "ERROR: The managed domain $($aadds.Name) must be running (Status:$($aadds.properties.serviceStatus))."
    }
    else
    {
        Write-Host -ForegroundColor Green "[Pass!]"
    }

    Write-Host "Checking for duplicate trust name..." -NoNewline
    $duplicateFound = $false
    $tempTrustSettingsValue = $aadds.Properties.resourceForestSettings.settings
    if (0 -lt $tempTrustSettingsValue.Count)
    {
        foreach ($tempTrustValue in $tempTrustSettingsValue)
        {
            #check for matching #fqdn
            if ($TrustFqdn -eq $tempTrustValue.trustedDomainFqdn)
            {
                $pass = $false
                $duplicateFound = $true
                Write-Host -ForegroundColor red "[Failed!]"
                Write-Host -ForegroundColor Red "ERROR: The trust $($TrustFqdn) already exist in the managed domain $($aadds.Name)."

                break;
            }
        }
    }

    if ($duplicateFound -eq $false)
    {
        Write-Host -ForegroundColor Green "[Pass!]"
    }

    if ($pass -eq $false)
    {
        Write-Host -ForegroundColor Red "ERROR: One or more prerequisites checks failed."

        Return
    }
    #endregion PREREQ CHECKS

    # Add any existing trusts to prevent Azure from deleting them
    foreach ($tempTrustValue in $tempTrustSettingsValue)
    {
        $TrustSettingsValue.Add($tempTrustValue)
    }

    # Add the new trust for Azure to create
    $TrustSettingsValue.Add(
        @{
            "friendlyName"      = $TrustFriendlyName;
            "trustedDomainFqdn" = $TrustFqdn;
            "remoteDNSIps"      = $TrustDnsIps;
            "trustPassword"     = $TrustPassword;
            "trustDirection"    = $TrustDirection;
        }
    )

    Write-host ([string]::Empty)
    $answer = Read-host -Prompt "Type 'Yes' to confirm you want to add the trust $TrustFqdn to the managed domain $($aadds.Name)"
    if ("Yes" -cne $answer)
    {
        Write-Host "User canceled."

        Return
    }

    # Assign the trust values to the trust settings
    $trustSettings = @{"settings" = $TrustSettingsValue }

    # Assign the trust settings to the ResourceForestSettings
    $resourceForestSettings = @{"resourceForestSettings" = $trustSettings }

    $actionStart = Get-Date

    Write-Host ([string]::Empty)
    Write-Host "Sending request to Azure. This action may take up to five minutes to complete. Please wait..."
    Set-AzResource -ResourceId $aadds.ResourceId -ApiVersion "2022-12-01" -Properties $resourceForestSettings -force

    $actionStop = Get-Date

    Write-Host "Elapsed Time: " ($actionStop - $actionStart)
} # End Process

# SIG # Begin signature block
# MIIsCgYJKoZIhvcNAQcCoIIr+zCCK/cCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDqtsdIo3UBXV5T
# KhQlDc3nUma8KxzcsKAZd5CL0pZlxKCCEXgwggiIMIIHcKADAgECAhM2AAACBIY2
# eKH0vgR+AAIAAAIEMA0GCSqGSIb3DQEBCwUAMEExEzARBgoJkiaJk/IsZAEZFgNH
# QkwxEzARBgoJkiaJk/IsZAEZFgNBTUUxFTATBgNVBAMTDEFNRSBDUyBDQSAwMTAe
# Fw0yNDExMDgxMjQ2MTVaFw0yNTExMDgxMjQ2MTVaMC8xLTArBgNVBAMTJE1pY3Jv
# c29mdCBBenVyZSBEZXBlbmRlbmN5IENvZGUgU2lnbjCCASIwDQYJKoZIhvcNAQEB
# BQADggEPADCCAQoCggEBAPMzJ8+5iuzPEvyWyqvQ8Lg6jR9oaO3Jf5qlRjxeD41Y
# bkqKFvk5zW3XfUzy9FaA4vhKYGTav3Afc6srskrKqEz64RPgkApueunqiytGXfNl
# Q7uP7iJJmBBXAcw23PR7cc6xrPvG+h5LDPHf9VT+iBsGyndA4SYH5oq8KVHF5H3j
# HfxNsgz3+YG5tJ6jH+/NptEg/NSoa3Xh78fBV1qX0PVlBGBFXt97ayY6NBwmWNYv
# UY7uLm3XzTNp7YG0WskxTD+vOij0XIc7rAe3EFpdrnWABFEiyaU591tWx48Iln/+
# TFC4K7alwjymJUcz5ia9YNoQVi3t+TbppVyHedzc6tMCAwEAAaOCBYkwggWFMCkG
# CSsGAQQBgjcVCgQcMBowDAYKKwYBBAGCN1sDATAKBggrBgEFBQcDAzA8BgkrBgEE
# AYI3FQcELzAtBiUrBgEEAYI3FQiGkOMNhNW0eITxiz6Fm90Wzp0SgWDigi2HkK4D
# AgFkAgEQMIICdgYIKwYBBQUHAQEEggJoMIICZDBiBggrBgEFBQcwAoZWaHR0cDov
# L2NybC5taWNyb3NvZnQuY29tL3BraWluZnJhL0NlcnRzL0JZMlBLSUNTQ0EwMS5B
# TUUuR0JMX0FNRSUyMENTJTIwQ0ElMjAwMSgyKS5jcnQwUgYIKwYBBQUHMAKGRmh0
# dHA6Ly9jcmwxLmFtZS5nYmwvYWlhL0JZMlBLSUNTQ0EwMS5BTUUuR0JMX0FNRSUy
# MENTJTIwQ0ElMjAwMSgyKS5jcnQwUgYIKwYBBQUHMAKGRmh0dHA6Ly9jcmwyLmFt
# ZS5nYmwvYWlhL0JZMlBLSUNTQ0EwMS5BTUUuR0JMX0FNRSUyMENTJTIwQ0ElMjAw
# MSgyKS5jcnQwUgYIKwYBBQUHMAKGRmh0dHA6Ly9jcmwzLmFtZS5nYmwvYWlhL0JZ
# MlBLSUNTQ0EwMS5BTUUuR0JMX0FNRSUyMENTJTIwQ0ElMjAwMSgyKS5jcnQwUgYI
# KwYBBQUHMAKGRmh0dHA6Ly9jcmw0LmFtZS5nYmwvYWlhL0JZMlBLSUNTQ0EwMS5B
# TUUuR0JMX0FNRSUyMENTJTIwQ0ElMjAwMSgyKS5jcnQwga0GCCsGAQUFBzAChoGg
# bGRhcDovLy9DTj1BTUUlMjBDUyUyMENBJTIwMDEsQ049QUlBLENOPVB1YmxpYyUy
# MEtleSUyMFNlcnZpY2VzLENOPVNlcnZpY2VzLENOPUNvbmZpZ3VyYXRpb24sREM9
# QU1FLERDPUdCTD9jQUNlcnRpZmljYXRlP2Jhc2U/b2JqZWN0Q2xhc3M9Y2VydGlm
# aWNhdGlvbkF1dGhvcml0eTAdBgNVHQ4EFgQUw39+RvM9ICQzKxoTRcu71FIzSBIw
# DgYDVR0PAQH/BAQDAgeAMEUGA1UdEQQ+MDykOjA4MR4wHAYDVQQLExVNaWNyb3Nv
# ZnQgQ29ycG9yYXRpb24xFjAUBgNVBAUTDTIzNjE2OSs1MDMxNTMwggHmBgNVHR8E
# ggHdMIIB2TCCAdWgggHRoIIBzYY/aHR0cDovL2NybC5taWNyb3NvZnQuY29tL3Br
# aWluZnJhL0NSTC9BTUUlMjBDUyUyMENBJTIwMDEoMikuY3JshjFodHRwOi8vY3Js
# MS5hbWUuZ2JsL2NybC9BTUUlMjBDUyUyMENBJTIwMDEoMikuY3JshjFodHRwOi8v
# Y3JsMi5hbWUuZ2JsL2NybC9BTUUlMjBDUyUyMENBJTIwMDEoMikuY3JshjFodHRw
# Oi8vY3JsMy5hbWUuZ2JsL2NybC9BTUUlMjBDUyUyMENBJTIwMDEoMikuY3JshjFo
# dHRwOi8vY3JsNC5hbWUuZ2JsL2NybC9BTUUlMjBDUyUyMENBJTIwMDEoMikuY3Js
# hoG9bGRhcDovLy9DTj1BTUUlMjBDUyUyMENBJTIwMDEoMiksQ049QlkyUEtJQ1ND
# QTAxLENOPUNEUCxDTj1QdWJsaWMlMjBLZXklMjBTZXJ2aWNlcyxDTj1TZXJ2aWNl
# cyxDTj1Db25maWd1cmF0aW9uLERDPUFNRSxEQz1HQkw/Y2VydGlmaWNhdGVSZXZv
# Y2F0aW9uTGlzdD9iYXNlP29iamVjdENsYXNzPWNSTERpc3RyaWJ1dGlvblBvaW50
# MB8GA1UdIwQYMBaAFJZRhOBrb3v+2Aarw/KF5imuavnUMB8GA1UdJQQYMBYGCisG
# AQQBgjdbAwEGCCsGAQUFBwMDMA0GCSqGSIb3DQEBCwUAA4IBAQAqhvUBfHIboRQv
# hZH+qh+g3/ifKd7J5mNS8Xa2FmDB3Nn+aqtVfjg0K3cXYOGQQPTTcBNJGFbrjRy2
# aqwhTqW/w7u1sCFmxMeN/fzHiiIxfCDFcjd2Q4c8N8BuZoZXgr5DONka2VJKTXLh
# g049b9vgWSNVEP8LT2sFfkZ6fuJ7WVWffWSDjWJmvKMjPl4y2boWRQtyN8War2h+
# oFEBEZDMaFZRqu/sDwFpJlarhEJs+qIZsTpKPJnHoCdrgX/MWmJpVqnzSpqajIfz
# CGY6ZQfnDPld6t+A6MLgGX/eGAlXmzLqcUzehzmrZGEEPSn3jrENGOis7Ql9/KtM
# 5d6oErXlMIII6DCCBtCgAwIBAgITHwAAAFHqj/accwyoOwAAAAAAUTANBgkqhkiG
# 9w0BAQsFADA8MRMwEQYKCZImiZPyLGQBGRYDR0JMMRMwEQYKCZImiZPyLGQBGRYD
# QU1FMRAwDgYDVQQDEwdhbWVyb290MB4XDTIxMDUyMTE4NDQxNFoXDTI2MDUyMTE4
# NTQxNFowQTETMBEGCgmSJomT8ixkARkWA0dCTDETMBEGCgmSJomT8ixkARkWA0FN
# RTEVMBMGA1UEAxMMQU1FIENTIENBIDAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
# MIIBCgKCAQEAyZpSCX0Bno1W1yqXMhT6BUlJZWpa4p3xFeiTHO4vm2Q6C/azR5xw
# xnyYHrkSGDtS2P9X+KDE64V20mmEQkubxnPNeOVnE2RvdPGxgwlq+BhS3ONdVsQP
# j79q7XgHM9HhzB9+qk0PC9KN1zm9p/seyiRS6JF1dbOqRf1pUl7FAVxmgiCFgV8h
# HIb/rDPXig7FDi3S0yEx2CUDVpIq8jEhG8anUFE1WYxM+ni0S5KHwwKPKV4qyGDo
# DO+9AmDoma3Chyu5WDlW5cdtqXTWsGPE3umtnX6AmlldUFLms4OVR4guKf+n5LIB
# CC6bTiocfXPomqYjYTKx7AGMfaVLaaXmhQIDAQABo4IE3DCCBNgwEgYJKwYBBAGC
# NxUBBAUCAwIAAjAjBgkrBgEEAYI3FQIEFgQUEmgkQiFHy9RrvjHPIKTACyN/P0cw
# HQYDVR0OBBYEFJZRhOBrb3v+2Aarw/KF5imuavnUMIIBBAYDVR0lBIH8MIH5Bgcr
# BgEFAgMFBggrBgEFBQcDAQYIKwYBBQUHAwIGCisGAQQBgjcUAgEGCSsGAQQBgjcV
# BgYKKwYBBAGCNwoDDAYJKwYBBAGCNxUGBggrBgEFBQcDCQYIKwYBBQUIAgIGCisG
# AQQBgjdAAQEGCysGAQQBgjcKAwQBBgorBgEEAYI3CgMEBgkrBgEEAYI3FQUGCisG
# AQQBgjcUAgIGCisGAQQBgjcUAgMGCCsGAQUFBwMDBgorBgEEAYI3WwEBBgorBgEE
# AYI3WwIBBgorBgEEAYI3WwMBBgorBgEEAYI3WwUBBgorBgEEAYI3WwQBBgorBgEE
# AYI3WwQCMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAS
# BgNVHRMBAf8ECDAGAQH/AgEAMB8GA1UdIwQYMBaAFCleUV5krjS566ycDaeMdQHR
# CQsoMIIBaAYDVR0fBIIBXzCCAVswggFXoIIBU6CCAU+GMWh0dHA6Ly9jcmwubWlj
# cm9zb2Z0LmNvbS9wa2lpbmZyYS9jcmwvYW1lcm9vdC5jcmyGI2h0dHA6Ly9jcmwy
# LmFtZS5nYmwvY3JsL2FtZXJvb3QuY3JshiNodHRwOi8vY3JsMy5hbWUuZ2JsL2Ny
# bC9hbWVyb290LmNybIYjaHR0cDovL2NybDEuYW1lLmdibC9jcmwvYW1lcm9vdC5j
# cmyGgapsZGFwOi8vL0NOPWFtZXJvb3QsQ049QU1FUm9vdCxDTj1DRFAsQ049UHVi
# bGljJTIwS2V5JTIwU2VydmljZXMsQ049U2VydmljZXMsQ049Q29uZmlndXJhdGlv
# bixEQz1BTUUsREM9R0JMP2NlcnRpZmljYXRlUmV2b2NhdGlvbkxpc3Q/YmFzZT9v
# YmplY3RDbGFzcz1jUkxEaXN0cmlidXRpb25Qb2ludDCCAasGCCsGAQUFBwEBBIIB
# nTCCAZkwRwYIKwYBBQUHMAKGO2h0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2lp
# bmZyYS9jZXJ0cy9BTUVSb290X2FtZXJvb3QuY3J0MDcGCCsGAQUFBzAChitodHRw
# Oi8vY3JsMi5hbWUuZ2JsL2FpYS9BTUVSb290X2FtZXJvb3QuY3J0MDcGCCsGAQUF
# BzAChitodHRwOi8vY3JsMy5hbWUuZ2JsL2FpYS9BTUVSb290X2FtZXJvb3QuY3J0
# MDcGCCsGAQUFBzAChitodHRwOi8vY3JsMS5hbWUuZ2JsL2FpYS9BTUVSb290X2Ft
# ZXJvb3QuY3J0MIGiBggrBgEFBQcwAoaBlWxkYXA6Ly8vQ049YW1lcm9vdCxDTj1B
# SUEsQ049UHVibGljJTIwS2V5JTIwU2VydmljZXMsQ049U2VydmljZXMsQ049Q29u
# ZmlndXJhdGlvbixEQz1BTUUsREM9R0JMP2NBQ2VydGlmaWNhdGU/YmFzZT9vYmpl
# Y3RDbGFzcz1jZXJ0aWZpY2F0aW9uQXV0aG9yaXR5MA0GCSqGSIb3DQEBCwUAA4IC
# AQBQECO3Tw/o317Rrd7yadqcswPx1LvIYymkaTN6KcmuRt6HKa0Xe73Ux2/AQ30T
# fgA9GBJngweRykKBusRzyOU17iIubJvy3gA21dwtqtB0DsoEv1U/ptVu2v++doTC
# J/i+GbssVXkgaX8H+6EOGEmT4evp4GbwR4HwWlc+Dvf8HH8PdUA2Z04CvcwIfckS
# ipbNm84jxJ8XjmTFTWscldL9edj2NsY6iGnyJFIyur2PS7VRYyV3p1VAJp91gj1j
# RQtWEyCB8P5g9nE3z8u0ANaU/hjwEQCrdGyravWgnf2JtG+bT26YAokbc8m+32zU
# tXRO+NK3tAjhOu2FdsG3qNrF4sc7y37R/C+7Pcb/cFfhttqsirepZii4xStcjMOD
# YuXzGm3IJs0b0owHG6oKd7ZOGvHpmmh9K8/DLriD/sq8bURD10qi/wuW8zM7IpLg
# 1vcR9dIK2mc0pj44pc6UX0XbttP/VEJgu3lT2eI9VjWtaKjx38xE9woSMyekPRtz
# TwgfuysF9DkJisr+yA4po/FPxpbBw9c/hBf32DH/GFxteS2pmjgKIbMP8sDukmEq
# 3lVvuWNJsybrZwQvQpvaM49fv+JKpLK5YWYEfwksYRR9wU8Hh/ID9hRCEkbUoQ2W
# 7mMpsp2Nbp/kcn4ivfolUy3Q9Yf0scsQ6WTLYpm+AoCUJTGCGegwghnkAgEBMFgw
# QTETMBEGCgmSJomT8ixkARkWA0dCTDETMBEGCgmSJomT8ixkARkWA0FNRTEVMBMG
# A1UEAxMMQU1FIENTIENBIDAxAhM2AAACBIY2eKH0vgR+AAIAAAIEMA0GCWCGSAFl
# AwQCAQUAoIGuMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcC
# AQsxDjAMBgorBgEEAYI3AgEVMC8GCSqGSIb3DQEJBDEiBCAMQ5woKMb0sq3M2FR7
# lCm+UnVhiSMh103Y9aSpNaxDajBCBgorBgEEAYI3AgEMMTQwMqAUgBIATQBpAGMA
# cgBvAHMAbwBmAHShGoAYaHR0cDovL3d3dy5taWNyb3NvZnQuY29tMA0GCSqGSIb3
# DQEBAQUABIIBALh6tN3D2pb8DDRFlqPguB8SKs5auRyXywiCNzY//FZfS+7nP5nI
# Ez87qH6Pw+eDVNq0mw4sD4ZDgsERHUS9zaalxHwzT2wwt3agUAGZeA8nLOvN+C/n
# 6ZuORf6Svyyny1ub+IbGlfObasArvItHRz/aux62jg3rd+q1GNgpOm5sz2yhSWx2
# 3kE199Pl/go11r/x3Z+Y7qnW5SFScpXB2CDOf3BQqlVETvo3xanU5v7bixFXpjhV
# 4XWvRg+3UJHg36UvzDV7xp3OPzkLSKPkaVaDLaOXDTL0QR5oTTXMLx37Uf0oOZDL
# 87htgBbrpz8OSqwYJXbN/Kh3ZjOtvV1UmxmhghewMIIXrAYKKwYBBAGCNwMDATGC
# F5wwgheYBgkqhkiG9w0BBwKggheJMIIXhQIBAzEPMA0GCWCGSAFlAwQCAQUAMIIB
# WgYLKoZIhvcNAQkQAQSgggFJBIIBRTCCAUECAQEGCisGAQQBhFkKAwEwMTANBglg
# hkgBZQMEAgEFAAQg0QWrFqTMZnC3S6C4jtGg0pgeXoHQ//a5M1rSxVK9s6wCBmhS
# 5mh9DBgTMjAyNTA2MjUxNzI5MTYuODA4WjAEgAIB9KCB2aSB1jCB0zELMAkGA1UE
# BhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAc
# BgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMkTWljcm9zb2Z0
# IElyZWxhbmQgT3BlcmF0aW9ucyBMaW1pdGVkMScwJQYDVQQLEx5uU2hpZWxkIFRT
# UyBFU046NDMxQS0wNUUwLUQ5NDcxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0
# YW1wIFNlcnZpY2WgghH+MIIHKDCCBRCgAwIBAgITMwAAAfr7O0TTdzPG0wABAAAB
# +jANBgkqhkiG9w0BAQsFADB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu
# Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv
# cmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDAe
# Fw0yNDA3MjUxODMxMTFaFw0yNTEwMjIxODMxMTFaMIHTMQswCQYDVQQGEwJVUzET
# MBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMV
# TWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJlbGFu
# ZCBPcGVyYXRpb25zIExpbWl0ZWQxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjo0
# MzFBLTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vy
# dmljZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMoWVQTNz2XAXxKQ
# H+3yCIcoMGFVT+uFEnmW0pUUd6byXm72tC0Ag1uOcjq7acCKRsgxl/hGwmx4UuU3
# eCdGJXPN87SxG20A+zOpKkdF4/p/NnBrHv0JzB9FkWS58IICXXp6UOlHIjOJzGGb
# 3UI8mwOKnoznvWNO9yZV791SG3ZEB9iRsk/KAfy7Lzy/5AJyeOaECKe0see0T0P9
# Duqmsidkia8HIwPGrjHQJ2SjosRZc6KKIe0ssnCOwRDR06ZFSq0VeWHpUb1jU4Na
# R+BAtijtm8bATdt27THk72RYnhiK/g/Jn9ZUELNB7f7TDlXWodeLe2JPsZeT+E8N
# 8XwBoB7L7GuroK8cJik019ZKlx+VwncN01XigmseiVfsoDOYtTa6CSsAQltdT8It
# M/5IvdGXjul3xBPZgpyZu+kHMYt7Z1v2P92bpikOl/4lSCaOy5NGf6QE0cACDasH
# b86XbV9oTiYm+BkfIrNm6SpLNOBrq38Hlj5/c+o2OxgQvo7PKUsBnsK338IAGzSp
# vNmQxb6gRkEFScCB0l6Y5Evht/XsmDhtq3CCwSA5c1MzBRSWzYebQ79xnidxCrwu
# LzUgMbRn2hv5kISuN2I3r7Ae9i6LlO/K8bTYbjF0s2h6uXxYht83LGB2muPsPmJj
# K4UxMw+EgIrId+QY6Fz9T9QreFWtAgMBAAGjggFJMIIBRTAdBgNVHQ4EFgQUY4xy
# my+VlepHdOiqHEB6YSvVP78wHwYDVR0jBBgwFoAUn6cVXQBeYl2D9OXSZacbUzUZ
# 6XIwXwYDVR0fBFgwVjBUoFKgUIZOaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3Br
# aW9wcy9jcmwvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAoMSku
# Y3JsMGwGCCsGAQUFBwEBBGAwXjBcBggrBgEFBQcwAoZQaHR0cDovL3d3dy5taWNy
# b3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIw
# UENBJTIwMjAxMCgxKS5jcnQwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggr
# BgEFBQcDCDAOBgNVHQ8BAf8EBAMCB4AwDQYJKoZIhvcNAQELBQADggIBALhWwqKx
# a76HRvmTSR92Pjc+UKVMrUFTmzsmBa4HBq8aujFGuMi5sTeMVnS9ZMoGluQTmd8Q
# ZT2O1abn+W+Xmlz+6kautcXjq193+uJBoklqEYvRCWsCVgsyX1EEU4Qy+M8SNqWH
# NcJz6e0OveWx6sGdNnmjgbnYfyHxJBntDn4+iEt6MmbCT9cmrXJuJAaiB+nW9fsH
# jOKuOjYQHwH9O9MxehfiKVB8obTG0IOfkB3zrsgc67euwojCUinCd5zFcnzZZ7+s
# r7bWMyyt8EvtEMCVImy2CTCOhRnErkcSpaukYzoSvS90Do4dFQjNdaxzNdWZjdHr
# iW2wQlX0BLnzizZBvPDBQlDRNdEkmzPzoPwm05KNDOcG1b0Cegqiyo7R0qHqABj3
# nl9uH+XD2Mk3CpWzOi6FHTtj+SUnSObNSRfzp+i4lE+dGnaUbLWWo22BHl/ze0b0
# m5J9HYw9wb09jn91n/YCHmkCB279Sdjvz+UDj0IlaPPtACpujNEyjnbooYSsQLf+
# mMpNexb90SHY0+sIi9qkSBLIDiad3yC8OJkET7t7KUX2pEqEHuTdHuB1hX/FltmS
# 9PnPN0M4d1bRDyOmNntgTv3loU2GyGx6amA3wLQGLWmCHXvO2cplxtzDtsFI4S/R
# 70kM46KrqvjqFJr3wVHAdnuS+kAhzuqkzu1qMIIHcTCCBVmgAwIBAgITMwAAABXF
# 52ueAptJmQAAAAAAFTANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzAR
# BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p
# Y3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2Vy
# dGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMjEwOTMwMTgyMjI1WhcNMzAwOTMw
# MTgzMjI1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4G
# A1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYw
# JAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCAiIwDQYJKoZI
# hvcNAQEBBQADggIPADCCAgoCggIBAOThpkzntHIhC3miy9ckeb0O1YLT/e6cBwfS
# qWxOdcjKNVf2AX9sSuDivbk+F2Az/1xPx2b3lVNxWuJ+Slr+uDZnhUYjDLWNE893
# MsAQGOhgfWpSg0S3po5GawcU88V29YZQ3MFEyHFcUTE3oAo4bo3t1w/YJlN8OWEC
# esSq/XJprx2rrPY2vjUmZNqYO7oaezOtgFt+jBAcnVL+tuhiJdxqD89d9P6OU8/W
# 7IVWTe/dvI2k45GPsjksUZzpcGkNyjYtcI4xyDUoveO0hyTD4MmPfrVUj9z6BVWY
# bWg7mka97aSueik3rMvrg0XnRm7KMtXAhjBcTyziYrLNueKNiOSWrAFKu75xqRdb
# Z2De+JKRHh09/SDPc31BmkZ1zcRfNN0Sidb9pSB9fvzZnkXftnIv231fgLrbqn42
# 7DZM9ituqBJR6L8FA6PRc6ZNN3SUHDSCD/AQ8rdHGO2n6Jl8P0zbr17C89XYcz1D
# TsEzOUyOArxCaC4Q6oRRRuLRvWoYWmEBc8pnol7XKHYC4jMYctenIPDC+hIK12Nv
# DMk2ZItboKaDIV1fMHSRlJTYuVD5C4lh8zYGNRiER9vcG9H9stQcxWv2XFJRXRLb
# JbqvUAV6bMURHXLvjflSxIUXk8A8FdsaN8cIFRg/eKtFtvUeh17aj54WcmnGrnu3
# tz5q4i6tAgMBAAGjggHdMIIB2TASBgkrBgEEAYI3FQEEBQIDAQABMCMGCSsGAQQB
# gjcVAgQWBBQqp1L+ZMSavoKRPEY1Kc8Q/y8E7jAdBgNVHQ4EFgQUn6cVXQBeYl2D
# 9OXSZacbUzUZ6XIwXAYDVR0gBFUwUzBRBgwrBgEEAYI3TIN9AQEwQTA/BggrBgEF
# BQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9z
# aXRvcnkuaHRtMBMGA1UdJQQMMAoGCCsGAQUFBwMIMBkGCSsGAQQBgjcUAgQMHgoA
# UwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQY
# MBaAFNX2VsuP6KJcYmjRPZSQW9fOmhjEMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6
# Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1
# dF8yMDEwLTA2LTIzLmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0
# dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljUm9vQ2VyQXV0XzIw
# MTAtMDYtMjMuY3J0MA0GCSqGSIb3DQEBCwUAA4ICAQCdVX38Kq3hLB9nATEkW+Ge
# ckv8qW/qXBS2Pk5HZHixBpOXPTEztTnXwnE2P9pkbHzQdTltuw8x5MKP+2zRoZQY
# Iu7pZmc6U03dmLq2HnjYNi6cqYJWAAOwBb6J6Gngugnue99qb74py27YP0h1AdkY
# 3m2CDPVtI1TkeFN1JFe53Z/zjj3G82jfZfakVqr3lbYoVSfQJL1AoL8ZthISEV09
# J+BAljis9/kpicO8F7BUhUKz/AyeixmJ5/ALaoHCgRlCGVJ1ijbCHcNhcy4sa3tu
# PywJeBTpkbKpW99Jo3QMvOyRgNI95ko+ZjtPu4b6MhrZlvSP9pEB9s7GdP32THJv
# EKt1MMU0sHrYUP4KWN1APMdUbZ1jdEgssU5HLcEUBHG/ZPkkvnNtyo4JvbMBV0lU
# ZNlz138eW0QBjloZkWsNn6Qo3GcZKCS6OEuabvshVGtqRRFHqfG3rsjoiV5PndLQ
# THa1V1QJsWkBRH58oWFsc/4Ku+xBZj1p/cvBQUl+fpO+y/g75LcVv7TOPqUxUYS8
# vwLBgqJ7Fx0ViY1w/ue10CgaiQuPNtq6TPmb/wrpNPgkNWcr4A245oyZ1uEi6vAn
# Qj0llOZ0dFtq0Z4+7X6gMTN9vMvpe784cETRkPHIqzqKOghif9lwY1NNje6CbaUF
# EMFxBmoQtB1VM1izoXBm8qGCA1kwggJBAgEBMIIBAaGB2aSB1jCB0zELMAkGA1UE
# BhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAc
# BgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMkTWljcm9zb2Z0
# IElyZWxhbmQgT3BlcmF0aW9ucyBMaW1pdGVkMScwJQYDVQQLEx5uU2hpZWxkIFRT
# UyBFU046NDMxQS0wNUUwLUQ5NDcxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0
# YW1wIFNlcnZpY2WiIwoBATAHBgUrDgMCGgMVAPeGfm1CZ/pysAbyCOrINDcu2jw2
# oIGDMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAO
# BgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEm
# MCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwDQYJKoZIhvcN
# AQELBQACBQDsBp7uMCIYDzIwMjUwNjI1MTYxNDM4WhgPMjAyNTA2MjYxNjE0Mzha
# MHcwPQYKKwYBBAGEWQoEATEvMC0wCgIFAOwGnu4CAQAwCgIBAAICCjICAf8wBwIB
# AAICEt0wCgIFAOwH8G4CAQAwNgYKKwYBBAGEWQoEAjEoMCYwDAYKKwYBBAGEWQoD
# AqAKMAgCAQACAwehIKEKMAgCAQACAwGGoDANBgkqhkiG9w0BAQsFAAOCAQEAM5Vg
# BfBBtyvjIVipQdNMIwPE00VP0MZ8buSBIPYRp0Nr3Fo8Xmuvn8sYmBK1WrZHXqw2
# Y//bFZI4lQTpOt+h9d+kFCZmQUZ7Gpe59jUB4MoURMhw4Uvs0I95nRZc2LAnYSMR
# dOurPHWQ2yI/7FF+3tSmjF3sHnMiGMRMUCN4eOt85DqocEHsT21Mva5tRYafDE9G
# Lsc7wXEyfDX3kj/Out+ko9+e89aaS9pBozzoV3MF2lYZTWyPJBs1UbyxrPASmqyv
# qqV21QrQER8Bz+OK6vBkcBuzKMO+U1o26pJNrX2qDKckXoy2co/DF+CB6I0enalX
# TG0NXJUCMu3AOCVRAzGCBA0wggQJAgEBMIGTMHwxCzAJBgNVBAYTAlVTMRMwEQYD
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1w
# IFBDQSAyMDEwAhMzAAAB+vs7RNN3M8bTAAEAAAH6MA0GCWCGSAFlAwQCAQUAoIIB
# SjAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwLwYJKoZIhvcNAQkEMSIEIGbu
# Yw9kIEhcvtw6pUqQW6yK8HQ4HdciN8Aq7zDLxU/vMIH6BgsqhkiG9w0BCRACLzGB
# 6jCB5zCB5DCBvQQgffJ/LcmvPgdo41P3aSUSMB8Bx6XKOaIDUrWKHG5DnlYwgZgw
# gYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE
# BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYD
# VQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAfr7O0TTdzPG
# 0wABAAAB+jAiBCAFrEZOj3xbc4v+bDP3rIqCHE/J8JhiANeqpVHnyPXGlDANBgkq
# hkiG9w0BAQsFAASCAgAwGfdHURIEyH2xbRXskEBOtTJISv1wuS0a2yIROAd1N24h
# 75U1ESosap4KYTYCWCacdhl6tsAO+R0QnurLtdBlz65Gxt+2zwphnOiincN9b1oZ
# yXsSf/B7OZuJuUeou8TMMItGH4NrtCVSBTLgRJuSleMwHmnhabZAPHkahZO6onT+
# Q5A2PBhvbZaJ+A2cWHc1S9GKMaoR7kbFMo3Q6m1THb2e7i8Iw7NwqVoua1hd3lUL
# 1rGhtK8bgY0w/gVqeSHXIaWI9f8GieDqZbxc+/y0yIickAd5KyuFQFU6oEW6pHav
# 68NvIdTW7geG2UiKO2Uo5/etuMfWd/pXqCsP9Y4YO4vJjVjPPdKYYdNkioRZtYCW
# 344HyblL0srmvd2r3eDQG4rVbrPxX4gptBIT1idbfgbAi5yusO0hlTuw2JNMeSg8
# +rWyBAQtg1KgwQAv44PsgJulnICMaYr/39akqnFUBWIRDSWT0570qt/aBEYjUHJ3
# sg+1OQKykx8+FWF+5OIBHUPdztri0r2gfsQGFek+y5yVJPxk3lndNiGdR5FP7cgs
# XwgCtcKMndanlHcFik+108e9UwwOCoyNFV8TU3s4ic4fH+naZPnvqLCYBJ9i3yEC
# JCcTh7yGePC0qqfrOrUv+cwx4fCYOg2xj9szXppCLgjHMt1HMm28HpUhiKKegw==
# SIG # End signature block