Handler/Handler.ps1

#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.
# See the License for the specific language governing permissions and
# limitations under the License.

#endregion

Set-StrictMode -Version Latest

enum Direction {
    Receive
    Send
}

<#
.SYNOPSIS
    Asserts the existence of a Microsoft BizTalk Server Adapter Handler.
.DESCRIPTION
    This command will throw if the Microsoft BizTalk Server Adapter Handler does not exist and will silently complete
    otherwise.
.PARAMETER Adapter
    The adapter name of the Microsoft BizTalk Server Adapter Handler.
.PARAMETER Host
    The host name of the Microsoft BizTalk Server Host Handler.
.PARAMETER Direction
    The direction of the Microsoft BizTalk Server Adapter Handler.
.EXAMPLE
    PS> Assert-BizTalkHandler -Adapter FILE -Host BizTalkServerApplication -Direction Send
.NOTES
    © 2020 be.stateless.
#>

function Assert-BizTalkHandler {
    [CmdletBinding()]
    [OutputType([void])]
    param(
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $Adapter,

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

        [Parameter(Mandatory = $true)]
        [Direction]
        $Direction
    )
    Resolve-ActionPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
    if (-not(Test-BizTalkHandler @PSBoundParameters)) {
        throw "Microsoft BizTalk Server $Direction '$Adapter' handler for '$Host' host does not exist."
    }
    Write-Verbose -Message "Microsoft BizTalk Server $Direction '$Adapter' handler for '$Host' host exists."
}

<#
.SYNOPSIS
    Gets information Microsoft BizTalk Server Adapter Handlers.
.DESCRIPTION
    Gets information Microsoft BizTalk Server Adapter Handlers.
.PARAMETER Adapter
    The adapter name of the Microsoft BizTalk Server Adapter Handlers.
.PARAMETER Host
    The host name of the Microsoft BizTalk Server Host Handlers.
.PARAMETER Direction
    The direction of the Microsoft BizTalk Server Adapter Handlers.
.OUTPUTS
    Returns information about Microsoft BizTalk Server Adapter Handlers.
.EXAMPLE
    PS> Get-BizTalkHandler -Adapter FILE
.EXAMPLE
    PS> Get-BizTalkHandler -Host BiztAlkServerIsolatedHost
.EXAMPLE
    PS> Get-BizTalkHandler -Direction Send
.EXAMPLE
    PS> Get-BizTalkHandler -Adapter FILE -Host BizTalkServerApplication -Direction Send
.NOTES
    © 2020 be.stateless.
#>

function Get-BizTalkHandler {
    [CmdletBinding()]
    [OutputType([PSCustomObject[]])]
    param(
        [Parameter(Mandatory = $false)]
        [AllowEmptyString()]
        [AllowNull()]
        [string[]]
        $Adapter = @([string]::Empty),

        [Parameter(Mandatory = $false)]
        [AllowEmptyString()]
        [AllowNull()]
        [string[]]
        $Host = @([string]::Empty),

        [Parameter(Mandatory = $false)]
        [Direction[]]
        $Direction = @([Direction]::Receive, [Direction]::Send)
    )
    Resolve-ActionPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
    foreach ($d in $Direction) {
        $className = Get-HandlerCimClassName -Direction $d
        foreach ($a in $Adapter) {
            foreach ($h in $Host) {
                $filter = if (![string]::IsNullOrWhiteSpace($a) -and ![string]::IsNullOrWhiteSpace($h)) {
                    "AdapterName='$a' and HostName='$h'"
                } elseif (![string]::IsNullOrWhiteSpace($a)) {
                    "AdapterName='$a'"
                } elseif (![string]::IsNullOrWhiteSpace($h)) {
                    "HostName='$h'"
                }
                Get-CimInstance -ErrorAction Stop -Namespace root/MicrosoftBizTalkServer -ClassName $className -Filter $filter |
                    Add-Member -NotePropertyName Direction -NotePropertyValue $d -PassThru
            }
        }
    }
}

<#
.SYNOPSIS
    Creates a Microsoft BizTalk Server Adapter Handler.
.DESCRIPTION
    Creates a Microsoft BizTalk Server Adapter Handler.
.PARAMETER Adapter
    The adapter name of the Microsoft BizTalk Server Adapter Handler.
.PARAMETER Host
    The host name of the Microsoft BizTalk Server Host Handler.
.PARAMETER Direction
    The direction of the Microsoft BizTalk Server Adapter Handler.
.PARAMETER Default
    Whether the Microsoft BizTalk Server Adapter Handler to be created will be the default Adapter Handler.
.EXAMPLE
    PS> New-BizTalkHandler -Adapter FILE -Host BizTalkServerApplication -Direction Receive
.LINK
    https://docs.microsoft.com/en-us/biztalk/core/technical-reference/creating-an-ftp-receive-handler-using-wmi
.NOTES
    © 2020 be.stateless.
#>

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

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

        [Parameter(Mandatory = $true)]
        [Direction]
        $Direction,

        # TODO refactor $Default as a Dynamic param which is only availble when $Direction = Send
        [Parameter(Mandatory = $false)]
        [switch]
        $Default
    )
    Resolve-ActionPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
    if (Test-BizTalkHandler -Adapter $Adapter -Host $Host -Direction $Direction) {
        Write-Information -MessageData "`t Microsoft BizTalk Server $Direction '$Adapter' handler for '$Host' host has already been created."
    } elseif ($PsCmdlet.ShouldProcess($globalMessages.Should_Target, "Creating $Direction '$Adapter' handler for '$Host' host")) {
        Write-Information -MessageData "`t Creating Microsoft BizTalk Server $Direction '$Adapter' handler for '$Host' host..."
        $className = Get-HandlerCimClassName -Direction $Direction
        $properties = @{ AdapterName = $Adapter ; HostName = $Host }
        if ($Direction -eq 'Send' -and $Default.IsPresent) { $properties.IsDefault = [bool]$Default }
        New-CimInstance -ErrorAction Stop -Namespace root/MicrosoftBizTalkServer -ClassName $className -Property $properties | Out-Null
        Write-Information -MessageData "`t Microsoft BizTalk Server $Direction '$Adapter' handler for '$Host' host has been created."
    }
}

<#
.SYNOPSIS
    Removes a Microsoft BizTalk Server Adapter Handler.
.DESCRIPTION
    Removes a Microsoft BizTalk Server Adapter Handler.
.PARAMETER Adapter
    The adapter name of the Microsoft BizTalk Server Adapter Handler.
.PARAMETER Host
    The host name of the Microsoft BizTalk Server Host Handler.
.PARAMETER Direction
    The direction of the Microsoft BizTalk Server Adapter Handler.
.EXAMPLE
    PS> Remove-BizTalkHandler -Adapter FILE -Host BizTalkServerApplication -Direction Receive
.NOTES
    © 2020 be.stateless.
#>

function Remove-BizTalkHandler {
    [CmdletBinding(SupportsShouldProcess = $true)]
    [OutputType([void])]
    param(
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $Adapter,

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

        [Parameter(Mandatory = $true)]
        [Direction]
        $Direction
    )
    Resolve-ActionPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
    if (-not(Test-BizTalkHandler -Adapter $Adapter -Host $Host -Direction $Direction)) {
        Write-Information -MessageData "`t Microsoft BizTalk Server $Direction '$Adapter' handler for '$Host' host has already been removed."
    } elseif ($PsCmdlet.ShouldProcess($globalMessages.Should_Target, "Removing $Direction '$Adapter' handler for '$Host' host")) {
        Write-Information -MessageData "`t Removing Microsoft BizTalk Server $Direction '$Adapter' handler for '$Host' host..."
        $className = Get-HandlerCimClassName -Direction $Direction
        # TODO will fail if try to remove default send handler
        $instance = Get-CimInstance -ErrorAction Stop -Namespace root/MicrosoftBizTalkServer -ClassName $className -Filter "AdapterName='$Adapter' and HostName='$Host'"
        Remove-CimInstance -ErrorAction Stop -InputObject $instance
        Write-Information -MessageData "`t Microsoft BizTalk Server $Direction '$Adapter' handler for '$Host' host has been removed."
    }
}

<#
.SYNOPSIS
    Returns whether a Microsoft BizTalk Server Adapter Handler exists.
.DESCRIPTION
    This command will return $true if the Microsoft BizTalk Server Adapter Handler exists; $false otherwise.
.PARAMETER Adapter
    The adapter name of the Microsoft BizTalk Server Adapter Handler.
.PARAMETER Host
    The host name of the Microsoft BizTalk Server Host Handler.
.PARAMETER Direction
    The direction of the Microsoft BizTalk Server Adapter Handler.
.OUTPUTS
    $true if the Microsoft BizTalk Server handler exists; $false otherwise.
.EXAMPLE
    PS> Test-BizTalkHandler -Adapter FILE -Host BizTalkServerApplication -Direction Send
.NOTES
    © 2020 be.stateless.
#>

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

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

        [Parameter(Mandatory = $true)]
        [Direction]
        $Direction
    )
    Resolve-ActionPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
    $className = Get-HandlerCimClassName -Direction $Direction
    [bool] (Get-CimInstance -ErrorAction Stop -Namespace root/MicrosoftBizTalkServer -ClassName $className -Filter "AdapterName='$Adapter' and HostName='$Host'")
}

function Get-HandlerCimClassName {
    [CmdletBinding()]
    [OutputType([string])]
    param(
        [Parameter(Mandatory = $true)]
        [Direction]
        $Direction
    )
    if ($direction -eq [Direction]::Receive) { 'MSBTS_ReceiveHandler' } else { 'MSBTS_SendHandler2' }
}
# SIG # Begin signature block
# MIIJEgYJKoZIhvcNAQcCoIIJAzCCCP8CAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU2R8Ht6llY+AIqFh6dL25XQhy
# NDegggWhMIIFnTCCA1GgAwIBAgIQKBOAjgMDO55A7UJ/k/g5nTBBBgkqhkiG9w0B
# AQowNKAPMA0GCWCGSAFlAwQCAQUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQC
# AQUAogMCASAwJjEkMCIGA1UEAwwbaWNyYWZ0c29mdHdhcmVAc3RhdGVsZXNzLmJl
# MB4XDTIwMDYyMzExNDM1NloXDTIxMDYyMzEyMDM1NlowJjEkMCIGA1UEAwwbaWNy
# YWZ0c29mdHdhcmVAc3RhdGVsZXNzLmJlMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
# MIICCgKCAgEAmQcb0GwlBHBHBJZ9vNM8EewN7T+nhsWVU0WBoWnIw6UAT99Rw9x5
# RcfOQU2hxqKmR1k+iI6B+qddpTC3VLSChA/mh1P4pCDDsZeyR/0nn/r/DezhDe8x
# 5jckjR88KSRcgDoh0kLjgfrToDpx9EvBcwXmNJKDwBIWu5SBvk04beU4XO7OHjBo
# g0kMaHxCZc9HcWfdzBefP+fbVzu6f1j1WgEqZn9sr1ML2ulHRdu26+56xGq9RZGJ
# vXyY1mY+K5mqBcET+1bV2pZnBrM3Gc/hlmvTkwrC0ZGBALLZWZqqpLVrDCY5eoHP
# w2C0kA4JzK4Q1o218s+wXbuDcjYRIZqBSwI8fizR/4DS+6dEjfa3kzs2z/MrkJOk
# hJ06tiMSRr55tX1DR8NwVLdiNqZYvs4zP2ZNRMMI8uFCjkP/Wn1hfBr+GSPlgdLq
# 2TFishY2pj5O1WlE/tCz+B0YLhPWdfbVEp8kB3fGBsVf7uw4STK/wDA1MYRIHikt
# w+K9gtdf0eIR9dYX9CMwoDN2TNLK6vnCWMrzWFe5EOU3/oljUBkyQT838a5A6wMu
# cGeu7Cwjdigylt7ULaTglL7ORIyaRbzkltxd+1oaQ21kjl4ef0ZD2gWLj7bwrZR+
# KWCfmaHFoZlVRKNPtScuyOnilPGGZ6T7SNuwVxSXFRtbp+cQea4UxxUCAwEAAaNf
# MF0wDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMBcGA1UdEQQQ
# MA6CDHN0YXRlbGVzcy5iZTAdBgNVHQ4EFgQUq4sCoE2IqN4K4uwNuibjqd5yNNQw
# QQYJKoZIhvcNAQEKMDSgDzANBglghkgBZQMEAgEFAKEcMBoGCSqGSIb3DQEBCDAN
# BglghkgBZQMEAgEFAKIDAgEgA4ICAQBR98amLpANKFlc7mPlkaV4ZtS2uTmbJ6dO
# qzyWKJ2yTmv7U9yq8PdEH9mPJlxYvGyNgxqHoocKv1SdjgYh27SM8pDnsfU2NpER
# 6K/3sICy6Orh9vhC+U18Bp93WoLEezolaBcF0co3/o+HazOvs/2zBFONFHMkef9/
# 3Bipm0sd95teHo53vLKViHbjSmoGxYsvJJiYITB4Zeo6xgUAmwcUpL1To62Lb3RP
# CDLKZQ5h8Ir07nncV4HLq+0qF3+G9Y0IXHJv6Qcr/XTTLo0J877HRqS37WJcgF8+
# 2nbZbqO9NVvp14A4nTqpeDFmzewDU33hiZvzuLHBj//OgLgGZ9lJPxCu0tVxfFWZ
# INHg1YHp3lMaAw00Q3tb/vhc5kE6Kl7FnXnUTsu4j+vUoaFMWhYezoyn9m4rD+xN
# RITrbLPZdWAZvVOJ8ehmswRhfiMZ1npwbrk7KU1UTsmMS7PHREWSyUM28WlMFf2i
# ut8TlY/MV/adUGr2GpqBWhxp5DRgfl1uamKm2wFlCra3/kReVlQgC/Bbod2JOgJW
# t8zCbO4nJx+fJYwM9RG70h/TmuqzP8uChsHtKcgs2YtXmSm12JZakXY4IflInI7p
# ddDEs9UOfsWXDsqpvmFQZbwgGeNeEsPk3Fdm1MzDtS9PBXMk4jGGXNzEsVUgwf42
# 2HuDWeX/4jGCAtswggLXAgEBMDowJjEkMCIGA1UEAwwbaWNyYWZ0c29mdHdhcmVA
# c3RhdGVsZXNzLmJlAhAoE4COAwM7nkDtQn+T+DmdMAkGBSsOAwIaBQCgeDAYBgor
# BgEEAYI3AgEMMQowCKACgAChAoAAMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEE
# MBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMCMGCSqGSIb3DQEJBDEWBBR+
# cJ9SQIxuMjLw/EmsVJOKAz391zANBgkqhkiG9w0BAQEFAASCAgBXVL0DPlBauwI0
# eolmZb2XkyxoTd8TLy5Bvilvl0oIhKlpqF4lX6BtLe7P5XCT3PcyxnBm4kMAgqWK
# UHPsLSMyFhwi+PL/Qnal6mwDpyftBhkqerbDKuBBgufkJ4VkKhN/IhQOyXs4svbO
# tAJ1kwBI3Ujq7v+hb3jPugc0bb3YEb1IFy3amyy8kE+x3DL/aMARbJqoWee4pq6H
# iBkH4ix24gc6nogjVlBxJsz6l8UyEJZDxOrULkAQR4goYS4rMouNPFLsgJjMGTDR
# 6vVFVystgIWDh1nFlB9DQHNpYiBngL+R5qMXBUelkbSfi0mI/ckrrKq9qypAMFLi
# smp54bcU27I+DfXCARfI+6fKAMomciqZ+iQCi4Xevsj8NZ7hAQ9/wu0/IE/HX90v
# uzfAPah9wNS9KEFke5VujJy8tT/G2187Ct3+yHputegIjy//C/S9Swj8Dy1hxxPF
# youZgU7ffG2nXERAgk7r676ZGlnKQDHII1THzX4tAm+AUkFaTyV0Usn0N2k347lR
# 5//k35I+Q7pm/S8AGHhhUSpXWRd7GmWc49UxWIazWOeehA/zQp7Ri+txjU2ywJOy
# dsJWhD9JvUJO6+N3yDIx0dEjn3vDidkFSoq7v7wuvG2jRtp3q8FujAEVFfv7kwBq
# b134zj8OznFwj50eo9gGuZuQ8xGUhA==
# SIG # End signature block