Handler/Handler.ps1

#region Copyright & License

# Copyright © 2012 - 2022 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
   © 2022 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
   © 2022 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
   © 2022 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
   © 2022 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
   © 2022 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
# MIII0QYJKoZIhvcNAQcCoIIIwjCCCL4CAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUWiX3l9zccIoKoLTSMTPK3k5J
# djygggVMMIIFSDCCAzCgAwIBAgIJAJkr3mJdTBkUMA0GCSqGSIb3DQEBCwUAMEEx
# PzA9BgNVBAMeNgBpAGMAcgBhAGYAdABzAG8AZgB0AHcAYQByAGUAQABzAHQAYQB0
# AGUAbABlAHMAcwAuAGIAZTAeFw0yMTA2MjUxNDEyMjNaFw00MTA2MjAxNDEyMjNa
# MEExPzA9BgNVBAMeNgBpAGMAcgBhAGYAdABzAG8AZgB0AHcAYQByAGUAQABzAHQA
# YQB0AGUAbABlAHMAcwAuAGIAZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
# ggIBAOeqdUHBv7sxSeX3aj6yPKj7PAvs8izpVXjyEBl5aR8mQneVcXuF53AH7EW1
# 6E5p4+Az5pJPGUD5c3tXhiGMF7vgLhQjO6hlaVBRIqiIYHikNLwMNy6YBMc/QQYM
# rPhqHEFsZ53dkBIIj3M8e3kFcTFA09n25yDtTPDab4nd9yUhc9Qc8+nfpIzfYsoP
# 1pZ3nCzhw6hN2/44v1dkQrG3dRYwt+px65p6NPNZWEJpt4VCJjIFh+lBYJdxm9d4
# X/rAnlHIkbv7liOavWDzgHVabS3hdAWtcDmynm+7+FcZDFqPWNCl3e4SS7xe4s/R
# CKFKA0IsfKkSk9YJlLgeSQIEXUOOWXJAGaLqnRD8xWLZsc4Oi9GZg7XV1mv/S88c
# oztXnwtAN3OOlRKBh2QbomMgxeMO0GvsLE/cq5Q/YKAoz+KGr/7LcZq9jzQ8IPus
# ZvWLeDXmxPiwJjpZc1koLgfGIEX2NStQTT3QmacWr9thrWcKvI+4uBmI4exS9B4a
# R3nV91w5EY+2RoYsHqej9LWwNamO96+jMX9pxprTX+EkLUuMAikw/po8sBC9MUUn
# 5pMWmUv7DCtQOLGGBDDMMMkn4ZcjpCEEdPGHRKfqNnD27ssGtDjiNzfQrsm67toU
# bBwUF+gyJq/YckWquYJhA9ZOFWEADuIwGnsOzsoRvuQyY+p9AgMBAAGjQzBBMA4G
# A1UdDwEB/wQEAwIHgDAWBgNVHSUBAf8EDDAKBggrBgEFBQcDAzAXBgNVHREEEDAO
# ggxzdGF0ZWxlc3MuYmUwDQYJKoZIhvcNAQELBQADggIBACithYM3qckZRc9+Xbfu
# a6gWr3HwjrW+FHKgjfrcOm8ZnLVapb9xFqsqrRQqd3RXWQDINEGrtI2rSfrzyfoK
# UiTgldIfQNP1ZcGY229d++90t3hdo2mlt05hjYlbMENloJHpsEP0vQZmwOcEimCT
# ex1pymYM+P9pj3j8UD1PT1eIZot6or8fBRl63UybyDSrM7L4UOkkAOniKxWy5pW6
# 6duS8SR+SZpr3Bv44NyXPj0Nv+MIpLmsLrd7XPBFmnGxzY01ZO9vzi9KEhM2wT5i
# jPqHDNOvfPiADtAa+EyUBzdJiqy9heCz/TMZQgMWGwtfqJNxWZmsHcha2anW4Qt+
# mzrLO4GojWoVog9uVSAq+l0a+YQsd1u1kUmm4vgZCFyUA+lEp4LkI7ca2VBHkLPD
# w+u2DoDMRiqFPZjO7BCKjGc0jj9B/qGR3JVt+tqDdB621xXf2YGF2oFvxZQ/keGt
# 0ujfJ+JwN3nCulDAA4773q6KUnfykyrvAgITNbRJL6TngeRKtw9VIJBPxzqMzLpV
# 5ggXNituwLaD1CCBJ1oo9DZHpL9gplXp1wGrelJOTiJhh+pdNsPtRH7CrranWa5h
# LFLuigqin0eewQ5giJ1VaiBVEseOmiZog+27UpFIv40aDzgGL3YxB/Mu0ojwrQtp
# WLmqJCmWnR5qxOm0yK+zNWe0MYIC7zCCAusCAQEwTjBBMT8wPQYDVQQDHjYAaQBj
# AHIAYQBmAHQAcwBvAGYAdAB3AGEAcgBlAEAAcwB0AGEAdABlAGwAZQBzAHMALgBi
# AGUCCQCZK95iXUwZFDAJBgUrDgMCGgUAoHgwGAYKKwYBBAGCNwIBDDEKMAigAoAA
# oQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4w
# DAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU6sjLZlwzGT6NiGpVN6N8KWnG
# tmkwDQYJKoZIhvcNAQEBBQAEggIAzg/+h60XnMuwDBCLAp0W4D3FJZt/O5O/pCLY
# 0fGzNL9DzM8qcwHvRv1+FbVCz2QHg0jbH6lE0DzI5jDjmKo+clK2Zx5ok3xn1x04
# fQSZkDObym4GSrGaKGsYVjl+oCN4FROIiKe8CfMfudKPDe2/BgJdC+Dmqcy94rS4
# GLbV+pBe+btql6dCn4YsKUbETuAx3djbY0w4ONDyEGTJ4j7Mm2G2Bsu1riMsPQG5
# NlGrJa5gYT0JGl4btqGJ/mblXQu12jeWK193EKu9jUhwvxw+UZXzvcTrB8wqIbRI
# z0MhsiX83RTEWljinnBLmVnEHv7RQcZLssiT0xDJrqG8MwvbZqsfmEp2nZMbvq4N
# P54GSA0o6I9TQzwdtS9SN+CNo6xbvnfHKYpxN5+3tLVFCoxgumQm8rW9dWeUaSgE
# 6a0WSiaNO88gJDDC19x/EltBbt5Ms9n0ZVuS0ImDNvkJQ1S56WZV5rrwJ+HBR2fb
# V/C+buJKhul2WI5jGh7U+fJAM6P5lmn4by+bakJWkwZZ5z9vxmA883so3Mqh+u4t
# j1DAE1Uy/5Q9I5hYbTwLSVuP0nMsMZoLmCRDBr3YCkUOpozsFz9RVSJPA0fymz6y
# 3yQaGvhKD2O9Tg8+WbRiJhN97CfR+mIp9FTmXxwxRE5q/fxzTCvEoGmojB1VB1Jq
# iqxO7PE=
# SIG # End signature block