Adapter/Adapter.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.u # See the License for the specific language governing permissions and # limitations under the License. #endregion Set-StrictMode -Version Latest <# .SYNOPSIS Asserts the existence of a Microsoft BizTalk Server Adapter. .DESCRIPTION This command will throw if the Microsoft BizTalk Server Adapter does not exist and will silently complete otherwise. If the existence has to be asserted for the combined sources, this command will silently complete only if the Microsoft BizTalk Server adapter exists in both sources. .PARAMETER Name The name of the Microsoft BizTalk Server Adapter. .PARAMETER Source The place where to look for the Microsoft BizTalk Server Adapter: either among those configured and available in Microsoft BizTalk Server, or among those registered in the local machine's COM registry, or as a combination of both sources. It defaults to BizTalk. .EXAMPLE PS> Assert-BizTalkAdapter -Name FILE .EXAMPLE PS> Assert-BizTalkAdapter -Name FILE -Source Registry .EXAMPLE PS> Assert-BizTalkAdapter -Name FILE -Source Combined .EXAMPLE PS> Assert-BizTalkAdapter -Name FILE -Source Combined -Verbose .NOTES © 2020 be.stateless. #> function Assert-BizTalkAdapter { [CmdletBinding()] [OutputType([void])] param( [Parameter(Position = 0, Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $Name, [Parameter(Position = 1, Mandatory = $false)] [ValidateSet('BizTalk', 'Registry', 'Combined')] [string] $Source = 'BizTalk' ) Resolve-ActionPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState if (-not(Test-BizTalkAdapter @PSBoundParameters)) { throw "Microsoft BizTalk Server Adapter '$Name' does not exist in $Source source(s)." } Write-Verbose "Microsoft BizTalk Server Adapter '$Name' exists in $Source source(s)." } <# .SYNOPSIS Gets information about the Microsoft BizTalk Server Adapters. .DESCRIPTION Gets information about the Microsoft BizTalk Server Adapters available in Microsoft BizTalk Server or the local machine's COM registry. .PARAMETER Name The name of the Microsoft BizTalk Server Adapter. .PARAMETER Source The place where to look for the Microsoft BizTalk Server Adapters: either among those configured and available in Microsoft BizTalk Server, or among those registered in the local machine's COM registry, or as a combination of both sources. It defaults to BizTalk. .OUTPUTS Returns information about the Microsoft BizTalk Server Adapters. .EXAMPLE PS> Get-BizTalkAdapter .EXAMPLE PS> Get-BizTalkAdapter -Name FILE .EXAMPLE PS> Get-BizTalkAdapter -Source Registry .EXAMPLE PS> Get-BizTalkAdapter -Name FILE -Source Biztalk .EXAMPLE PS> Get-BizTalkAdapter -Name FILE -Source Combined .LINK https://docs.microsoft.com/en-us/biztalk/core/registering-an-adapter .NOTES © 2020 be.stateless. #> function Get-BizTalkAdapter { [CmdletBinding()] [OutputType([PSCustomObject[]])] param( [Parameter(Position = 0, Mandatory = $false)] [AllowEmptyString()] [AllowNull()] [string] $Name, [Parameter(Position = 1, Mandatory = $false)] [ValidateSet('BizTalk', 'Registry', 'Combined')] [string] $Source = 'BizTalk' ) function ConvertTo-BizTalkAdapterObject { [CmdletBinding()] [OutputType([PSCustomObject])] param( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [Microsoft.Win32.RegistryKey] $Key ) $adapter = [PSCustomObject]@{ Source = @('Registry') ; MgmtCLSID = ($Key.Name | Split-Path | Split-Path -Leaf) } $Key.GetValueNames() | Where-Object -FilterScript { -not [string]::IsNullOrWhiteSpace($_) } | ForEach-Object -Process { Add-Member -InputObject $adapter -NotePropertyName $_ -NotePropertyValue $Key.GetValue($_) } $adapter } function Merge-BizTalkAdapterObjects { [CmdletBinding()] [OutputType([PSCustomObject])] param( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [PSCustomObject] $BizTalkAdapter, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [PSCustomObject] $RegistryAdapter ) $adapter = [PSCustomObject]@{ Source = @('BizTalk', 'Registry') MgmtCLSID = $BizTalkAdapter.MgmtCLSID Constraints = @(($BizTalkAdapter.Constraints, $RegistryAdapter.Constraints) | Select-Object -Unique) } $BizTalkAdapter | Get-Member -MemberType Properties | Where-Object -FilterScript { $_.Name -notin @('Source', 'MgmtCLSID', 'Constraints') } | ForEach-Object -Process { Add-Member -InputObject $adapter -NotePropertyName $_.Name -NotePropertyValue $BizTalkAdapter.($_.Name) } $RegistryAdapter | Get-Member -MemberType Properties | Where-Object -FilterScript { $_.Name -notin @('Source', 'MgmtCLSID', 'Constraints') } | ForEach-Object -Process { Add-Member -InputObject $adapter -NotePropertyName $_.Name -NotePropertyValue $RegistryAdapter.($_.Name) } $adapter } Resolve-ActionPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState if ($Source -eq 'BizTalk') { $filter = if (![string]::IsNullOrWhiteSpace($Name)) { "Name='$Name'" } Get-CimInstance -ErrorAction Stop -Namespace root/MicrosoftBizTalkServer -ClassName MSBTS_AdapterSetting -Filter $filter | Add-Member -NotePropertyName Source -NotePropertyValue @($Source) -PassThru } elseif ($Source -eq 'Registry') { if ([string]::IsNullOrWhiteSpace($Name)) { Get-BizTalkAdapterRegistryKey | ForEach-Object -Process { ConvertTo-BizTalkAdapterObject -Key $_ } } else { # speed up registry lookup by 1st looking up the MgmtCLSID in BizTalk $mgmtCLSID = Get-BizTalkAdapter -Name $Name -Source BizTalk | Select-Object -ExpandProperty MgmtCLSID if ($null -ne $mgmtCLSID) { Get-BizTalkAdapterRegistryKey -MgmtCLSID $mgmtCLSID | Where-Object -FilterScript { $null -ne $_ } | ForEach-Object -Process { ConvertTo-BizTalkAdapterObject -Key $_ } } else { Get-BizTalkAdapterRegistryKey | Where-Object -FilterScript { $_.GetValue('TransportType') -eq $Name } | ForEach-Object -Process { ConvertTo-BizTalkAdapterObject -Key $_ } } } } else { $btsAdapters = @(Get-BizTalkAdapter -Name $Name -Source BizTalk) $btsMgmtClsIds = $btsAdapters | ForEach-Object MgmtCLSID $comAdapters = @(Get-BizTalkAdapter -Name $Name -Source Registry) $comMgmtClsIds = $comAdapters | ForEach-Object MgmtCLSID $commonMgmtClsIds = $btsMgmtClsIds | Where-Object -FilterScript { $comMgmtClsIds -contains $_ } $commonMgmtClsIds | ForEach-Object -Process { Merge-BizTalkAdapterObjects -BizTalkAdapter ($btsAdapters | Where-Object MgmtCLSID -eq $_) -RegistryAdapter ($comAdapters | Where-Object MgmtCLSID -eq $_) } $btsOnlyMgmtClsIds = $btsMgmtClsIds | Where-Object -FilterScript { $comMgmtClsIds -notcontains $_ } $btsAdapters | Where-Object -FilterScript { $_.MgmtCLSID -in $btsOnlyMgmtClsIds } $comOnlyMgmtClsIds = $comMgmtClsIds | Where-Object -FilterScript { $btsMgmtClsIds -notcontains $_ } $comAdapters | Where-Object -FilterScript { $_.MgmtCLSID -in $comOnlyMgmtClsIds } } } <# .SYNOPSIS Creates a Microsoft BizTalk Server Adapter. .DESCRIPTION Creates a Microsoft BizTalk Server Adapter. The adapter to be created should be locally installed in order for its creation to succeed. .PARAMETER Name The name of the Microsoft BizTalk Server Adapter to create. .PARAMETER MgmtCLSID The MgmtCLSID of the Microsoft BizTalk Server Adapter to create. If the MgmtCLSID argument is omitted, it will be looked up in the local machine's COM registry. .PARAMETER Comment A descriptive comment of the Microsoft BizTalk Server Adapter to create. .EXAMPLE PS> New-BizTalkAdapter -Name 'WCF-SQL' .EXAMPLE PS> New-BizTalkAdapter -Name 'WCF-SQL' -MgmtCLSID '{59B35D03-6A06-4734-A249-EF561254ECF7}' .EXAMPLE PS> New-BizTalkAdapter -Name 'WCF-SQL' -Comment 'Windows Communication Foundation (WCF) in-process adapter for SQL Server.' .NOTES © 2020 be.stateless. #> function New-BizTalkAdapter { [CmdletBinding(SupportsShouldProcess = $true)] [OutputType([void])] param( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $Name, [Parameter(Mandatory = $false)] [AllowEmptyString()] [AllowNull()] [string] $MgmtCLSID, [Parameter(Mandatory = $false)] [AllowEmptyString()] [AllowNull()] [string] $Comment ) Resolve-ActionPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState if (Test-BizTalkAdapter -Name $Name -Source BizTalk) { Write-Information "`t Microsoft BizTalk Server '$Name' adapter has already been created." } elseif ($PsCmdlet.ShouldProcess("Microsoft BizTalk Server Group", "Creating '$Name' adapter")) { Write-Information "`t Creating Microsoft BizTalk Server '$Name' adapter..." if ([string]::IsNullOrWhiteSpace($MgmtCLSID)) { $MgmtCLSID = Get-BizTalkAdapter -Name $Name -Source Registry | Select-Object -ExpandProperty MgmtCLSID } if ([string]::IsNullOrWhiteSpace($MgmtCLSID)) { throw "'$Name' adapter's MgmtCLSID could not be resolved on the local machine. The '$Name' adapter might not be installed on $($env:COMPUTERNAME)." } if ($null -eq (Get-BizTalkAdapterRegistryKey -MgmtCLSID $mgmtCLSID)) { throw "'$Name' adapter's MgmtCLSID $mgmtCLSID does not exist on the local machine. The '$Name' adapter might not be installed on $($env:COMPUTERNAME)." } $properties = @{ Name = $Name MgmtCLSID = $MgmtCLSID } if (-not [string]::IsNullOrWhiteSpace($Comment)) { $properties.Comment = $Comment } $properties New-CimInstance -ErrorAction Stop -Namespace root/MicrosoftBizTalkServer -ClassName MSBTS_AdapterSetting -Property $properties | Out-Null Write-Information "`t Microsoft BizTalk Server '$Name' adapter has been created." } } <# .SYNOPSIS Removes a Microsoft BizTalk Server Adapter. .DESCRIPTION Removes a Microsoft BizTalk Server Adapter. .PARAMETER Name The name of the Microsoft BizTalk Server Adapter to remove. .EXAMPLE PS> Remove-BizTalkAdapter -Name 'WCF-SQL' .NOTES © 2020 be.stateless. #> function Remove-BizTalkAdapter { [CmdletBinding(SupportsShouldProcess = $true)] [OutputType([void])] param( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $Name ) Resolve-ActionPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState if (-not(Test-BizTalkAdapter -Name $Name -Source BizTalk)) { Write-Information "`t Microsoft BizTalk Server '$Name' adapter has already been removed." } elseif ($PsCmdlet.ShouldProcess("Microsoft BizTalk Server Group", "Removing '$Name' adapter")) { Write-Information "`t Removing Microsoft BizTalk Server '$Name' adapter..." $filter = if (![string]::IsNullOrWhiteSpace($Name)) { "Name='$Name'" } $instance = Get-CimInstance -ErrorAction Stop -Namespace root/MicrosoftBizTalkServer -ClassName MSBTS_AdapterSetting -Filter $filter Remove-CimInstance -ErrorAction Stop -InputObject $instance Write-Information "`t Microsoft BizTalk Server '$Name' adapter has been removed." } } <# .SYNOPSIS Returns whether a Microsoft BizTalk Server Adapter exists. .DESCRIPTION This command will return $true if the Microsoft BizTalk Server Adapter exists; $false otherwise. If the existence has to be tested for the combined sources, this command will return $true only if the Microsoft BizTalk Server adapter exists in both sources. .PARAMETER Name The name of the Microsoft BizTalk Server Adapter whose availability or installation has to be tested. .PARAMETER Source The place where to look for the Microsoft BizTalk Server Adapter: either among those configured and available in Microsoft BizTalk Server, or among those registered in the local machine's COM registry, or as a combination of both sources. It defaults to BizTalk. .OUTPUTS $true if the Microsoft BizTalk Server Adapter exists; $false otherwise. .EXAMPLE PS> Test-BizTalkAdapter -Name FILE .EXAMPLE PS> Test-BizTalkAdapter -Name FILE -Source Registry .EXAMPLE PS> Test-BizTalkAdapter -Name FILE -Source Combined .NOTES © 2020 be.stateless. #> function Test-BizTalkAdapter { [CmdletBinding()] [OutputType([bool])] param( [Parameter(Position = 0, Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $Name, [Parameter(Position = 1, Mandatory = $false)] [ValidateSet('BizTalk', 'Registry', 'Combined')] [string] $Source = 'BizTalk' ) Resolve-ActionPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState if ($Source -eq 'Combined') { (Test-BizTalkAdapter -Name $Name -Source BizTalk) -and (Test-BizTalkAdapter -Name $Name -Source Registry) } else { [bool](Get-BizTalkAdapter -Name $Name -Source $Source) } } function Get-BizTalkAdapterRegistryKey { [CmdletBinding()] [OutputType([Microsoft.Win32.RegistryKey[]])] param( [Parameter(Position = 0, Mandatory = $false)] [AllowEmptyString()] [AllowNull()] [string] $MgmtCLSID ) Use-Object ($hklm = [Microsoft.Win32.RegistryKey]::OpenBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine, [Microsoft.Win32.RegistryView]::Registry32)) { Use-Object ($clsidKey = $hklm.OpenSubKey('SOFTWARE\Classes\CLSID')) { $(if ([string]::IsNullOrWhiteSpace($MgmtCLSID)) { $clsidKey.GetSubKeyNames() } else { @($MgmtCLSID) }) | ForEach-Object -Process { Use-Object ($clsid = $clsidKey.OpenSubKey($_)) { if ($null -ne $clsid) { Use-Object ($adapterCategoryKey = $clsid.OpenSubKey('Implemented Categories\{7F46FC3E-3C2C-405B-A47F-8D17942BA8F9}')) { if ($null -ne $adapterCategoryKey) { Use-Object ($adapterKey = $clsid.OpenSubKey('BizTalk')) { $adapterKey } } } } } } } } } # SIG # Begin signature block # MIITugYJKoZIhvcNAQcCoIITqzCCE6cCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUWW02nqrvSvBC7Z1Hy4mRWpwb # 5U2ggg46MIID7jCCA1egAwIBAgIQfpPr+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 # BAGCNwIBCzEOMAwGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkEMRYEFLRw099nO+C7 # YyiVByklV4yOgydDMA0GCSqGSIb3DQEBAQUABIICAI6N/R0QdyY2USv7gHeIdFlC # 3ew5g7LtIFMcdQuTI+OoRulW7Z3v15tiUjnbXDJUodCQyW+GCpPkUro5moor/Rt6 # KkSkFx7nBpUn/ce3JH56T7FZa7tNIWf6rHV4EjBX8q5gkWdOFvG535//HCa8xzxY # 653LPMAY1X5x9zPWLnkLdkQH5hq/Od5loGCf3XRliPU2eLl8AzdCwKdzYZbyt8KO # 5BF5r0DlyPxpWXtrqdhNPR925UVOpkdyydLBJTAfSbnqEa99WSmqTYXrgBq1hRIh # W4afhoBs450kk7oHaM7lI2MgwogJnSEK3u6cy9Zn/HsiZnQiMO/KX7ZPt4MtECzl # 4gdgIzO4s5YahtiLh5Qkl3PBL59/YQIG4MAWBozfNGxDy4tctIK+dF32Z37KKd+0 # 9JU6WFFEwTDjQWjiPA7CVwoz1ZBozUkexcAJYmScEZIAQxeqfcuBjKsHyeEH6rNH # UOcuhzjGxom6zkm3b/L8qldqWiD7ooQ/Z3xQqvBzRxRPNTZCFaTjVjwj9VYkHELh # TUo3AkRyr8CwoUzhARJ7XwkH8I8k7MpNK+8JJiKNVm4Fk5XNNR6srEC+P1x4LRQv # fF/5nU+DkEQz03cKdQiYHnEt1XVvwmloMUzPiAeuj3TFG5lHW7JcTk0GGnck+27y # DXyGeD/jEamc1UUCD8zeoYICCzCCAgcGCSqGSIb3DQEJBjGCAfgwggH0AgEBMHIw # XjELMAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMTAw # LgYDVQQDEydTeW1hbnRlYyBUaW1lIFN0YW1waW5nIFNlcnZpY2VzIENBIC0gRzIC # EA7P9DjI/r81bgTYapgbGlAwCQYFKw4DAhoFAKBdMBgGCSqGSIb3DQEJAzELBgkq # hkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTIwMDkzMDE0MTMyM1owIwYJKoZIhvcN # AQkEMRYEFLazdNAYytw5Goc7bgpE4O+3UOq2MA0GCSqGSIb3DQEBAQUABIIBACM3 # 3o7ED81wonezwtbiaeL8Vv/4ff94TFurMQfZEIyrMOID+une+iR01ML8tk5cKSWh # V9Bmp5TfmBIt46txxqoUzYfu9MTy7jmJOOgYIwqCTasAPuwaPA4NRR3f66uvGDkO # pG4r+jOxuUa+k7aX73kqBy4rnth/yPzkjUG4xdoGydf5qanwsVywO5A3QfD/MgSq # zFa4u+GS+8ObXkEKIciQnffKxDrXglxxsnKUJgEDhXvgaI7ZX5WSdo3BucNN8jVX # Ih/tRzTcUu8GJ++T5uodjDSvVpAcNOdmRqwF0cUD2wQFK0QXK3NwYK3p8TYRuC8j # k3cgsXAMV7WSMkhMl6c= # SIG # End signature block |