helpers/DscOperations.psm1
Set-StrictMode -Version latest $ErrorActionPreference = 'Stop' Import-Module $PSScriptRoot/GuestConfigPath.psm1 -Force $script:ExecuteDscOperationsScript = @" using System; using System.Runtime.InteropServices; using System.Management.Automation; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; namespace GuestConfig {{ public class DscOperations {{ [DllImport("{0}", CharSet = CharSet.Ansi, SetLastError = true, CallingConvention = CallingConvention.StdCall)] public static extern IntPtr new_dsc_library_context(string assignment_name, string dsc_binary_path, IntPtr writeMessageCallback, IntPtr writeErrorCallback, IntPtr writeResultCallback); [DllImport("{0}", CharSet = CharSet.Ansi, SetLastError = true, CallingConvention = CallingConvention.StdCall)] public static extern Int32 test_dsc_configuration(IntPtr context, string job_id, string assignment_name, string file_path); [DllImport("{0}", CharSet = CharSet.Ansi, SetLastError = true, CallingConvention = CallingConvention.StdCall)] public static extern Int32 get_dsc_configuration(IntPtr context, string job_id, string assignment_name, string file_path); [DllImport("{0}", CharSet = CharSet.Ansi, SetLastError = true, CallingConvention = CallingConvention.StdCall)] public static extern Int32 publish_dsc_assignment(IntPtr context, string job_id, string assignment_name, string assignments_path); [DllImport("{0}", CharSet = CharSet.Ansi, SetLastError = true, CallingConvention = CallingConvention.StdCall)] public static extern Int32 set_dsc_meta_configuration(IntPtr context, string job_id, string assignment_name, string assignments_path); [DllImport("{0}", CharSet = CharSet.Ansi, SetLastError = true, CallingConvention = CallingConvention.StdCall)] public static extern void delete_dsc_library_context(IntPtr context); internal enum MessageChannel {{ Warning, Verbose, Debug, Error }} public DscOperations() {{ m_messages = new List<Tuple<MessageChannel, string>>(); m_result = ""; WriteMessageDelegate delegate_write_message = new WriteMessageDelegate(WriteMessage); GCHandle m_write_message_gc_handle = GCHandle.Alloc(delegate_write_message); m_write_message_callback = Marshal.GetFunctionPointerForDelegate(delegate_write_message); WriteErrorDelegate delegate_write_error = new WriteErrorDelegate(WriteError); m_write_error_gc_handle = GCHandle.Alloc(delegate_write_error); m_write_error_callback = Marshal.GetFunctionPointerForDelegate(delegate_write_error); WriteResultDelegate delegate_write_result = new WriteResultDelegate(WriteResult); m_write_result_gc_handle = GCHandle.Alloc(delegate_write_result); m_write_result_callback = Marshal.GetFunctionPointerForDelegate(delegate_write_result); }} ~DscOperations() {{ if (m_write_message_gc_handle.IsAllocated) {{ m_write_message_gc_handle.Free(); }} if (m_write_error_gc_handle.IsAllocated) {{ m_write_error_gc_handle.Free(); }} if (m_write_result_gc_handle.IsAllocated) {{ m_write_result_gc_handle.Free(); }} }} public string TestDscConfiguration(PSCmdlet ps_cmdlet, string job_id, string configuration_name, string gc_bin_path) {{ IntPtr context = IntPtr.Zero; try {{ ClearMessages(); context = new_dsc_library_context(configuration_name, gc_bin_path, m_write_message_callback, m_write_error_callback, m_write_result_callback); if(context == IntPtr.Zero) {{ ps_cmdlet.WriteError(CreateErrorRecord("TestGuestConfiguration", "Failed to initialize Guest Configuration library.", true)); }} Int32 result = test_dsc_configuration(context, job_id, configuration_name, ""); for (int i = 0; i < m_messages.Count; i++) {{ var message = m_messages[i]; if(message.Item1 == MessageChannel.Error) {{ ps_cmdlet.WriteError(CreateErrorRecord("TestGuestConfiguration", message.Item2, false)); }} else if(message.Item1 == MessageChannel.Warning) {{ ps_cmdlet.WriteWarning(message.Item2); }} else if(message.Item1 == MessageChannel.Debug) {{ ps_cmdlet.WriteDebug(message.Item2); }} else {{ ps_cmdlet.WriteVerbose(message.Item2); }} }} }} finally {{ delete_dsc_library_context(context); }} return m_result; }} public string GettDscConfiguration(PSCmdlet ps_cmdlet, string job_id, string configuration_name, string gc_bin_path) {{ IntPtr context = IntPtr.Zero; try {{ ClearMessages(); context = new_dsc_library_context(configuration_name, gc_bin_path, m_write_message_callback, m_write_error_callback, m_write_result_callback); if(context == IntPtr.Zero) {{ ps_cmdlet.WriteError(CreateErrorRecord("TestGuestConfiguration", "Failed to initialize Guest Configuration library.", true)); }} Int32 result = get_dsc_configuration(context, job_id, configuration_name, ""); for (int i = 0; i < m_messages.Count; i++) {{ var message = m_messages[i]; if(message.Item1 == MessageChannel.Error) {{ ps_cmdlet.WriteError(new ErrorRecord( new InvalidOperationException(message.Item2), "TestGuestConfiguration", ErrorCategory.InvalidResult, null)); }} else if(message.Item1 == MessageChannel.Warning) {{ ps_cmdlet.WriteWarning(message.Item2); }} else {{ ps_cmdlet.WriteVerbose(message.Item2); }} }} }} finally {{ delete_dsc_library_context(context); }} return m_result; }} public void PublishDscConfiguration(PSCmdlet ps_cmdlet, string job_id, string configuration_name, string gc_bin_path, string policy_path) {{ IntPtr context = IntPtr.Zero; try {{ ClearMessages(); context = new_dsc_library_context(configuration_name, gc_bin_path, m_write_message_callback, m_write_error_callback, m_write_result_callback); if(context == IntPtr.Zero) {{ ps_cmdlet.WriteError(CreateErrorRecord("TestGuestConfiguration", "Failed to initialize Guest Configuration library.", true)); }} Int32 result = publish_dsc_assignment(context, job_id, configuration_name, policy_path); if(result != 0) {{ ps_cmdlet.WriteError(CreateErrorRecord("TestGuestConfiguration", "Failed to publish Guest Configuration policy package.", true)); }} }} finally {{ delete_dsc_library_context(context); }} }} public void SetDscLocalConfigurationManager(PSCmdlet ps_cmdlet, string job_id, string configuration_name, string gc_bin_path, string policy_path) {{ IntPtr context = IntPtr.Zero; try {{ ClearMessages(); context = new_dsc_library_context(configuration_name, gc_bin_path, m_write_message_callback, m_write_error_callback, m_write_result_callback); if(context == IntPtr.Zero) {{ ps_cmdlet.WriteError(CreateErrorRecord("TestGuestConfiguration", "Failed to initialize Guest Configuration library.", true)); }} Int32 result = set_dsc_meta_configuration(context, job_id, configuration_name, policy_path); if(result != 0) {{ ps_cmdlet.WriteError(CreateErrorRecord("TestGuestConfiguration", "Failed to set Meta config settings.", true)); }} }} finally {{ delete_dsc_library_context(context); }} }} private delegate Int32 WriteMessageDelegate(Int32 channel, IntPtr message); private delegate Int32 WriteErrorDelegate(IntPtr error); private delegate Int32 WriteResultDelegate(IntPtr result); private string m_result; private List<Tuple<MessageChannel, string>> m_messages; private GCHandle m_write_message_gc_handle; private GCHandle m_write_error_gc_handle; private GCHandle m_write_result_gc_handle; private IntPtr m_write_message_callback; private IntPtr m_write_error_callback; private IntPtr m_write_result_callback; internal Int32 WriteMessage(Int32 channel, IntPtr message_ptr) {{ string message; message = Marshal.PtrToStringAnsi(message_ptr); m_messages.Add(Tuple.Create((MessageChannel)channel, message)); return 0; }} internal Int32 WriteError(IntPtr error_ptr) {{ string error; error = Marshal.PtrToStringAnsi(error_ptr); m_messages.Add(Tuple.Create(MessageChannel.Error, error)); return 0; }} internal Int32 WriteResult(IntPtr result_ptr) {{ m_result = Marshal.PtrToStringAnsi(result_ptr); return 0; }} private void ClearMessages() {{ m_messages.Clear(); }} private ErrorRecord CreateErrorRecord(string error_id, string error_message, bool include_error_from_message_list) {{ string error = error_message + "\r\n"; for (int i = 0; include_error_from_message_list && i < m_messages.Count; i++) {{ var message = m_messages[i]; if(message.Item1 == MessageChannel.Error) {{ error = message.Item2 + "\r\n"; }} }} return new ErrorRecord( new InvalidOperationException(error), error_id, ErrorCategory.InvalidResult, null); }} }} }} "@ <# .SYNOPSIS Test DSC configuration. .Parameter ConfigurationName Configuration name. .Example Test-DscConfiguration -ConfigurationName WindowsTLS #> function Test-DscConfiguration { [CmdletBinding()] param ( [parameter(Position=0, Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $ConfigurationName ) $job_id = [guid]::NewGuid().Guid $gcBinPath = Get-GuestConfigBinaryPath $dsclibPath = $(Get-DscLibPath) -replace '[""\\]','\$&' if(-not ([System.Management.Automation.PSTypeName]'GuestConfig.DscOperations').Type) { $addTypeScript = $ExecuteDscOperationsScript -f $dsclibPath Add-Type -TypeDefinition $addTypeScript -ReferencedAssemblies 'System.Management.Automation','System.Console','System.Collections' } $dscOperation = [GuestConfig.DscOperations]::New() $result = $dscOperation.TestDscConfiguration($PSCmdlet, $job_id, $ConfigurationName, $gcBinPath) return ConvertFrom-Json $result } <# .SYNOPSIS Get DSC configuration. .Parameter ConfigurationName Configuration name. .Example Get-DscConfiguration -ConfigurationName WindowsTLS #> function Get-DscConfiguration { [CmdletBinding()] param ( [parameter(Position=0, Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $ConfigurationName ) $job_id = [guid]::NewGuid().Guid $gcBinPath = Get-GuestConfigBinaryPath $dsclibPath = $(Get-DscLibPath) -replace '[""\\]','\$&' if(-not ([System.Management.Automation.PSTypeName]'GuestConfig.DscOperations').Type) { $addTypeScript = $ExecuteDscOperationsScript -f $dsclibPath Add-Type -TypeDefinition $addTypeScript -ReferencedAssemblies 'System.Management.Automation','System.Console','System.Collections' } $dscOperation = [GuestConfig.DscOperations]::New() $result = $dscOperation.GettDscConfiguration($PSCmdlet, $job_id, $ConfigurationName, $gcBinPath) return ConvertFrom-Json $result } <# .SYNOPSIS Publish DSC configuration. .Parameter ConfigurationName Configuration name. .Example Publish-DscConfiguration -Path C:\metaconfig #> function Publish-DscConfiguration { [CmdletBinding()] param ( [parameter(Position=0, Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $ConfigurationName, [parameter(Position=1, Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $Path ) $job_id = [guid]::NewGuid().Guid $gcBinPath = Get-GuestConfigBinaryPath $dsclibPath = $(Get-DscLibPath) -replace '[""\\]','\$&' if(-not ([System.Management.Automation.PSTypeName]'GuestConfig.DscOperations').Type) { $addTypeScript = $ExecuteDscOperationsScript -f $dsclibPath Add-Type -TypeDefinition $addTypeScript -ReferencedAssemblies 'System.Management.Automation','System.Console','System.Collections' } $dscOperation = [GuestConfig.DscOperations]::New() $result = $dscOperation.PublishDscConfiguration($PSCmdlet, $job_id, $ConfigurationName, $gcBinPath, $Path) } <# .SYNOPSIS Set DSC LCM settings. .Parameter ConfigurationName Configuration name. .Example Set-DscLocalConfigurationManager -Path C:\metaconfig #> function Set-DscLocalConfigurationManager { [CmdletBinding()] param ( [parameter(Position=0, Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $ConfigurationName, [parameter(Position=1, Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $Path ) $job_id = [guid]::NewGuid().Guid $gcBinPath = Get-GuestConfigBinaryPath $dsclibPath = $(Get-DscLibPath) -replace '[""\\]','\$&' if(-not ([System.Management.Automation.PSTypeName]'GuestConfig.DscOperations').Type) { $addTypeScript = $ExecuteDscOperationsScript -f $dsclibPath Add-Type -TypeDefinition $addTypeScript -ReferencedAssemblies 'System.Management.Automation','System.Console','System.Collections' } $dscOperation = [GuestConfig.DscOperations]::New() $result = $dscOperation.SetDscLocalConfigurationManager($PSCmdlet, $job_id, $ConfigurationName, $gcBinPath, $Path) } # SIG # Begin signature block # MIIjigYJKoZIhvcNAQcCoIIjezCCI3cCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAWlJbrT3Npm7Nl # 8TTPNBBRJ4qz3wUEvMx4mdLXGq0hGaCCDYUwggYDMIID66ADAgECAhMzAAABUptA # n1BWmXWIAAAAAAFSMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p # bmcgUENBIDIwMTEwHhcNMTkwNTAyMjEzNzQ2WhcNMjAwNTAyMjEzNzQ2WjB0MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB # AQCxp4nT9qfu9O10iJyewYXHlN+WEh79Noor9nhM6enUNbCbhX9vS+8c/3eIVazS # YnVBTqLzW7xWN1bCcItDbsEzKEE2BswSun7J9xCaLwcGHKFr+qWUlz7hh9RcmjYS # kOGNybOfrgj3sm0DStoK8ljwEyUVeRfMHx9E/7Ca/OEq2cXBT3L0fVnlEkfal310 # EFCLDo2BrE35NGRjG+/nnZiqKqEh5lWNk33JV8/I0fIcUKrLEmUGrv0CgC7w2cjm # bBhBIJ+0KzSnSWingXol/3iUdBBy4QQNH767kYGunJeY08RjHMIgjJCdAoEM+2mX # v1phaV7j+M3dNzZ/cdsz3oDfAgMBAAGjggGCMIIBfjAfBgNVHSUEGDAWBgorBgEE # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQU3f8Aw1sW72WcJ2bo/QSYGzVrRYcw # VAYDVR0RBE0wS6RJMEcxLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJh # dGlvbnMgTGltaXRlZDEWMBQGA1UEBRMNMjMwMDEyKzQ1NDEzNjAfBgNVHSMEGDAW # gBRIbmTlUAXTgqoXNzcitW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8v # d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIw # MTEtMDctMDguY3JsMGEGCCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDov # L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDEx # XzIwMTEtMDctMDguY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB # AJTwROaHvogXgixWjyjvLfiRgqI2QK8GoG23eqAgNjX7V/WdUWBbs0aIC3k49cd0 # zdq+JJImixcX6UOTpz2LZPFSh23l0/Mo35wG7JXUxgO0U+5drbQht5xoMl1n7/TQ # 4iKcmAYSAPxTq5lFnoV2+fAeljVA7O43szjs7LR09D0wFHwzZco/iE8Hlakl23ZT # 7FnB5AfU2hwfv87y3q3a5qFiugSykILpK0/vqnlEVB0KAdQVzYULQ/U4eFEjnis3 # Js9UrAvtIhIs26445Rj3UP6U4GgOjgQonlRA+mDlsh78wFSGbASIvK+fkONUhvj8 # B8ZHNn4TFfnct+a0ZueY4f6aRPxr8beNSUKn7QW/FQmn422bE7KfnqWncsH7vbNh # G929prVHPsaa7J22i9wyHj7m0oATXJ+YjfyoEAtd5/NyIYaE4Uu0j1EhuYUo5VaJ # JnMaTER0qX8+/YZRWrFN/heps41XNVjiAawpbAa0fUa3R9RNBjPiBnM0gvNPorM4 # dsV2VJ8GluIQOrJlOvuCrOYDGirGnadOmQ21wPBoGFCWpK56PxzliKsy5NNmAXcE # x7Qb9vUjY1WlYtrdwOXTpxN4slzIht69BaZlLIjLVWwqIfuNrhHKNDM9K+v7vgrI # bf7l5/665g0gjQCDCN6Q5sxuttTAEKtJeS/pkpI+DbZ/MIIHejCCBWKgAwIBAgIK # YQ6Q0gAAAAAAAzANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNV # BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv # c29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlm # aWNhdGUgQXV0aG9yaXR5IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEw # OTA5WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE # BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYD # VQQDEx9NaWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG # 9w0BAQEFAAOCAg8AMIICCgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+la # UKq4BjgaBEm6f8MMHt03a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc # 6Whe0t+bU7IKLMOv2akrrnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4D # dato88tt8zpcoRb0RrrgOGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+ # lD3v++MrWhAfTVYoonpy4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nk # kDstrjNYxbc+/jLTswM9sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6 # A4aN91/w0FK/jJSHvMAhdCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmd # X4jiJV3TIUs+UsS1Vz8kA/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL # 5zmhD+kjSbwYuER8ReTBw3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zd # sGbiwZeBe+3W7UvnSSmnEyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3 # T8HhhUSJxAlMxdSlQy90lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS # 4NaIjAsCAwEAAaOCAe0wggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRI # bmTlUAXTgqoXNzcitW2oynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAL # BgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBD # uRQFTuHqp8cx0SOJNDBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jv # c29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf # MDNfMjIuY3JsMF4GCCsGAQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3 # dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf # MDNfMjIuY3J0MIGfBgNVHSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEF # BQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1h # cnljcHMuaHRtMEAGCCsGAQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkA # YwB5AF8AcwB0AGEAdABlAG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn # 8oalmOBUeRou09h0ZyKbC5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7 # v0epo/Np22O/IjWll11lhJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0b # pdS1HXeUOeLpZMlEPXh6I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/ # KmtYSWMfCWluWpiW5IP0wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvy # CInWH8MyGOLwxS3OW560STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBp # mLJZiWhub6e3dMNABQamASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJi # hsMdYzaXht/a8/jyFqGaJ+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYb # BL7fQccOKO7eZS/sl/ahXJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbS # oqKfenoi+kiVH6v7RyOA9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sL # gOppO6/8MO0ETI7f33VtY5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtX # cVZOSEXAQsmbdlsKgEhr/Xmfwb1tbWrJUnMTDXpQzTGCFVswghVXAgEBMIGVMH4x # CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt # b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01p # Y3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTECEzMAAAFSm0CfUFaZdYgAAAAA # AVIwDQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQw # HAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEID/L # yClLR44PVCAVoVrqgcuYGS0bvt8e9y2GnSo9TySwMEIGCisGAQQBgjcCAQwxNDAy # oBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5j # b20wDQYJKoZIhvcNAQEBBQAEggEAEIcqDt9oMJiV4ygsVPzna49mPcOAYPSbqhtB # WvH49riXBJzwJ8UjVOTIaQbHD/wK2haasqOqPWsoIzv+rZQd+ZE6iyRvfbsTD3cT # Bec/Ohwkq9EOyBxKEsDSL6KVbfLp12R6H+4d1OtJs4MyKqwpl2L+senOCHsleHr4 # ONY0A2FT/1nCFDyauZMrui/MytxWpwNtHeFHgJQ5Esbrsj32HcSDSC5RgxZbRTt9 # Gshw9nlmUZKeeHNgO+dYlZlXHPXBTOWZGT/XHVCNoahGiUBIWSkxBou+SA4qsBrQ # 3B4j0WknSR8oNulKDds7O7R+7gIwC2+2a1XU1IlrgkKhtBRte6GCEuUwghLhBgor # BgEEAYI3AwMBMYIS0TCCEs0GCSqGSIb3DQEHAqCCEr4wghK6AgEDMQ8wDQYJYIZI # AWUDBAIBBQAwggFRBgsqhkiG9w0BCRABBKCCAUAEggE8MIIBOAIBAQYKKwYBBAGE # WQoDATAxMA0GCWCGSAFlAwQCAQUABCBEHzDej1ownWdqtMF/gyjJ1fJWBIOUMJXW # sFX6GlAr5QIGXnvAjwVGGBMyMDIwMDMyNzE4NTQwNi4xMTRaMASAAgH0oIHQpIHN # MIHKMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH # UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQL # ExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMSYwJAYDVQQLEx1UaGFsZXMg # VFNTIEVTTjoxQThGLUUzQzMtRDY5RDElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt # U3RhbXAgU2VydmljZaCCDjwwggTxMIID2aADAgECAhMzAAABG+IgzdyKr4vZAAAA # AAEbMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo # aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y # cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw # MB4XDTE5MTExMzIxNDAzOFoXDTIxMDIxMTIxNDAzOFowgcoxCzAJBgNVBAYTAlVT # MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK # ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVy # aWNhIE9wZXJhdGlvbnMxJjAkBgNVBAsTHVRoYWxlcyBUU1MgRVNOOjFBOEYtRTND # My1ENjlEMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNlMIIB # IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlYPnftgJcrLXnTYwYfN0LYMd # LhjoGXYd8nHWa1rTxh8qzVlCrSHfByTm6G43p3uqdI2meGJrnizB1iMtWRnn+Y+g # YMgAcUytVahJTrqlLTMf3y43rhcCa4oDtctg7ASraXaClx27FMGylrJ1BOehlgv3 # kFmAWrjLQ8oRzLXs3HC5iP8BPXOjnANKbiZVooUBTktY4rN7xXdWvj/Icwgf5nxa # DqOzbqTIlVVZr+XONbXMXkHEbrTtmp6li5iwg/2JjNgb3K9g+2gjnLY3W/j+NA4E # DX4jrqISaIKiaEPUVTNPMuLj7JVB7UXtLGwYGt26O1DZHeKDErd61VFMt1ManQID # AQABo4IBGzCCARcwHQYDVR0OBBYEFBrlk8pCa7yC3Ccd1pNo2Q8uwRr5MB8GA1Ud # IwQYMBaAFNVjOlyKMZDzQ3t8RhvFM2hahW1VMFYGA1UdHwRPME0wS6BJoEeGRWh0 # dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1RpbVN0 # YVBDQV8yMDEwLTA3LTAxLmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAKG # Pmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljVGltU3RhUENB # XzIwMTAtMDctMDEuY3J0MAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUH # AwgwDQYJKoZIhvcNAQELBQADggEBAFw19IRnpZACw6p+kcoxyfWZNQE/F1D4IZyI # DCHvEPiTTRJgw+DZqMy9elGjQisWrXsT441XnAv3XXsuWcZObKSv5KO75aqRiCGr # v8/IYYPzfcPbKixHDddScaCXawL0oW4AShZx3YLfU8TVkAkKQWz30Te/f+x3FdsE # 4rW/EYkQDLoux3W7lbcOJW4S4JsGBIFm5Qumml9m3buhgsUTfBfCYGEbtdU9Gf2l # /KvW6vX3e39w694zQsRrXkTwSaHoA/uvfYhZq/31hUaY6bMYt+bdqdc+yQCGwECT # f6WZi0z+4UYlwDaPCGfnjx4P+y9m6Hst7LmCsIe4X/UbHs8v9wwwggZxMIIEWaAD # AgECAgphCYEqAAAAAAACMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzET # MBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMV # TWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBD # ZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAxMDAeFw0xMDA3MDEyMTM2NTVaFw0yNTA3 # MDEyMTQ2NTVaMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw # DgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x # JjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMIIBIjANBgkq # hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqR0NvHcRijog7PwTl/X6f2mUa3RUENWl # CgCChfvtfGhLLF/Fw+Vhwna3PmYrW/AVUycEMR9BGxqVHc4JE458YTBZsTBED/Fg # iIRUQwzXTbg4CLNC3ZOs1nMwVyaCo0UN0Or1R4HNvyRgMlhgRvJYR4YyhB50YWeR # X4FUsc+TTJLBxKZd0WETbijGGvmGgLvfYfxGwScdJGcSchohiq9LZIlQYrFd/Xcf # PfBXday9ikJNQFHRD5wGPmd/9WbAA5ZEfu/QS/1u5ZrKsajyeioKMfDaTgaRtogI # Neh4HLDpmc085y9Euqf03GS9pAHBIAmTeM38vMDJRF1eFpwBBU8iTQIDAQABo4IB # 5jCCAeIwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFNVjOlyKMZDzQ3t8RhvF # M2hahW1VMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAP # BgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQW9fOmhjE # MFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kv # Y3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBaBggrBgEF # BQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9w # a2kvY2VydHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3J0MIGgBgNVHSABAf8E # gZUwgZIwgY8GCSsGAQQBgjcuAzCBgTA9BggrBgEFBQcCARYxaHR0cDovL3d3dy5t # aWNyb3NvZnQuY29tL1BLSS9kb2NzL0NQUy9kZWZhdWx0Lmh0bTBABggrBgEFBQcC # AjA0HjIgHQBMAGUAZwBhAGwAXwBQAG8AbABpAGMAeQBfAFMAdABhAHQAZQBtAGUA # bgB0AC4gHTANBgkqhkiG9w0BAQsFAAOCAgEAB+aIUQ3ixuCYP4FxAz2do6Ehb7Pr # psz1Mb7PBeKp/vpXbRkws8LFZslq3/Xn8Hi9x6ieJeP5vO1rVFcIK1GCRBL7uVOM # zPRgEop2zEBAQZvcXBf/XPleFzWYJFZLdO9CEMivv3/Gf/I3fVo/HPKZeUqRUgCv # OA8X9S95gWXZqbVr5MfO9sp6AG9LMEQkIjzP7QOllo9ZKby2/QThcJ8ySif9Va8v # /rbljjO7Yl+a21dA6fHOmWaQjP9qYn/dxUoLkSbiOewZSnFjnXshbcOco6I8+n99 # lmqQeKZt0uGc+R38ONiU9MalCpaGpL2eGq4EQoO4tYCbIjggtSXlZOz39L9+Y1kl # D3ouOVd2onGqBooPiRa6YacRy5rYDkeagMXQzafQ732D8OE7cQnfXXSYIghh2rBQ # Hm+98eEA3+cxB6STOvdlR3jo+KhIq/fecn5ha293qYHLpwmsObvsxsvYgrRyzR30 # uIUBHoD7G4kqVDmyW9rIDVWZeodzOwjmmC3qjeAzLhIp9cAvVCch98isTtoouLGp # 25ayp0Kiyc8ZQU3ghvkqmqMRZjDTu3QyS99je/WZii8bxyGvWbWu3EQ8l1Bx16HS # xVXjad5XwdHeMMD9zOZN+w2/XU/pnR4ZOC+8z1gFLu8NoFA12u8JJxzVs341Hgi6 # 2jbb01+P3nSISRKhggLOMIICNwIBATCB+KGB0KSBzTCByjELMAkGA1UEBhMCVVMx # EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT # FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJp # Y2EgT3BlcmF0aW9uczEmMCQGA1UECxMdVGhhbGVzIFRTUyBFU046MUE4Ri1FM0Mz # LUQ2OUQxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2WiIwoB # ATAHBgUrDgMCGgMVAJ4Pq+8iqLeMzXj4lUks5CQ7nFTGoIGDMIGApH4wfDELMAkG # A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx # HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9z # b2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwDQYJKoZIhvcNAQEFBQACBQDiKDlGMCIY # DzIwMjAwMzI3MTYzNTE4WhgPMjAyMDAzMjgxNjM1MThaMHcwPQYKKwYBBAGEWQoE # ATEvMC0wCgIFAOIoOUYCAQAwCgIBAAICINcCAf8wBwIBAAICEvUwCgIFAOIpisYC # AQAwNgYKKwYBBAGEWQoEAjEoMCYwDAYKKwYBBAGEWQoDAqAKMAgCAQACAwehIKEK # MAgCAQACAwGGoDANBgkqhkiG9w0BAQUFAAOBgQCOJn94vDPW1qCMA996OR/rsBHs # mgM83JQZ6E5adzb6QBJhs0EnoBc93x0ZfnvWnQ2uaYpqKjXPjbAwIh8gSJ6/YEVF # 8gRC//YGKD4/rL21sUHYTs/ZCjOPMMJYvzSlkLD8Z6pb7/W8EW7kZe3UrdQVDF2+ # G6r8Rsad9N6Vejf94jGCAw0wggMJAgEBMIGTMHwxCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1w # IFBDQSAyMDEwAhMzAAABG+IgzdyKr4vZAAAAAAEbMA0GCWCGSAFlAwQCAQUAoIIB # SjAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwLwYJKoZIhvcNAQkEMSIEINTi # eWXlEXrTyc1l7rJqSfJHEMsDFkwR0/fdNskTgFfDMIH6BgsqhkiG9w0BCRACLzGB # 6jCB5zCB5DCBvQQg4JFt8aLEcWZTbJSv9NN8rWqnlSn5A+2N9Bw2imkr23cwgZgw # gYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE # BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYD # VQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAARviIM3ciq+L # 2QAAAAABGzAiBCAhKAIz3Nhvhw0fRL/7es8DKcVYlIcmAIVGsX4dBchMXDANBgkq # hkiG9w0BAQsFAASCAQCPwHuBsHqPGG7EzloIavD4w+s+hPA3InHLos50/rAcHWWD # 4b9zBz+E/8hTdd/1GWhhV/Qi+K0HWHzbcJaAaR9aktTQnSGdJvRBymNTrxoRVjUz # pjNR0tyyQGjEmhP+MXuCAikP1DXzLCCI0LXiDNtDqgvwrvvZFr9CRmtOTuAy4ex8 # xBnIGU1AacZeGipre6NkhmvKH1Y/iRaSi8DBvSkYLfYpCZqMAXIZNDdLMFj21LqF # cR8D1VSOnHJmX/4Gzo9boWpqYsS4C2Gq5/LzMqxta85nuq7KV64NMVK8VZTNsa31 # L/4JNAhRLTUunyFl5NiGwecP1jJbmg8e9nkKsUhD # SIG # End signature block |