Host/Host.psm1

#region Copyright & License

# Copyright © 2012 - 2020 François Chabot
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.u
# See the License for the specific language governing permissions and
# limitations under the License.

#endregion

Set-StrictMode -Version Latest

enum HostType {
    InProcess = [Microsoft.BizTalk.ExplorerOM.HostType]::InProcess
    Isolated = [Microsoft.BizTalk.ExplorerOM.HostType]::Isolated
}

<#
.SYNOPSIS
    Asserts the existence of a Microsoft BizTalk Server Host.
.DESCRIPTION
    This command will throw if the Microsoft BizTalk Server Host does not exist and will silently complete otherwise.
.PARAMETER Name
    The name of the Microsoft BizTalk Server Host.
.EXAMPLE
    PS> Assert-BizTalkHost -Name 'Transmit Host'
.EXAMPLE
    PS> Assert-BizTalkHost -Name 'Transmit Host' -Verbose
.NOTES
    © 2020 be.stateless.
#>

function Assert-BizTalkHost {
    [CmdletBinding()]
    [OutputType([void])]
    param(
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $Name
    )
    Resolve-ActionPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
    if (-not(Test-BizTalkHost @PSBoundParameters)) {
        throw "Microsoft BizTalk Server Host '$Name' does not exist."
    }
    Write-Verbose "Microsoft BizTalk Server Host '$Name' exists."
}

<#
.SYNOPSIS
    Gets information about the Microsoft BizTalk Server Hosts.
.DESCRIPTION
    Gets either summary or detailed information about the Microsoft BizTalk Server Hosts.
.PARAMETER Name
    The name of the Microsoft BizTalk Server Host.
.PARAMETER Detailed
    To get detailed, instead of summary, information about the Microsoft BizTalk Server Hosts.
.OUTPUTS
    Returns information about the Microsoft BizTalk Server Hosts.
.EXAMPLE
    PS> Get-BizTalkHost
.EXAMPLE
    PS> Get-BizTalkHost -Name 'Transmit Host'
.EXAMPLE
    PS> Get-BizTalkHost -Name 'Transmit Host' -Detailed
.NOTES
    © 2020 be.stateless.
#>

function Get-BizTalkHost {
    [CmdletBinding()]
    [OutputType([PSCustomObject[]])]
    param(
        [Parameter(Position = 0, Mandatory = $false)]
        [AllowEmptyString()]
        [AllowNull()]
        [string]
        $Name,

        [Parameter(Mandatory = $false)]
        [switch]
        $Detailed
    )
    Resolve-ActionPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
    $className = if ($Detailed) { 'MSBTS_HostSetting' } else { 'MSBTS_Host' }
    $filter = if (![string]::IsNullOrWhiteSpace($Name)) {
        "Name='$Name'"
    }
    Get-CimInstance -ErrorAction Stop -Namespace root/MicrosoftBizTalkServer -ClassName $className -Filter $filter
}

<#
.SYNOPSIS
    Creates a new Microsoft BizTalk Server Host.
.DESCRIPTION
    Creates and configures a new Microsoft BizTalk Server Host.
.PARAMETER Name
    The name of the Microsoft BizTalk Server Host.
.PARAMETER Type
    The type of the Microsoft BizTalk Server Host, either InProcess or Isolated.
.PARAMETER Group
    The Windows Domain Group used to control access of this host.
.PARAMETER x86
    Whether instances of this host will be 32-bit only processes.
.PARAMETER Default
    Whether this host is to be the default host in the Microsoft BizTalk Server Group or not.
.PARAMETER Tracking
    Wheter to enable the Microsoft BizTalk Server Tracking component for this host or not.
.PARAMETER Trusted
    Whether Microsoft BizTalk Server should trust this host or not.
.EXAMPLE
    PS> New-BizTalkHost -Name 'Transmit Host' -Type InProcess -Group 'BizTalk Application Users'
.EXAMPLE
    PS> New-BizTalkHost -Name 'Transmit Host' -Type InProcess -Group 'BizTalk Application Users' -x86
.EXAMPLE
    PS> New-BizTalkHost -Name 'Transmit Host' -Type InProcess -Group 'BizTalk Application Users' -x86:$false
.EXAMPLE
    PS> New-BizTalkHost -Name 'Transmit Host' -Type InProcess -Group 'BizTalk Application Users' -Verbose
.EXAMPLE
    PS> New-BizTalkHost -Name 'Transmit Host' -Type InProcess -Group 'BizTalk Application Users' -WhatIf
.LINK
    https://msdn.microsoft.com/en-us/library/aa560467.aspx, Creating, Updating, and Deleting a Host Instance Using WMI
.NOTES
    © 2020 be.stateless.
#>

function New-BizTalkHost {
    [CmdletBinding(SupportsShouldProcess = $true)]
    [OutputType([void])]
    param(
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $Name,

        [Parameter(Mandatory = $true)]
        [HostType]
        $Type,

        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $Group,

        [Parameter(Mandatory = $false)]
        [switch]
        $x86,

        [Parameter(Mandatory = $false)]
        [switch]
        $Default,

        [Parameter(Mandatory = $false)]
        [switch]
        $Tracking,

        [Parameter(Mandatory = $false)]
        [switch]
        $Trusted
    )
    Resolve-ActionPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
    if (Test-BizTalkHost -Name $Name) {
        Write-Information "`t Microsoft BizTalk Server $Type '$Name' host has already been created."
    } elseif ($PsCmdlet.ShouldProcess("Microsoft BizTalk Server Group", "Creating $Type '$Name' host")) {
        Write-Information "`t Creating Microsoft BizTalk Server $Type '$Name' host with '$Group' Windows Domain Group..."
        $instanceClass = Get-CimClass -ErrorAction Stop -Namespace root/MicrosoftBizTalkServer -ClassName MSBTS_HostSetting
        $instance = New-CimInstance -ErrorAction Stop -CimClass $instanceClass -Property @{
            Name            = $Name
            HostType        = [Uint32]$Type
            NTGroupName     = $Group
            IsHost32BitOnly = [bool]$x86
            IsDefault       = [bool]$Default
            HostTracking    = [bool]$Tracking
            AuthTrusted     = [bool]$Trusted
        }
        Set-CimInstance -ErrorAction Stop -InputObject $instance
        Write-Information "`t Microsoft BizTalk Server $Type '$Name' host has been created."
    }
}

<#
.SYNOPSIS
    Removes a Microsoft BizTalk Server Host.
.DESCRIPTION
    Removes a Microsoft BizTalk Server Host.
.PARAMETER Name
    The name of the Microsoft BizTalk Server Host.
.EXAMPLE
    PS> Remove-BizTalkHost -Name 'Transmit Host'
.NOTES
    © 2020 be.stateless.
#>

function Remove-BizTalkHost {
    [CmdletBinding(SupportsShouldProcess = $true)]
    [OutputType([void])]
    param(
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $Name
    )
    Resolve-ActionPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
    if (-not(Test-BizTalkHost -Name $Name)) {
        Write-Information "`t Microsoft BizTalk Server '$Name' host has already been removed."
    } elseif ($PsCmdlet.ShouldProcess("Microsoft BizTalk Server Group", "Removing '$Name' host")) {
        Write-Information "`t Removing Microsoft BizTalk Server '$Name' host..."
        $instance = Get-CimInstance -ErrorAction Stop -Namespace root/MicrosoftBizTalkServer -ClassName MSBTS_HostSetting -Filter "Name='$Name'"
        Remove-CimInstance -ErrorAction Stop -InputObject $instance
        Write-Information "`t Microsoft BizTalk Server '$Name' host has been removed."
    }
}

<#
.SYNOPSIS
    Returns whether a Microsoft BizTalk Server Host type exists.
.DESCRIPTION
    This command will return $true if the Microsoft BizTalk Server Host exists; $false otherwise. The existence test
    can be narrowed down to a particular Type of Microsoft BizTalk Server Host, i.e. either InProcess or Isolated.
.PARAMETER Name
    The name of the Microsoft BizTalk Server Host.
.PARAMETER Type
    The type of the Microsoft BizTalk Server Host.
.OUTPUTS
    $true if the Microsoft BizTalk Server Host exists and is of the given Type; $false otherwise.
.EXAMPLE
    PS> Test-BizTalkHost -Name 'Transmit Host'
.EXAMPLE
    PS> Test-BizTalkHost -Name 'Transmit Host' -Type Isolated
.NOTES
    © 2020 be.stateless.
#>

function Test-BizTalkHost {
    [CmdletBinding()]
    [OutputType([bool])]
    param(
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $Name,

        [Parameter(Mandatory = $false)]
        [HostType]
        $Type
    )
    Resolve-ActionPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
    $btsHost = Get-CimInstance -ErrorAction Stop -Namespace root/MicrosoftBizTalkServer -ClassName MSBTS_HostSetting -Filter "Name='$Name'"
    [bool]$btsHost -and (-not $PSBoundParameters.ContainsKey('Type') -or $btsHost.HostType -eq $Type)
}

<#
.SYNOPSIS
    Updates the configuration settings of a Microsoft BizTalk Server Host.
.DESCRIPTION
    Updates the configuration settings of a Microsoft BizTalk Server Host.
.PARAMETER Name
    The name of the Microsoft BizTalk Server Host.
.PARAMETER x86
    Whether instances of this host will be 32-bit only processes.
.PARAMETER Default
    Whether this host is to be the default host in the Microsoft BizTalk Server group or not.
.PARAMETER Tracking
    Wheter to enable the Microsoft BizTalk Server Tracking component for this host or not.
.PARAMETER Trusted
    Whether Microsoft BizTalk Server should trust this host or not.
.EXAMPLE
    PS> Update-BizTalkHost -Name 'Transmit Host' -x86 -Verbose
    With the -Verbose switch, this command will confirm this process is 32 bit.
.EXAMPLE
    PS> Update-BizTalkHost -Name 'Transmit Host' -x86 -Verbose -WhatIf
.EXAMPLE
    PS> Update-BizTalkHost -Name 'Transmit Host' -x86:$false -Verbose
    With the -Verbose switch, this command will confirm this process is not 32 bit.
.NOTES
    © 2020 be.stateless.
#>

function Update-BizTalkHost {
    [CmdletBinding(SupportsShouldProcess = $true)]
    [OutputType([void])]
    param(
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $Name,

        [Parameter(Mandatory = $false)]
        [bool]
        $x86,

        [Parameter(Mandatory = $false)]
        [switch]
        $Default,

        [Parameter(Mandatory = $false)]
        [bool]
        $Tracking,

        [Parameter(Mandatory = $false)]
        [bool]
        $Trusted
    )

    function Set-BizTalkHostProperty {
        [CmdletBinding(SupportsShouldProcess = $true)]
        [OutputType([void])]
        param(
            [Parameter(Mandatory = $true)]
            [string]
            $Name,

            [Parameter(Mandatory = $true)]
            [string]
            $Property,

            [Parameter(Mandatory = $true)]
            [object]
            $Value,

            [Parameter(Mandatory = $true)]
            [string]
            $ActionToPerform,

            [Parameter(Mandatory = $true)]
            [string]
            $PerformedAction
        )
        $instance = Get-CimInstance -ErrorAction Stop -Namespace root/MicrosoftBizTalkServer -ClassName MSBTS_HostSetting -Filter "Name='$Name'"
        if ($instance.$Property -ne $value -and $PsCmdlet.ShouldProcess("Microsoft BizTalk Server Group", $ActionToPerform)) {
            Write-Information "`t $ActionToPerform..."
            $instance.$Property = $Value
            Set-CimInstance -ErrorAction Stop -InputObject $instance
            Write-Information "`t $PerformedAction."
        }
    }

    Resolve-ActionPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
    if (Test-BizTalkHost -Name $Name) {
        if ($PSBoundParameters.ContainsKey('x86')) {
            $subject = "'$Name' host's 32-bit only restriction"
            Set-BizTalkHostProperty -Name $Name -Property IsHost32BitOnly -Value $x86 `
                -ActionToPerform ("{1} {0}" -f $Subject, (@('Enabling', 'Disabling')[!$x86])) `
                -PerformedAction ("{0} has been {1}" -f $Subject, (@('enabled', 'disabled')[!$x86]))
        }

        if ($Default.IsPresent -and -not $btsHost.IsDefault) {
            Set-BizTalkHostProperty -Name $Name -Property IsDefault -Value $Default `
                -ActionToPerform "Setting '$Name' host as default Microsoft BizTalk Server Group host" `
                -PerformedAction "'$Name' host has been set as default Microsoft BizTalk Server Group host"
        }

        if ($PSBoundParameters.ContainsKey('Tracking')) {
            $subject = "'$Name' host's Tracking capability"
            Set-BizTalkHostProperty -Name $Name -Property HostTracking -Value $Tracking `
                -ActionToPerform ("{1} {0}" -f $Subject, (@('Enabling', 'Disabling')[!$Tracking])) `
                -PerformedAction ("{0} has been {1}" -f $Subject, (@('enabled', 'disabled')[!$Tracking]))
        }

        if ($PSBoundParameters.ContainsKey('Trusted')) {
            $subject = "'$Name' host's Trusted Authentication"
            Set-BizTalkHostProperty -Name $Name -Property AuthTrusted -Value $Trusted `
                -ActionToPerform ("{1} {0}" -f $Subject, (@('Enabling', 'Disabling')[!$Trusted])) `
                -PerformedAction ("{0} has been {1}" -f $Subject, (@('enabled', 'disabled')[!$Trusted]))
        }
    } else {
        Write-Information "`t Microsoft BizTalk Server '$Name' host does not exist."
    }
}

# SIG # Begin signature block
# MIITugYJKoZIhvcNAQcCoIITqzCCE6cCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUiZ3g6+1XjwoXPw0aLkM8+9ew
# GbOggg46MIID7jCCA1egAwIBAgIQfpPr+3zGTlnqS5p31Ab8OzANBgkqhkiG9w0B
# AQUFADCBizELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTEUMBIG
# A1UEBxMLRHVyYmFudmlsbGUxDzANBgNVBAoTBlRoYXd0ZTEdMBsGA1UECxMUVGhh
# d3RlIENlcnRpZmljYXRpb24xHzAdBgNVBAMTFlRoYXd0ZSBUaW1lc3RhbXBpbmcg
# Q0EwHhcNMTIxMjIxMDAwMDAwWhcNMjAxMjMwMjM1OTU5WjBeMQswCQYDVQQGEwJV
# UzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xMDAuBgNVBAMTJ1N5bWFu
# dGVjIFRpbWUgU3RhbXBpbmcgU2VydmljZXMgQ0EgLSBHMjCCASIwDQYJKoZIhvcN
# AQEBBQADggEPADCCAQoCggEBALGss0lUS5ccEgrYJXmRIlcqb9y4JsRDc2vCvy5Q
# WvsUwnaOQwElQ7Sh4kX06Ld7w3TMIte0lAAC903tv7S3RCRrzV9FO9FEzkMScxeC
# i2m0K8uZHqxyGyZNcR+xMd37UWECU6aq9UksBXhFpS+JzueZ5/6M4lc/PcaS3Er4
# ezPkeQr78HWIQZz/xQNRmarXbJ+TaYdlKYOFwmAUxMjJOxTawIHwHw103pIiq8r3
# +3R8J+b3Sht/p8OeLa6K6qbmqicWfWH3mHERvOJQoUvlXfrlDqcsn6plINPYlujI
# fKVOSET/GeJEB5IL12iEgF1qeGRFzWBGflTBE3zFefHJwXECAwEAAaOB+jCB9zAd
# BgNVHQ4EFgQUX5r1blzMzHSa1N197z/b7EyALt0wMgYIKwYBBQUHAQEEJjAkMCIG
# CCsGAQUFBzABhhZodHRwOi8vb2NzcC50aGF3dGUuY29tMBIGA1UdEwEB/wQIMAYB
# Af8CAQAwPwYDVR0fBDgwNjA0oDKgMIYuaHR0cDovL2NybC50aGF3dGUuY29tL1Ro
# YXd0ZVRpbWVzdGFtcGluZ0NBLmNybDATBgNVHSUEDDAKBggrBgEFBQcDCDAOBgNV
# HQ8BAf8EBAMCAQYwKAYDVR0RBCEwH6QdMBsxGTAXBgNVBAMTEFRpbWVTdGFtcC0y
# MDQ4LTEwDQYJKoZIhvcNAQEFBQADgYEAAwmbj3nvf1kwqu9otfrjCR27T4IGXTdf
# plKfFo3qHJIJRG71betYfDDo+WmNI3MLEm9Hqa45EfgqsZuwGsOO61mWAK3ODE2y
# 0DGmCFwqevzieh1XTKhlGOl5QGIllm7HxzdqgyEIjkHq3dlXPx13SYcqFgZepjhq
# IhKjURmDfrYwggSjMIIDi6ADAgECAhAOz/Q4yP6/NW4E2GqYGxpQMA0GCSqGSIb3
# DQEBBQUAMF4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3Jh
# dGlvbjEwMC4GA1UEAxMnU3ltYW50ZWMgVGltZSBTdGFtcGluZyBTZXJ2aWNlcyBD
# QSAtIEcyMB4XDTEyMTAxODAwMDAwMFoXDTIwMTIyOTIzNTk1OVowYjELMAkGA1UE
# BhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMTQwMgYDVQQDEytT
# eW1hbnRlYyBUaW1lIFN0YW1waW5nIFNlcnZpY2VzIFNpZ25lciAtIEc0MIIBIjAN
# BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAomMLOUS4uyOnREm7Dv+h8GEKU5Ow
# mNutLA9KxW7/hjxTVQ8VzgQ/K/2plpbZvmF5C1vJTIZ25eBDSyKV7sIrQ8Gf2Gi0
# jkBP7oU4uRHFI/JkWPAVMm9OV6GuiKQC1yoezUvh3WPVF4kyW7BemVqonShQDhfu
# ltthO0VRHc8SVguSR/yrrvZmPUescHLnkudfzRC5xINklBm9JYDh6NIipdC6Anqh
# d5NbZcPuF3S8QYYq3AhMjJKMkS2ed0QfaNaodHfbDlsyi1aLM73ZY8hJnTrFxeoz
# C9Lxoxv0i77Zs1eLO94Ep3oisiSuLsdwxb5OgyYI+wu9qU+ZCOEQKHKqzQIDAQAB
# o4IBVzCCAVMwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAO
# BgNVHQ8BAf8EBAMCB4AwcwYIKwYBBQUHAQEEZzBlMCoGCCsGAQUFBzABhh5odHRw
# Oi8vdHMtb2NzcC53cy5zeW1hbnRlYy5jb20wNwYIKwYBBQUHMAKGK2h0dHA6Ly90
# cy1haWEud3Muc3ltYW50ZWMuY29tL3Rzcy1jYS1nMi5jZXIwPAYDVR0fBDUwMzAx
# oC+gLYYraHR0cDovL3RzLWNybC53cy5zeW1hbnRlYy5jb20vdHNzLWNhLWcyLmNy
# bDAoBgNVHREEITAfpB0wGzEZMBcGA1UEAxMQVGltZVN0YW1wLTIwNDgtMjAdBgNV
# HQ4EFgQURsZpow5KFB7VTNpSYxc/Xja8DeYwHwYDVR0jBBgwFoAUX5r1blzMzHSa
# 1N197z/b7EyALt0wDQYJKoZIhvcNAQEFBQADggEBAHg7tJEqAEzwj2IwN3ijhCcH
# bxiy3iXcoNSUA6qGTiWfmkADHN3O43nLIWgG2rYytG2/9CwmYzPkSWRtDebDZw73
# BaQ1bHyJFsbpst+y6d0gxnEPzZV03LZc3r03H0N45ni1zSgEIKOq8UvEiCmRDoDR
# EfzdXHZuT14ORUZBbg2w6jiasTraCXEQ/Bx5tIB7rGn0/Zy2DBYr8X9bCT2bW+IW
# yhOBbQAuOA2oKY8s4bL0WqkBrxWcLC9JG9siu8P+eJRRw4axgohd8D20UaF5Mysu
# e7ncIAkTcetqGVvP6KUwVyyJST+5z3/Jvz4iaGNTmr1pdKzFHTx/kuDDvBzYBHUw
# ggWdMIIDUaADAgECAhAoE4COAwM7nkDtQn+T+DmdMEEGCSqGSIb3DQEBCjA0oA8w
# DQYJYIZIAWUDBAIBBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAIBBQCiAwIB
# IDAmMSQwIgYDVQQDDBtpY3JhZnRzb2Z0d2FyZUBzdGF0ZWxlc3MuYmUwHhcNMjAw
# NjIzMTE0MzU2WhcNMjEwNjIzMTIwMzU2WjAmMSQwIgYDVQQDDBtpY3JhZnRzb2Z0
# d2FyZUBzdGF0ZWxlc3MuYmUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
# AQCZBxvQbCUEcEcEln280zwR7A3tP6eGxZVTRYGhacjDpQBP31HD3HlFx85BTaHG
# oqZHWT6IjoH6p12lMLdUtIKED+aHU/ikIMOxl7JH/Sef+v8N7OEN7zHmNySNHzwp
# JFyAOiHSQuOB+tOgOnH0S8FzBeY0koPAEha7lIG+TTht5Thc7s4eMGiDSQxofEJl
# z0dxZ93MF58/59tXO7p/WPVaASpmf2yvUwva6UdF27br7nrEar1FkYm9fJjWZj4r
# maoFwRP7VtXalmcGszcZz+GWa9OTCsLRkYEAstlZmqqktWsMJjl6gc/DYLSQDgnM
# rhDWjbXyz7Bdu4NyNhEhmoFLAjx+LNH/gNL7p0SN9reTOzbP8yuQk6SEnTq2IxJG
# vnm1fUNHw3BUt2I2pli+zjM/Zk1Ewwjy4UKOQ/9afWF8Gv4ZI+WB0urZMWKyFjam
# Pk7VaUT+0LP4HRguE9Z19tUSnyQHd8YGxV/u7DhJMr/AMDUxhEgeKS3D4r2C11/R
# 4hH11hf0IzCgM3ZM0srq+cJYyvNYV7kQ5Tf+iWNQGTJBPzfxrkDrAy5wZ67sLCN2
# KDKW3tQtpOCUvs5EjJpFvOSW3F37WhpDbWSOXh5/RkPaBYuPtvCtlH4pYJ+ZocWh
# mVVEo0+1Jy7I6eKU8YZnpPtI27BXFJcVG1un5xB5rhTHFQIDAQABo18wXTAOBgNV
# HQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwFwYDVR0RBBAwDoIMc3Rh
# dGVsZXNzLmJlMB0GA1UdDgQWBBSriwKgTYio3gri7A26JuOp3nI01DBBBgkqhkiG
# 9w0BAQowNKAPMA0GCWCGSAFlAwQCAQUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFl
# AwQCAQUAogMCASADggIBAFH3xqYukA0oWVzuY+WRpXhm1La5OZsnp06rPJYonbJO
# a/tT3Krw90Qf2Y8mXFi8bI2DGoeihwq/VJ2OBiHbtIzykOex9TY2kRHor/ewgLLo
# 6uH2+EL5TXwGn3dagsR7OiVoFwXRyjf+j4drM6+z/bMEU40UcyR5/3/cGKmbSx33
# m14ejne8spWIduNKagbFiy8kmJghMHhl6jrGBQCbBxSkvVOjrYtvdE8IMsplDmHw
# ivTuedxXgcur7SoXf4b1jQhccm/pByv9dNMujQnzvsdGpLftYlyAXz7adtluo701
# W+nXgDidOql4MWbN7ANTfeGJm/O4scGP/86AuAZn2Uk/EK7S1XF8VZkg0eDVgene
# UxoDDTRDe1v++FzmQToqXsWdedROy7iP69ShoUxaFh7OjKf2bisP7E1EhOtss9l1
# YBm9U4nx6GazBGF+IxnWenBuuTspTVROyYxLs8dERZLJQzbxaUwV/aK63xOVj8xX
# 9p1QavYamoFaHGnkNGB+XW5qYqbbAWUKtrf+RF5WVCAL8Fuh3Yk6Ala3zMJs7icn
# H58ljAz1EbvSH9Oa6rM/y4KGwe0pyCzZi1eZKbXYllqRdjgh+Uicjul10MSz1Q5+
# xZcOyqm+YVBlvCAZ414Sw+TcV2bUzMO1L08FcyTiMYZc3MSxVSDB/jbYe4NZ5f/i
# MYIE6jCCBOYCAQEwOjAmMSQwIgYDVQQDDBtpY3JhZnRzb2Z0d2FyZUBzdGF0ZWxl
# c3MuYmUCECgTgI4DAzueQO1Cf5P4OZ0wCQYFKw4DAhoFAKB4MBgGCisGAQQBgjcC
# AQwxCjAIoAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYB
# BAGCNwIBCzEOMAwGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkEMRYEFC9UEDuptNH7
# nHOSBsGoWpt/XDSyMA0GCSqGSIb3DQEBAQUABIICABP8ts8sUxSXdpCb5Umj0fxk
# k91whpIoBIJYOoJgNe0GiPbuLDl/c8tDLQq2Pl3KMH9fblQyMjmCzdP/PHLDbR9d
# a37Y/BusbJs3v68ByxptKjK2JEaLz3SSOLLDUfdBK81hszID7ORGKcIiHVe34n3d
# 3iSHxCpx92mHMyqmFA2pLm8EEsaDWuN16NMdRXCp7oz7nA9yjyJAgCw/JBuSJ6uV
# WKslIbB9HRNJ44Uen4+m6/r0p3apWyQMV8RkswxSGzOr3H5bl3ex1mj4nIF5NZ2y
# k+dZjck0UjjiGMLGhnHkyWxzpuy4YkKZH3zr1JxFV9k/7rwkz9c7aK1rf7aG4ZRU
# 9oxEiLSsCkX68NV4EEIXiWYTM3ODIJ271EKMbqJ0QeQ2Tes9FWcV7wziv+DMb4qe
# CCAAmQ/RDgHMkfWELGv2Ht+Z+//GJhnZTbMVBH9FkQsuC42E1kNUSfkWqgMEKP69
# 0kODbBqkdji6HMoNnreBTNrBHlmGo7/2ZCEznFzI/2t9j2hYQF6DetoIQ1pMFkL1
# 2PcUr/WD475QQEfNZ9+UUWuOJ45yGm3p3MfrtijO8nJsleIjHBW4JeG6g35giYr9
# 5UVBL4h+kNe1P3eC+kpw9afYQBbbiZJqKB4/yMlM6X+6wPEDRaaXd7SXVUsNftjl
# aimBEdNP6GlUDyMrUyIKoYICCzCCAgcGCSqGSIb3DQEJBjGCAfgwggH0AgEBMHIw
# XjELMAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMTAw
# LgYDVQQDEydTeW1hbnRlYyBUaW1lIFN0YW1waW5nIFNlcnZpY2VzIENBIC0gRzIC
# EA7P9DjI/r81bgTYapgbGlAwCQYFKw4DAhoFAKBdMBgGCSqGSIb3DQEJAzELBgkq
# hkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTIwMDYzMDE0Mjc0NFowIwYJKoZIhvcN
# AQkEMRYEFBvpkJaokruYtN9VTtKl4gThPK7OMA0GCSqGSIb3DQEBAQUABIIBAE8c
# QO4S/nk1R1TLwrQawUD6DdcjxEeZ5/zLO6JTgi2WjLSGtl5a14wHze6Q4k1a4yaO
# csLbLk627WOo9fMSppdcFm4t64bJe5Bwz2rvLcjgYDcK0LY6khK0oE9q0ZbrR+XW
# et9J8a8+sLiv+yFpo+1hNY6aTrmvlBCdBaYI4wkO6C0kj9jXvr72wi+ypnPSHl5U
# Ale7JB12tWHNCD4017S0b769gBZAyyGzBlF04gZ9fZgDIztAuZfeHAaTX01Obc0m
# QB3WwWiAFgOjguuZplgezrokPFUYEC9Li16sb1YYTdYBLw/U06cD9WaPcnSEDHpz
# pjFuhoYmRhqepuigf98=
# SIG # End signature block