DSCResources/VE_XD7AccessPolicy/VE_XD7AccessPolicy.psm1
Import-LocalizedData -BindingVariable localizedData -FileName VE_XD7AccessPolicy.Resources.psd1; function Get-TargetResource { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param ( # Delivery Group Name [Parameter(Mandatory)] [System.String] $DeliveryGroup, # NotViaAG | ViaAG [Parameter(Mandatory)] [ValidateSet('AccessGateway','Direct')] [System.String] $AccessType, [Parameter()] [System.Boolean] $Enabled = $true, [Parameter()] [System.Boolean] $AllowRestart = $true, [Parameter()] [ValidateSet('HDX','RDP')] [System.String[]] $Protocol = @('HDX','RDP'), # Name example: <DeliveryGroupName>_Direct or <DeliveryGroupName>_AG [Parameter()] [System.String] $Name, [Parameter()] [AllowNull()] [System.String] $Description = $null, # IncludedUsersFilterEnabled/IncludedUsers [Parameter()] [ValidateNotNull()] [System.String[]] $IncludeUsers = @(), # ExcludedUserFilterEnabled/ExcludedUsers [Parameter()] [ValidateNotNull()] [System.String[]] $ExcludeUsers = @(), [Parameter()] [ValidateSet('Present','Absent')] [System.String] $Ensure = 'Present', [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.CredentialAttribute()] $Credential ) begin { AssertXDModule -Name 'Citrix.Broker.Admin.V2' -IsSnapin; if ([System.String]::IsNullOrEmpty($Name)) { $Name = '{0}_Direct' -f $DeliveryGroup; if ($AccessType -eq 'AccessGateway') { $Name = '{0}_AG' -f $DeliveryGroup; } } } process { $scriptBlock = { Add-PSSnapin -Name 'Citrix.Broker.Admin.V2' -ErrorAction Stop; $desktopGroup = Get-BrokerDesktopGroup -Name $using:DeliveryGroup -ErrorAction Stop; $desktopGroupAccessPolicy = Get-BrokerAccessPolicyRule -Name $using:Name -DesktopGroupUid $desktopGroup.Uid -ErrorAction SilentlyContinue; $targetResource = @{ DeliveryGroup = $using:DeliveryGroup; Name = $desktopGroupAccessPolicy.Name; AccessType = if ($desktopGroupAccessPolicy.AllowedConnections -eq 'ViaAG') { 'AccessGateway' } else { 'Direct' } Enabled = $desktopGroupAccessPolicy.Enabled; AllowRestart = $desktopGroupAccessPolicy.AllowRestart; Protocol = [System.String[]] $desktopGroupAccessPolicy.AllowedProtocols; Description = [System.String] $desktopGroupAccessPolicy.Description; IncludeUsers = @() ExcludeUsers = @(); Ensure = 'Absent'; } $targetResource['IncludeUsers'] += $desktopGroupAccessPolicy.IncludedUsers | Where-Object Name -ne $null | Select-Object -ExpandProperty Name; $targetResource['ExcludeUsers'] += $desktopGroupAccessPolicy.ExcludedUsers | Where-Object Name -ne $null | Select-Object -ExpandProperty Name; if ($desktopGroupAccessPolicy) { $targetResource.Ensure = 'Present'; } return $targetResource; } #end scriptBlock $invokeCommandParams = @{ ScriptBlock = $scriptBlock; ErrorAction = 'Stop'; } Write-Verbose ($localizedData.InvokingScriptBlockWithParams -f [System.String]::Join("','", @($Name, $Enabled, $Ensure))); if ($Credential) { AddInvokeScriptBlockCredentials -Hashtable $invokeCommandParams -Credential $Credential; $targetResource = Invoke-Command @invokeCommandParams; } else { $invokeScriptBlock = [System.Management.Automation.ScriptBlock]::Create($scriptBlock.ToString().Replace('$using:','$')); $targetResource = InvokeScriptBlock -ScriptBlock $invokeScriptBlock; } return $targetResource; } } #end function Get-TargetResource function Test-TargetResource { [CmdletBinding()] [OutputType([System.Boolean])] param ( # Delivery Group Name [Parameter(Mandatory)] [System.String] $DeliveryGroup, # NotViaAG | ViaAG [Parameter(Mandatory)] [ValidateSet('AccessGateway','Direct')] [System.String] $AccessType, [Parameter()] [System.Boolean] $Enabled = $true, [Parameter()] [System.Boolean] $AllowRestart = $true, [Parameter()] [ValidateSet('HDX','RDP')] [System.String[]] $Protocol = @('HDX','RDP'), # Name example: <DeliveryGroupName>_Direct or <DeliveryGroupName>_AG [Parameter()] [System.String] $Name, [Parameter()] [AllowNull()] [System.String] $Description = $null, # IncludedUsersFilterEnabled/IncludedUsers [Parameter()] [ValidateNotNull()] [System.String[]] $IncludeUsers = @(), # ExcludedUserFilterEnabled/ExcludedUsers [Parameter()] [ValidateNotNull()] [System.String[]] $ExcludeUsers = @(), [Parameter()] [ValidateSet('Present','Absent')] [System.String] $Ensure = 'Present', [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.CredentialAttribute()] $Credential ) begin { if ([System.String]::IsNullOrEmpty($Name)) { $Name = '{0}_Direct' -f $DeliveryGroup; if ($AccessType -eq 'AccessGateway') { $Name = '{0}_AG' -f $DeliveryGroup; } } } #end begin process { $PSBoundParameters['Ensure'] = $Ensure; $targetResource = Get-TargetResource @PSBoundParameters; $inCompliance = $true; foreach ($property in $PSBoundParameters.Keys) { if ($targetResource.ContainsKey($property)) { $expected = $PSBoundParameters[$property]; $actual = $targetResource[$property]; if ($PSBoundParameters[$property] -is [System.String[]]) { if (($null -ne $expected) -and ($null -eq $actual)) { ## No existing Access policy configured (#53) Write-Verbose ($localizedData.ResourcePropertyMismatch -f $property, ($expected -join ','), ''); $inCompliance = $false; } elseif (Compare-Object -ReferenceObject $expected -DifferenceObject $actual) { Write-Verbose ($localizedData.ResourcePropertyMismatch -f $property, ($expected -join ','), ($actual -join ',')); $inCompliance = $false; } } elseif ($expected -ne $actual) { Write-Verbose ($localizedData.ResourcePropertyMismatch -f $property, $expected, $actual); $inCompliance = $false; } } } if ($inCompliance) { Write-Verbose ($localizedData.ResourceInDesiredState -f $DeliveryGroup); } else { Write-Verbose ($localizedData.ResourceNotInDesiredState -f $DeliveryGroup); } return $inCompliance; } #end process } #end function Test-TargetResource function Set-TargetResource { [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')] param ( # Delivery Group Name [Parameter(Mandatory)] [System.String] $DeliveryGroup, # NotViaAG | ViaAG [Parameter(Mandatory)] [ValidateSet('AccessGateway','Direct')] [System.String] $AccessType, [Parameter()] [System.Boolean] $Enabled = $true, [Parameter()] [System.Boolean] $AllowRestart = $true, [Parameter()] [ValidateSet('HDX','RDP')] [System.String[]] $Protocol = @('HDX','RDP'), # Name example: <DeliveryGroupName>_Direct or <DeliveryGroupName>_AG [Parameter()] [System.String] $Name, [Parameter()] [AllowNull()] [System.String] $Description = $null, # IncludedUsersFilterEnabled/IncludedUsers [Parameter()] [ValidateNotNull()] [System.String[]] $IncludeUsers = @(), # ExcludedUserFilterEnabled/ExcludedUsers [Parameter()] [ValidateNotNull()] [System.String[]] $ExcludeUsers = @(), [Parameter()] [ValidateSet('Present','Absent')] [System.String] $Ensure = 'Present', [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.CredentialAttribute()] $Credential ) begin { AssertXDModule -Name 'Citrix.Broker.Admin.V2' -IsSnapin; if ([System.String]::IsNullOrEmpty($Name)) { $Name = '{0}_Direct' -f $DeliveryGroup; if ($AccessType -eq 'AccessGateway') { $Name = '{0}_AG' -f $DeliveryGroup; } } } #end begin process { $scriptBlock = { Add-PSSnapin -Name 'Citrix.Broker.Admin.V2' -ErrorAction Stop; $desktopGroup = Get-BrokerDesktopGroup -Name $using:DeliveryGroup -ErrorAction Stop; $desktopGroupAccessPolicy = Get-BrokerAccessPolicyRule -Name $using:Name -DesktopGroupUid $desktopGroup.Uid -ErrorAction SilentlyContinue; if ($using:Ensure -eq 'Present') { $accessPolicyParams = @{ Enabled = $using:Enabled; Description = $using:Description; AllowRestart = $using:AllowRestart; AllowedConnections = if ($using:AccessType -eq 'AccessGateway') { 'ViaAG' } else { 'NotViaAG' } AllowedProtocols = $using:Protocol; IncludedUserFilterEnabled = $false; IncludedUsers = @(); ExcludedUserFilterEnabled = $false; ExcludedUsers = @(); } if ($using:IncludeUsers.Count -ge 1) { $accessPolicyParams['IncludedUserFilterEnabled'] = $true; foreach ($user in $using:IncludeUsers) { $brokerUser = Get-BrokerUser -FullName $user -ErrorAction SilentlyContinue; if (-not $brokerUser) { $brokerUser = New-BrokerUser -Name $user -ErrorAction Stop; } $accessPolicyParams['IncludedUsers'] += $brokerUser; } } if ($using:ExcludeUsers.Count -ge 1) { $accessPolicyParams['ExcludedUserFilterEnabled'] = $true; foreach ($user in $using:ExcludeUsers) { $brokerUser = Get-BrokerUser -FullName $user -ErrorAction SilentlyContinue; if (-not $brokerUser) { $brokerUser = New-BrokerUser -Name $user -ErrorAction Stop; } $accessPolicyParams['ExcludedUsers'] += $brokerUser; } } if ($desktopGroupAccessPolicy) { ## Can't change name or delivery group if ($desktopGroup.Uid -ne $desktopGroupAccessPolicy.DesktopGroupUid) { throw ($using:localizedData.ImmutablePropertyError -f 'Uid'); } elseif ($using:Name -ne $desktopGroupAccessPolicy.Name) { throw ($using:localizedData.ImmutablePropertyError -f 'Name'); } Write-Verbose ($using:localizedData.UpdatingAccessPolicy -f $using:Name); $null = $desktopGroupAccessPolicy | Set-BrokerAccessPolicyRule @accessPolicyParams; } else { $accessPolicyParams['Name'] = $using:Name; $accessPolicyParams['DesktopGroupUid'] = $desktopGroup.Uid; Write-Verbose ($using:localizedData.AddingAccessPolicy -f $using:Name); New-BrokerAccessPolicyRule @accessPolicyParams; } } else { if ($desktopGroupAccessPolicy) { Write-Verbose ($using:localizedData.RemovingAccessPolicy -f $using:Name); $desktopGroupAccessPolicy | Remove-BrokerAccessPolicyRule; } } } #end scriptBlock $invokeCommandParams = @{ ScriptBlock = $scriptBlock; ErrorAction = 'Stop'; } Write-Verbose ($localizedData.InvokingScriptBlockWithParams -f [System.String]::Join("','", @($Name, $Enabled, $Ensure))); if ($Credential) { AddInvokeScriptBlockCredentials -Hashtable $invokeCommandParams -Credential $Credential; [ref] $null = Invoke-Command @invokeCommandParams; } else { $invokeScriptBlock = [System.Management.Automation.ScriptBlock]::Create($scriptBlock.ToString().Replace('$using:','$')); [ref] $null = InvokeScriptBlock -ScriptBlock $invokeScriptBlock; } } #end process } #end function Set-TargetResource $moduleRoot = Split-Path -Path $MyInvocation.MyCommand.Path -Parent; ## Import the XD7Common library functions $moduleParent = Split-Path -Path $moduleRoot -Parent; Import-Module (Join-Path -Path $moduleParent -ChildPath 'VE_XD7Common'); ## Import the InvokeScriptBlock function into the current scope . (Join-Path -Path (Join-Path -Path $moduleParent -ChildPath 'VE_XD7Common') -ChildPath 'InvokeScriptBlock.ps1'); Export-ModuleMember -Function *-TargetResource; # SIG # Begin signature block # MIIm9AYJKoZIhvcNAQcCoIIm5TCCJuECAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUyC+JYv/XJ+DumKG2dRGCtG/u # 4/aggiCcMIIFjTCCBHWgAwIBAgIQDpsYjvnQLefv21DiCEAYWjANBgkqhkiG9w0B # AQwFADBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD # VQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVk # IElEIFJvb3QgQ0EwHhcNMjIwODAxMDAwMDAwWhcNMzExMTA5MjM1OTU5WjBiMQsw # CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu # ZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQw # ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz # 7MKnJS7JIT3yithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS # 5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7 # bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfI # SKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jH # trHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14 # Ztk6MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2 # h4mXaXpI8OCiEhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt # 6zPZxd9LBADMfRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPR # iQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ER # ElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4K # Jpn15GkvmB0t9dmpsh3lGwIDAQABo4IBOjCCATYwDwYDVR0TAQH/BAUwAwEB/zAd # BgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wHwYDVR0jBBgwFoAUReuir/SS # y4IxLVGLp6chnfNtyA8wDgYDVR0PAQH/BAQDAgGGMHkGCCsGAQUFBwEBBG0wazAk # BggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEMGCCsGAQUFBzAC # hjdodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURS # b290Q0EuY3J0MEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0 # LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwEQYDVR0gBAowCDAGBgRV # HSAAMA0GCSqGSIb3DQEBDAUAA4IBAQBwoL9DXFXnOF+go3QbPbYW1/e/Vwe9mqyh # hyzshV6pGrsi+IcaaVQi7aSId229GhT0E0p6Ly23OO/0/4C5+KH38nLeJLxSA8hO # 0Cre+i1Wz/n096wwepqLsl7Uz9FDRJtDIeuWcqFItJnLnU+nBgMTdydE1Od/6Fmo # 8L8vC6bp8jQ87PcDx4eo0kxAGTVGamlUsLihVo7spNU96LHc/RzY9HdaXFSMb++h # UD38dglohJ9vytsgjTVgHAIDyyCwrFigDkBjxZgiwbJZ9VVrzyerbHbObyMt9H5x # aiNrIv8SuFQtJ37YOtnwtoeW/VvRXKwYw02fc7cBqZ9Xql4o4rmUMIIGrjCCBJag # AwIBAgIQBzY3tyRUfNhHrP0oZipeWzANBgkqhkiG9w0BAQsFADBiMQswCQYDVQQG # EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl # cnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMjIw # MzIzMDAwMDAwWhcNMzcwMzIyMjM1OTU5WjBjMQswCQYDVQQGEwJVUzEXMBUGA1UE # ChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQg # UlNBNDA5NiBTSEEyNTYgVGltZVN0YW1waW5nIENBMIICIjANBgkqhkiG9w0BAQEF # AAOCAg8AMIICCgKCAgEAxoY1BkmzwT1ySVFVxyUDxPKRN6mXUaHW0oPRnkyibaCw # zIP5WvYRoUQVQl+kiPNo+n3znIkLf50fng8zH1ATCyZzlm34V6gCff1DtITaEfFz # sbPuK4CEiiIY3+vaPcQXf6sZKz5C3GeO6lE98NZW1OcoLevTsbV15x8GZY2UKdPZ # 7Gnf2ZCHRgB720RBidx8ald68Dd5n12sy+iEZLRS8nZH92GDGd1ftFQLIWhuNyG7 # QKxfst5Kfc71ORJn7w6lY2zkpsUdzTYNXNXmG6jBZHRAp8ByxbpOH7G1WE15/teP # c5OsLDnipUjW8LAxE6lXKZYnLvWHpo9OdhVVJnCYJn+gGkcgQ+NDY4B7dW4nJZCY # OjgRs/b2nuY7W+yB3iIU2YIqx5K/oN7jPqJz+ucfWmyU8lKVEStYdEAoq3NDzt9K # oRxrOMUp88qqlnNCaJ+2RrOdOqPVA+C/8KI8ykLcGEh/FDTP0kyr75s9/g64ZCr6 # dSgkQe1CvwWcZklSUPRR8zZJTYsg0ixXNXkrqPNFYLwjjVj33GHek/45wPmyMKVM # 1+mYSlg+0wOI/rOP015LdhJRk8mMDDtbiiKowSYI+RQQEgN9XyO7ZONj4KbhPvbC # dLI/Hgl27KtdRnXiYKNYCQEoAA6EVO7O6V3IXjASvUaetdN2udIOa5kM0jO0zbEC # AwEAAaOCAV0wggFZMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFLoW2W1N # hS9zKXaaL3WMaiCPnshvMB8GA1UdIwQYMBaAFOzX44LScV1kTN8uZz/nupiuHA9P # MA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDCDB3BggrBgEFBQcB # AQRrMGkwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBBBggr # BgEFBQcwAoY1aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1 # c3RlZFJvb3RHNC5jcnQwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybDMuZGln # aWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcmwwIAYDVR0gBBkwFzAI # BgZngQwBBAIwCwYJYIZIAYb9bAcBMA0GCSqGSIb3DQEBCwUAA4ICAQB9WY7Ak7Zv # mKlEIgF+ZtbYIULhsBguEE0TzzBTzr8Y+8dQXeJLKftwig2qKWn8acHPHQfpPmDI # 2AvlXFvXbYf6hCAlNDFnzbYSlm/EUExiHQwIgqgWvalWzxVzjQEiJc6VaT9Hd/ty # dBTX/6tPiix6q4XNQ1/tYLaqT5Fmniye4Iqs5f2MvGQmh2ySvZ180HAKfO+ovHVP # ulr3qRCyXen/KFSJ8NWKcXZl2szwcqMj+sAngkSumScbqyQeJsG33irr9p6xeZmB # o1aGqwpFyd/EjaDnmPv7pp1yr8THwcFqcdnGE4AJxLafzYeHJLtPo0m5d2aR8XKc # 6UsCUqc3fpNTrDsdCEkPlM05et3/JWOZJyw9P2un8WbDQc1PtkCbISFA0LcTJM3c # HXg65J6t5TRxktcma+Q4c6umAU+9Pzt4rUyt+8SVe+0KXzM5h0F4ejjpnOHdI/0d # KNPH+ejxmF/7K9h+8kaddSweJywm228Vex4Ziza4k9Tm8heZWcpw8De/mADfIBZP # J/tgZxahZrrdVcA6KYawmKAr7ZVBtzrVFZgxtGIJDwq9gdkT/r+k0fNX2bwE+oLe # Mt8EifAAzV3C+dAjfwAL5HYCJtnwZXZCpimHCUcr5n8apIUP/JiW9lVUKx+A+sDy # Divl1vupL0QVSucTDh3bNzgaoSv27dZ8/DCCBrAwggSYoAMCAQICEAitQLJg0pxM # n17Nqb2TrtkwDQYJKoZIhvcNAQEMBQAwYjELMAkGA1UEBhMCVVMxFTATBgNVBAoT # DERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UE # AxMYRGlnaUNlcnQgVHJ1c3RlZCBSb290IEc0MB4XDTIxMDQyOTAwMDAwMFoXDTM2 # MDQyODIzNTk1OVowaTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ # bmMuMUEwPwYDVQQDEzhEaWdpQ2VydCBUcnVzdGVkIEc0IENvZGUgU2lnbmluZyBS # U0E0MDk2IFNIQTM4NCAyMDIxIENBMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC # AgoCggIBANW0L0LQKK14t13VOVkbsYhC9TOM6z2Bl3DFu8SFJjCfpI5o2Fz16zQk # B+FLT9N4Q/QX1x7a+dLVZxpSTw6hV/yImcGRzIEDPk1wJGSzjeIIfTR9TIBXEmtD # mpnyxTsf8u/LR1oTpkyzASAl8xDTi7L7CPCK4J0JwGWn+piASTWHPVEZ6JAheEUu # oZ8s4RjCGszF7pNJcEIyj/vG6hzzZWiRok1MghFIUmjeEL0UV13oGBNlxX+yT4Us # SKRWhDXW+S6cqgAV0Tf+GgaUwnzI6hsy5srC9KejAw50pa85tqtgEuPo1rn3MeHc # reQYoNjBI0dHs6EPbqOrbZgGgxu3amct0r1EGpIQgY+wOwnXx5syWsL/amBUi0nB # k+3htFzgb+sm+YzVsvk4EObqzpH1vtP7b5NhNFy8k0UogzYqZihfsHPOiyYlBrKD # 1Fz2FRlM7WLgXjPy6OjsCqewAyuRsjZ5vvetCB51pmXMu+NIUPN3kRr+21CiRshh # WJj1fAIWPIMorTmG7NS3DVPQ+EfmdTCN7DCTdhSmW0tddGFNPxKRdt6/WMtyEClB # 8NXFbSZ2aBFBE1ia3CYrAfSJTVnbeM+BSj5AR1/JgVBzhRAjIVlgimRUwcwhGug4 # GXxmHM14OEUwmU//Y09Mu6oNCFNBfFg9R7P6tuyMMgkCzGw8DFYRAgMBAAGjggFZ # MIIBVTASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBRoN+Drtjv4XxGG+/5h # ewiIZfROQjAfBgNVHSMEGDAWgBTs1+OC0nFdZEzfLmc/57qYrhwPTzAOBgNVHQ8B # Af8EBAMCAYYwEwYDVR0lBAwwCgYIKwYBBQUHAwMwdwYIKwYBBQUHAQEEazBpMCQG # CCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQQYIKwYBBQUHMAKG # NWh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRSb290 # RzQuY3J0MEMGA1UdHwQ8MDowOKA2oDSGMmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNv # bS9EaWdpQ2VydFRydXN0ZWRSb290RzQuY3JsMBwGA1UdIAQVMBMwBwYFZ4EMAQMw # CAYGZ4EMAQQBMA0GCSqGSIb3DQEBDAUAA4ICAQA6I0Q9jQh27o+8OpnTVuACGqX4 # SDTzLLbmdGb3lHKxAMqvbDAnExKekESfS/2eo3wm1Te8Ol1IbZXVP0n0J7sWgUVQ # /Zy9toXgdn43ccsi91qqkM/1k2rj6yDR1VB5iJqKisG2vaFIGH7c2IAaERkYzWGZ # gVb2yeN258TkG19D+D6U/3Y5PZ7Umc9K3SjrXyahlVhI1Rr+1yc//ZDRdobdHLBg # XPMNqO7giaG9OeE4Ttpuuzad++UhU1rDyulq8aI+20O4M8hPOBSSmfXdzlRt2V0C # FB9AM3wD4pWywiF1c1LLRtjENByipUuNzW92NyyFPxrOJukYvpAHsEN/lYgggnDw # zMrv/Sk1XB+JOFX3N4qLCaHLC+kxGv8uGVw5ceG+nKcKBtYmZ7eS5k5f3nqsSc8u # pHSSrds8pJyGH+PBVhsrI/+PteqIe3Br5qC6/To/RabE6BaRUotBwEiES5ZNq0RA # 443wFSjO7fEYVgcqLxDEDAhkPDOPriiMPMuPiAsNvzv0zh57ju+168u38HcT5uco # P6wSrqUvImxB+YJcFWbMbA7KxYbD9iYzDAdLoNMHAmpqQDBISzSoUSC7rRuFCOJZ # DW3KBVAr6kocnqX9oKcfBnTn8tZSkP2vhUgh+Vc7tJwD7YZF9LRhbr9o4iZghurI # r6n+lB3nYxs6hlZ4TjCCBsIwggSqoAMCAQICEAVEr/OUnQg5pr/bP1/lYRYwDQYJ # KoZIhvcNAQELBQAwYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ # bmMuMTswOQYDVQQDEzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJTQTQwOTYgU0hBMjU2 # IFRpbWVTdGFtcGluZyBDQTAeFw0yMzA3MTQwMDAwMDBaFw0zNDEwMTMyMzU5NTla # MEgxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjEgMB4GA1UE # AxMXRGlnaUNlcnQgVGltZXN0YW1wIDIwMjMwggIiMA0GCSqGSIb3DQEBAQUAA4IC # DwAwggIKAoICAQCjU0WHHYOOW6w+VLMj4M+f1+XS512hDgncL0ijl3o7Kpxn3GIV # WMGpkxGnzaqyat0QKYoeYmNp01icNXG/OpfrlFCPHCDqx5o7L5Zm42nnaf5bw9Yr # IBzBl5S0pVCB8s/LB6YwaMqDQtr8fwkklKSCGtpqutg7yl3eGRiF+0XqDWFsnf5x # XsQGmjzwxS55DxtmUuPI1j5f2kPThPXQx/ZILV5FdZZ1/t0QoRuDwbjmUpW1R9d4 # KTlr4HhZl+NEK0rVlc7vCBfqgmRN/yPjyobutKQhZHDr1eWg2mOzLukF7qr2JPUd # vJscsrdf3/Dudn0xmWVHVZ1KJC+sK5e+n+T9e3M+Mu5SNPvUu+vUoCw0m+PebmQZ # BzcBkQ8ctVHNqkxmg4hoYru8QRt4GW3k2Q/gWEH72LEs4VGvtK0VBhTqYggT02ke # fGRNnQ/fztFejKqrUBXJs8q818Q7aESjpTtC/XN97t0K/3k0EH6mXApYTAA+hWl1 # x4Nk1nXNjxJ2VqUk+tfEayG66B80mC866msBsPf7Kobse1I4qZgJoXGybHGvPrhv # ltXhEBP+YUcKjP7wtsfVx95sJPC/QoLKoHE9nJKTBLRpcCcNT7e1NtHJXwikcKPs # CvERLmTgyyIryvEoEyFJUX4GZtM7vvrrkTjYUQfKlLfiUKHzOtOKg8tAewIDAQAB # o4IBizCCAYcwDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/ # BAwwCgYIKwYBBQUHAwgwIAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJYIZIAYb9bAcB # MB8GA1UdIwQYMBaAFLoW2W1NhS9zKXaaL3WMaiCPnshvMB0GA1UdDgQWBBSltu8T # 5+/N0GSh1VapZTGj3tXjSTBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsMy5k # aWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRSU0E0MDk2U0hBMjU2VGltZVN0 # YW1waW5nQ0EuY3JsMIGQBggrBgEFBQcBAQSBgzCBgDAkBggrBgEFBQcwAYYYaHR0 # cDovL29jc3AuZGlnaWNlcnQuY29tMFgGCCsGAQUFBzAChkxodHRwOi8vY2FjZXJ0 # cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRSU0E0MDk2U0hBMjU2VGlt # ZVN0YW1waW5nQ0EuY3J0MA0GCSqGSIb3DQEBCwUAA4ICAQCBGtbeoKm1mBe8cI1P # ijxonNgl/8ss5M3qXSKS7IwiAqm4z4Co2efjxe0mgopxLxjdTrbebNfhYJwr7e09 # SI64a7p8Xb3CYTdoSXej65CqEtcnhfOOHpLawkA4n13IoC4leCWdKgV6hCmYtld5 # j9smViuw86e9NwzYmHZPVrlSwradOKmB521BXIxp0bkrxMZ7z5z6eOKTGnaiaXXT # UOREEr4gDZ6pRND45Ul3CFohxbTPmJUaVLq5vMFpGbrPFvKDNzRusEEm3d5al08z # jdSNd311RaGlWCZqA0Xe2VC1UIyvVr1MxeFGxSjTredDAHDezJieGYkD6tSRN+9N # UvPJYCHEVkft2hFLjDLDiOZY4rbbPvlfsELWj+MXkdGqwFXjhr+sJyxB0JozSqg2 # 1Llyln6XeThIX8rC3D0y33XWNmdaifj2p8flTzU8AL2+nCpseQHc2kTmOt44Owde # OVj0fHMxVaCAEcsUDH6uvP6k63llqmjWIso765qCNVcoFstp8jKastLYOrixRoZr # uhf9xHdsFWyuq69zOuhJRrfVf8y2OMDY7Bz1tqG4QyzfTkx9HmhwwHcK1ALgXGC7 # KP845VJa1qwXIiNO9OzTF/tQa/8Hdx9xl0RBybhG02wyfFgvZ0dl5Rtztpn5aywG # Ru9BHvDwX+Db2a2QgESvgBBBijCCBtswggTDoAMCAQICEATKzAo8VGv2qBgLEa7N # zyYwDQYJKoZIhvcNAQELBQAwaTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lD # ZXJ0LCBJbmMuMUEwPwYDVQQDEzhEaWdpQ2VydCBUcnVzdGVkIEc0IENvZGUgU2ln # bmluZyBSU0E0MDk2IFNIQTM4NCAyMDIxIENBMTAeFw0yMTEwMTkwMDAwMDBaFw0y # MzExMDQyMzU5NTlaMGAxCzAJBgNVBAYTAkdCMQ8wDQYDVQQHEwZMb25kb24xHzAd # BgNVBAoTFlZpcnR1YWwgRW5naW5lIExpbWl0ZWQxHzAdBgNVBAMTFlZpcnR1YWwg # RW5naW5lIExpbWl0ZWQwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQC1 # ubejnuZBjG7SJ1KJ+GXJloNU7Rm7QGcZMVk61kuJsGi2CkqnsF7eT1YPIhs6JQdV # oVjsMbxovySukCuP7colHj1Tmktdx681RAUsvXymL2Vn57bD51wEB+4nfQnvrRW0 # 8PAADueYB9/d/2j60QHVmch5fOU9HIzPthlLjewN4B+3ynyMXOYzSNG231Jc3Epw # LSCdfoLHS/DgCTGYy2t5f8iC+PlVWrgzzUTzgJ59axT8imogvbjGnGXc47BnnfDO # f6s8DdP1uPQ9TIj/pW841QhEP8R84PG6tV1IN24sexFqDj5DfEW9mb9Y2qyvaoa/ # ssdPe4o+yO48GjUzP18z8B8/B0R8zfEn5jWsGpTGcOHBhL3sXDcszreVMqXds3hM # 4UQlfxg+ALTYni/NhIg/R/AEE/J3sy1uJfMW9KheeXQRCaMf6Th+M4LCfW2Bacjv # s0RPTkl3ToXc53nYif2ognkGG7jOUwURCATsk404jj8eX90HN82TIi0wxFw2I8kC # AwEAAaOCAgYwggICMB8GA1UdIwQYMBaAFGg34Ou2O/hfEYb7/mF7CIhl9E5CMB0G # A1UdDgQWBBQSv6nVtbCtP7OXr5NeEdbP17Bi4DAOBgNVHQ8BAf8EBAMCB4AwEwYD # VR0lBAwwCgYIKwYBBQUHAwMwgbUGA1UdHwSBrTCBqjBToFGgT4ZNaHR0cDovL2Ny # bDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0Q29kZVNpZ25pbmdSU0E0 # MDk2U0hBMzg0MjAyMUNBMS5jcmwwU6BRoE+GTWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0 # LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNBNDA5NlNIQTM4NDIw # MjFDQTEuY3JsMD4GA1UdIAQ3MDUwMwYGZ4EMAQQBMCkwJwYIKwYBBQUHAgEWG2h0 # dHA6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzCBlAYIKwYBBQUHAQEEgYcwgYQwJAYI # KwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBcBggrBgEFBQcwAoZQ # aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0Q29k # ZVNpZ25pbmdSU0E0MDk2U0hBMzg0MjAyMUNBMS5jcnQwDAYDVR0TAQH/BAIwADAN # BgkqhkiG9w0BAQsFAAOCAgEAHfkR7a+g8eOt0OUHzSShxbZmtVwo7n885yE86/Ev # V69c92hp7E0MLBfMz/oZdrhTVWFX4apt5D4kJkVdZuLJzGpcR+Ll/GPaxHN0XcIO # ii0WKrErV6rPZbzYpHkVfjktOxAyuDo7yQDadvZ4HGTpNZhS1L7eO11L+fAOn8H8 # D6iXQJoPnWGXOr1BjQ02TCxtn58qYjGKeoQUXqe1o6ZA1ZLQQ601AFh2V/Sk1OEG # 4/EQ2wO1ZFLnqmDep+Xf6SG1553ywWjJj/2DVKh9tzsMBCJi1OKSZ6QD6zlaQdjV # 7CJIX81xdI00w2Bu4CyLOgxD02Qn+8yGzz36E1R7pOWT1sV984/2iHnPoN/9ccmy # WE1jcPFZhBDG2rNmkCT/gYInwv2p14QO+26U+nenpWo0HFA+73wLjql9eAJfS8iJ # 5XLdFk6EcPYkLK1Y0VZckW+ijTdqRzJO6aKrb6Z7DoAvBcoq0V6gMd+fMORWxlE+ # pjj2AQJUqJ9jtntSy5/dIE4Hq3E6XMrXl4xHYQhGwFII9VkJ69T3PnUM/8Ytnr+Q # IMbqFy7qKx6chYDFbDXCIa/ocmlxrve6aZFihR4q01XyGDsi2U+Ka2uOOhP7RyIT # w6G6/kYMGorQYTiKQIhRnIWDvimmQdXir5iCFe+5uTAxJXvKYVEqGBwZAuUNc/45 # pVAxggXCMIIFvgIBATB9MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2Vy # dCwgSW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25p # bmcgUlNBNDA5NiBTSEEzODQgMjAyMSBDQTECEATKzAo8VGv2qBgLEa7NzyYwCQYF # Kw4DAhoFAKB4MBgGCisGAQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJKoZIhvcNAQkD # MQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwIwYJ # KoZIhvcNAQkEMRYEFCoDNSiS2Dp9Kksd7ocXmPg9wUmfMA0GCSqGSIb3DQEBAQUA # BIIBgF8NiEFIpF5Somwi73S9Za7VwF3bhkky44L4J30AMl9jn1DC0UDdgVaBQ3Q4 # S5b2Ssmod/I1GhzuvsOS5xGE4BAsfDh2IDqUj83wBKPUYFxVuzjfty5qUeTPmutH # 7wWdW1hEThN7DZ6mQ4dV+Ro+1SAbodqi4A7VBRn/np8reI5fArbimGtEarMe79kG # RchJca1FuSGvzmtSHiQsj08sqq9jyRjA/l8/r4kjLu3QI6ANexy2aBWgRcOp3wB2 # t5OUzXqo3BTMu7jI0xa+RbsW4AZgkvB2l6C9J8qOdqkWA3usJwdANCS1jMpoNvXh # LmYKW5Lk7ZoAW+kpGnwEWwxoqSKEt5I629D6IhUjD3hmoIVa4B1b2betXOVnDgcJ # bGAu4oaO0h0e0SuqTgVDAIlE2ADmrgQ2IB2S3ZBZlnIgF2LYjKG4PXkoJ4Tq/W24 # 1j0TBYsGmO+tYK8zl+4RktsycjZAwGhYg9w7/nZh28lM46WGWzQGEjBUAQVqXSzv # 6hQiSqGCAyAwggMcBgkqhkiG9w0BCQYxggMNMIIDCQIBATB3MGMxCzAJBgNVBAYT # AlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQg # VHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0ECEAVEr/OU # nQg5pr/bP1/lYRYwDQYJYIZIAWUDBAIBBQCgaTAYBgkqhkiG9w0BCQMxCwYJKoZI # hvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0yMzExMDQxNzA2NThaMC8GCSqGSIb3DQEJ # BDEiBCBB+RC0RBl2D2W/jBC6JVnRWjQka3icqdb9CWuOnoi55DANBgkqhkiG9w0B # AQEFAASCAgAxJWDdzXjEy/rhvgopurSucHIP6N7nhHM9n0DFMGhun83+ayip4B27 # Yb8Dsjo/V73kJIr/KDE/v7PncRFChIX61K42XfsQGbIIVzDHBl8rLHIOHXMB62iN # FH6svgCH1Ydz9cU+G4gdHgHqWCY1KcTsOZ7vQaZPzUMN5+sh9u9QfHANsJpXrvXR # 9x8a7c3yEQ16iDavWM10vvojX60RZSXj3lpIz4ZnB/aAVPko1VjX+T4pQ+TP0Nfa # vHBo2hoiBQj/2PyMkffOKKa7+5m38klKDThFGAbcW5fsUuSZvR6WND/2q17VHjMb # ePraZeMbMvHjd7bqsJinrKxER1yrT+ll3d0f07L7Uc4WcQGmfLu2uFX6p2vktAUa # prtpw5ZTtmwzMmuY9dvje/9D5+CKeWGZxVedujdfUHOz+qX9KlwdPF2OKI6qti6U # zgO3KvQAqgwzRcC0lTa9Sta4AoHtbeM7o4ynRmQ2TA1uEoCeS/CSJNrce1G+v/vx # fwHVhyYQnsO05Ow6o+Lkc4wX2dnbtzLaUaVvkRWECn/fIJ21AFYny7cFFtHKcblB # K7wF1S0ApDFzVdS0q6MNylyfmB1V2/u2+6D+hg2jlxcSNSp8ios2NfMNFC5HKeUo # V91EGmb59D53/wdzvY9RyN+8ocrL7uagbejhZZpKQmXJmxUk10bnpw== # SIG # End signature block |