CTToolkit.psm1
Class CTReturnObject { [String] $Status [String] $ErrorMessage [System.Exception] $Exception [System.Collections.ArrayList] $Tracelog [System.Collections.ArrayList] $Input = ([Hashtable] $PSBoundParameters) [System.Collections.ArrayList] $Output = @() } #Not in use, because of issue with $PSBoundparameters as default value Function Get-CTReturnObject { param( [String] $Status = "Unknown", [String] $ErrorMessage, [System.Collections.ArrayList] $Tracelog = $Script:Tracelog, [Hashtable] $InputParameters = ([Hashtable] $PSBoundParameters), [System.Collections.ArrayList] $Output = [System.Collections.ArrayList] @() ) return [CTReturnObject] @{ Status = $Status ErrorMessage = $ErrorMessage Tracelog = $Tracelog Input = $InputParameters Output = $Output } } Function Get-TraceLogMessage { <# .Synopsis Generates shorter strings from a long string. .DESCRIPTION Used to limit a tracelog file and split into multiple pieces, for use with a limited field, such as windows event log. #> param($RunbookName, $Message, $maxLength) $Message += "Runbook Name: $RunbookName`n" $Message += "Runas domain: $($env:userdomain)`n" #add last part of tracelog. $Message += "Last part of Trace Log:`n" # $maxLength = 30000 $NumberOfMessages = [Math]::Ceiling(($Script:Tracelog.Length / $maxLength)) For ($i = 0; $i -lt $NumberOfMessages; $i++) { $start = (0 + ($maxLength * $i)) $end = $maxLength if ($end -gt $Script:Tracelog.Length - $start) { $end = $Script:Tracelog.Length - $start } $Message = $Script:Tracelog.Substring($start, $end) if ($Message.Length -eq $maxLength) { $Message = $Message + "`ncontinued.." } $Message } } Function Write-EventLogTraceLog { <# .Synopsis Splits tracelog into multiple strings and then writes them to the windows event log .DESCRIPTION uses the Get-TraceLogMessages function to split the tracelog and write it to event log. #> param($LogName, $SourceName, $RunbookName, $EntryType, $EventId, $Message) $Messages = Get-TraceLogMessage -RunbookName $RunbookName -Message $Message -maxLength 30000 #write event log if (!([System.Diagnostics.EventLog]::SourceExists($SourceName))) { New-EventLog -LogName $LogName -Source $SourceName } foreach ($message in $messages) { Write-EventLog -LogName $LogName -Source $SourceName -EntryType $EntryType -EventId $EventId -Message $Message } } Function Add-Tracelog { <# .Synopsis Adds a tracelog message to tracelog .DESCRIPTION Uses a script scope tracelog variable to have alle scopes write to a sinlg etracelog. Outputs each message to the Verbose stream. #> param($Message) if ([String]::IsNullOrEmpty($script:Tracelog)) { $script:TraceLogId = 0 [System.Collections.ArrayList] $script:Tracelog = @() } $Message = "{0}: {1:yyyy-MM-dd HH:mm:ss.fff}: {2}`n" -f $script:TraceLogId,(get-date),$Message $script:TraceLogId++ #$Message = "$(get-date) - $Message`n" Write-Verbose $Message $script:Tracelog.Add($Message.ToString()) } Function Get-TraceLog { [System.Collections.ArrayList] $script:TraceLog } Function Write-TextLog { <# .Synopsis Writes the tracelog to a text file. .DESCRIPTION Writes the tracelog to a text file. If the text file looks "weird" in notepad, it is becausenotepad cannot alway list the line breaks correctly. Use another editor to view the log. #> param($Message, $LogFolderPath, $LogName, $StartTime) #Write to file $Message + "`n" + ($script:TraceLog -join "`n") | Out-file $LogFolderPath\$($LogName)_$($StartTime.ToString("yyyyMMddhhmmss")).log -Encoding ASCII } Function ConvertTo-IndexedTable { <# .Synopsis Converts an array of objects to a array of hashtables for performance .DESCRIPTION Converts an array of objects to a hashtable of hashtables for performance The hashtable has takes one field as index, for example name and the index field can be used to filter/sort much quicker than and array of objects. (see example for details) .Example Get-CMDevice -CollectionName "All Systems" -Fast | ConvertTo-IndexedTable Name Name Value ---- ----- Object ... Name NCOP-CCMP-CCM01 the index field is available directly, while the complete object is available in the object key of the hash table. #> param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $false, Position = 0)] $IndexFieldName, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true, Position = 1)] [Object]$Object ) #begin { $ReturnArray = @() } #New-Object System.Collections.ArrayList } process { @{ $IndexFieldName = $Object.$IndexFieldName Object = $Object } } #end { $ReturnArray } } Function Clear-Tracelog { <# .Synopsis Clears the tracelog .DESCRIPTION Clears the tracelog #> $script:Tracelog = [System.Collections.ArrayList] @() } Function Write-CTError { param($PSError,$returnObject) #get error messa $CurrentError = $PSError $ErrorMessage = $CurrentError.Exception.Message + "`n $($CurrentError.InvocationInfo.PositionMessage)" Add-Tracelog -Message "Error in control runbook: $ErrorMessage" Write-Error -Message $ErrorMessage #-ErrorAction Continue #output error without stopping, for logging purposes. } # SIG # Begin signature block # MIIm+AYJKoZIhvcNAQcCoIIm6TCCJuUCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCnXPX4pa+w99wW # gCnWiwLwSyVeCR3zdRizb6Qkpo87HqCCH+QwggVvMIIEV6ADAgECAhBI/JO0YFWU # jTanyYqJ1pQWMA0GCSqGSIb3DQEBDAUAMHsxCzAJBgNVBAYTAkdCMRswGQYDVQQI # DBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoM # EUNvbW9kbyBDQSBMaW1pdGVkMSEwHwYDVQQDDBhBQUEgQ2VydGlmaWNhdGUgU2Vy # dmljZXMwHhcNMjEwNTI1MDAwMDAwWhcNMjgxMjMxMjM1OTU5WjBWMQswCQYDVQQG # EwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRTZWN0aWdv # IFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEBAQUA # A4ICDwAwggIKAoICAQCN55QSIgQkdC7/FiMCkoq2rjaFrEfUI5ErPtx94jGgUW+s # hJHjUoq14pbe0IdjJImK/+8Skzt9u7aKvb0Ffyeba2XTpQxpsbxJOZrxbW6q5KCD # J9qaDStQ6Utbs7hkNqR+Sj2pcaths3OzPAsM79szV+W+NDfjlxtd/R8SPYIDdub7 # P2bSlDFp+m2zNKzBenjcklDyZMeqLQSrw2rq4C+np9xu1+j/2iGrQL+57g2extme # me/G3h+pDHazJyCh1rr9gOcB0u/rgimVcI3/uxXP/tEPNqIuTzKQdEZrRzUTdwUz # T2MuuC3hv2WnBGsY2HH6zAjybYmZELGt2z4s5KoYsMYHAXVn3m3pY2MeNn9pib6q # RT5uWl+PoVvLnTCGMOgDs0DGDQ84zWeoU4j6uDBl+m/H5x2xg3RpPqzEaDux5mcz # mrYI4IAFSEDu9oJkRqj1c7AGlfJsZZ+/VVscnFcax3hGfHCqlBuCF6yH6bbJDoEc # QNYWFyn8XJwYK+pF9e+91WdPKF4F7pBMeufG9ND8+s0+MkYTIDaKBOq3qgdGnA2T # OglmmVhcKaO5DKYwODzQRjY1fJy67sPV+Qp2+n4FG0DKkjXp1XrRtX8ArqmQqsV/ # AZwQsRb8zG4Y3G9i/qZQp7h7uJ0VP/4gDHXIIloTlRmQAOka1cKG8eOO7F/05QID # AQABo4IBEjCCAQ4wHwYDVR0jBBgwFoAUoBEKIz6W8Qfs4q8p74Klf9AwpLQwHQYD # VR0OBBYEFDLrkpr/NZZILyhAQnAgNpFcF4XmMA4GA1UdDwEB/wQEAwIBhjAPBgNV # HRMBAf8EBTADAQH/MBMGA1UdJQQMMAoGCCsGAQUFBwMDMBsGA1UdIAQUMBIwBgYE # VR0gADAIBgZngQwBBAEwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybC5jb21v # ZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNAYIKwYBBQUHAQEE # KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wDQYJKoZI # hvcNAQEMBQADggEBABK/oe+LdJqYRLhpRrWrJAoMpIpnuDqBv0WKfVIHqI0fTiGF # OaNrXi0ghr8QuK55O1PNtPvYRL4G2VxjZ9RAFodEhnIq1jIV9RKDwvnhXRFAZ/ZC # J3LFI+ICOBpMIOLbAffNRk8monxmwFE2tokCVMf8WPtsAO7+mKYulaEMUykfb9gZ # pk+e96wJ6l2CxouvgKe9gUhShDHaMuwV5KZMPWw5c9QLhTkg4IUaaOGnSDip0TYl # d8GNGRbFiExmfS9jzpjoad+sPKhdnckcW67Y8y90z7h+9teDnRGWYpquRRPaf9xH # +9/DUp/mBlXpnYzyOmJRvOwkDynUWICE5EV7WtgwggYaMIIEAqADAgECAhBiHW0M # UgGeO5B5FSCJIRwKMA0GCSqGSIb3DQEBDAUAMFYxCzAJBgNVBAYTAkdCMRgwFgYD # VQQKEw9TZWN0aWdvIExpbWl0ZWQxLTArBgNVBAMTJFNlY3RpZ28gUHVibGljIENv # ZGUgU2lnbmluZyBSb290IFI0NjAeFw0yMTAzMjIwMDAwMDBaFw0zNjAzMjEyMzU5 # NTlaMFQxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxKzAp # BgNVBAMTIlNlY3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBDQSBSMzYwggGiMA0G # CSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCbK51T+jU/jmAGQ2rAz/V/9shTUxjI # ztNsfvxYB5UXeWUzCxEeAEZGbEN4QMgCsJLZUKhWThj/yPqy0iSZhXkZ6Pg2A2NV # DgFigOMYzB2OKhdqfWGVoYW3haT29PSTahYkwmMv0b/83nbeECbiMXhSOtbam+/3 # 6F09fy1tsB8je/RV0mIk8XL/tfCK6cPuYHE215wzrK0h1SWHTxPbPuYkRdkP05Zw # mRmTnAO5/arnY83jeNzhP06ShdnRqtZlV59+8yv+KIhE5ILMqgOZYAENHNX9SJDm # +qxp4VqpB3MV/h53yl41aHU5pledi9lCBbH9JeIkNFICiVHNkRmq4TpxtwfvjsUe # dyz8rNyfQJy/aOs5b4s+ac7IH60B+Ja7TVM+EKv1WuTGwcLmoU3FpOFMbmPj8pz4 # 4MPZ1f9+YEQIQty/NQd/2yGgW+ufflcZ/ZE9o1M7a5Jnqf2i2/uMSWymR8r2oQBM # dlyh2n5HirY4jKnFH/9gRvd+QOfdRrJZb1sCAwEAAaOCAWQwggFgMB8GA1UdIwQY # MBaAFDLrkpr/NZZILyhAQnAgNpFcF4XmMB0GA1UdDgQWBBQPKssghyi47G9IritU # pimqF6TNDDAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADATBgNV # HSUEDDAKBggrBgEFBQcDAzAbBgNVHSAEFDASMAYGBFUdIAAwCAYGZ4EMAQQBMEsG # A1UdHwREMEIwQKA+oDyGOmh0dHA6Ly9jcmwuc2VjdGlnby5jb20vU2VjdGlnb1B1 # YmxpY0NvZGVTaWduaW5nUm9vdFI0Ni5jcmwwewYIKwYBBQUHAQEEbzBtMEYGCCsG # AQUFBzAChjpodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3RpZ29QdWJsaWNDb2Rl # U2lnbmluZ1Jvb3RSNDYucDdjMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0 # aWdvLmNvbTANBgkqhkiG9w0BAQwFAAOCAgEABv+C4XdjNm57oRUgmxP/BP6YdURh # w1aVcdGRP4Wh60BAscjW4HL9hcpkOTz5jUug2oeunbYAowbFC2AKK+cMcXIBD0Zd # OaWTsyNyBBsMLHqafvIhrCymlaS98+QpoBCyKppP0OcxYEdU0hpsaqBBIZOtBajj # cw5+w/KeFvPYfLF/ldYpmlG+vd0xqlqd099iChnyIMvY5HexjO2AmtsbpVn0OhNc # WbWDRF/3sBp6fWXhz7DcML4iTAWS+MVXeNLj1lJziVKEoroGs9Mlizg0bUMbOalO # hOfCipnx8CaLZeVme5yELg09Jlo8BMe80jO37PU8ejfkP9/uPak7VLwELKxAMcJs # zkyeiaerlphwoKx1uHRzNyE6bxuSKcutisqmKL5OTunAvtONEoteSiabkPVSZ2z7 # 6mKnzAfZxCl/3dq3dUNw4rg3sTCggkHSRqTqlLMS7gjrhTqBmzu1L90Y1KWN/Y5J # KdGvspbOrTfOXyXvmPL6E52z1NZJ6ctuMFBQZH3pwWvqURR8AgQdULUvrxjUYbHH # j95Ejza63zdrEcxWLDX6xWls/GDnVNueKjWUH3fTv1Y8Wdho698YADR7TNx8X8z2 # Bev6SivBBOHY+uqiirZtg0y9ShQoPzmCcn63Syatatvx157YK9hlcPmVoa1oDE5/ # L9Uo2bC5a4CH2RwwggZmMIIEzqADAgECAhEA4ikD7Bz5tV4p2sDA6k14ITANBgkq # hkiG9w0BAQwFADBUMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1p # dGVkMSswKQYDVQQDEyJTZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgQ0EgUjM2 # MB4XDTIyMDQxMTAwMDAwMFoXDTI1MDQxMDIzNTk1OVowUTELMAkGA1UEBhMCREsx # FDASBgNVBAgMC0hvdmVkc3RhZGVuMRUwEwYDVQQKDAxDVEdsb2JhbCBBL1MxFTAT # BgNVBAMMDENUR2xvYmFsIEEvUzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC # ggIBALo7Bkeh1fssdIJNGZ28+cH/K4trX84QLalEvjcu4UPFxS+gUy2djPuXqh1+ # Nr/PYDG047ZI08uQVF1onebKftvZC3BiEq7EwPUU6GBndD3mt3Q7V9BQfEPsZs+q # rgdCrWS4frWx3cCyAODqG3/b5omtwaPFdUX8ro2Rf4i8T8ddmAYfA4+qwpBvKP8A # ThfaVIOBpRfY0gvdqyXu4os5BJEbAvPyWCKlRWPrXLwcGsyN7HVlD1YjCyf4Paan # 5UMwHA44YclgPCmz6NThWUCH1b/LGzM7j0emCbq3jO7Z1UAnBkt7NrGfe7wjHIes # aSdNlIWhsfqUCSfO1xut7zjS+8goSYg4I2oyzF+QKP6fVWRAQDlOHpeXV1vk68vI # V9/UeUBJIyl0OQqaUKjk4kpwW9XHNWPz7VX32Q7Pm9GhCbwNvF7WgG22Jw2/IuF9 # JoVim8tLGVIQ2SKrJagsLrkEDyt7IOV7TKuljqIMfhe75WeAaAdfdZ0wCxcAXGis # rXWhY2TCx2Jfux80dt+isPvzRQH7pKvRMRnJlIJoICCb/9HR8SRfYOaDAfC62Nsb # J2C8JPgXxMaL+TDyz84i9mVv5DjX6s4tRNSGnHX+7FIMsXNm+bFAR3ZAUYNXUjAF # /Qzm+xwgtVl5sGQqtv9bmDmOSya1TLvq8GTldmKqdijV1EdJAgMBAAGjggG0MIIB # sDAfBgNVHSMEGDAWgBQPKssghyi47G9IritUpimqF6TNDDAdBgNVHQ4EFgQUjd9u # TSXhujdMkYFBibuhgRy3Rn8wDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAw # EwYDVR0lBAwwCgYIKwYBBQUHAwMwSgYDVR0gBEMwQTA1BgwrBgEEAbIxAQIBAwIw # JTAjBggrBgEFBQcCARYXaHR0cHM6Ly9zZWN0aWdvLmNvbS9DUFMwCAYGZ4EMAQQB # MEkGA1UdHwRCMEAwPqA8oDqGOGh0dHA6Ly9jcmwuc2VjdGlnby5jb20vU2VjdGln # b1B1YmxpY0NvZGVTaWduaW5nQ0FSMzYuY3JsMHkGCCsGAQUFBwEBBG0wazBEBggr # BgEFBQcwAoY4aHR0cDovL2NydC5zZWN0aWdvLmNvbS9TZWN0aWdvUHVibGljQ29k # ZVNpZ25pbmdDQVIzNi5jcnQwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLnNlY3Rp # Z28uY29tMCkGA1UdEQQiMCCBHml0YWRtaW5ka0BjdGdsb2JhbHNlcnZpY2VzLmNv # bTANBgkqhkiG9w0BAQwFAAOCAYEAeiTTMB3+8pbkqdiQFE7CJxlDUx3Yp44RjMGN # IocltTEccGHf4sMzuoLuP7MUT82snXD3avaGUsxXYeKZgxoGZbtwYf4eSBhdx23g # aNGA5t5VBTHYzpic2z5hYISGbYZXZoYjcpPL1gcZeCfPj0Vl+6w2UQ5ocseDHyOF # DtXlSTDxkyLY/eo+11u+01BM4KEH77LIWxnpOsm0nN4RJLkLzmckrrSSeFKOtCaP # 8i69Fy942+jURbuK2fgDLY8Bre8KhpCdKm5DMv6Z3iLswMvpVG7e38UeuAXl7T8i # JCMozgr8EYGFxcFzRzBEJrvk12neEojFi9J6TWh9UJDwFDgYfJhDm/Qy5XkIWnPM # 3vyl47ULFQlw6O5bBKwHmgi5+GSgBQXef0K0fImA4XT1CB8Vm5FUWsP9ZV07lBUX # Gs5onrau8ULB4JjEcB/+6BPrwBBoibYbZHAPIfqMZAhF117gH8eYrGbT0zdy9vUF # jWayEi/2vZRQgwSdeSI+v5cCpvTsMIIG7DCCBNSgAwIBAgIQMA9vrN1mmHR8qUY2 # p3gtuTANBgkqhkiG9w0BAQwFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5l # dyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNF # UlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh # dGlvbiBBdXRob3JpdHkwHhcNMTkwNTAyMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjB9 # MQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYD # VQQHEwdTYWxmb3JkMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxJTAjBgNVBAMT # HFNlY3RpZ28gUlNBIFRpbWUgU3RhbXBpbmcgQ0EwggIiMA0GCSqGSIb3DQEBAQUA # A4ICDwAwggIKAoICAQDIGwGv2Sx+iJl9AZg/IJC9nIAhVJO5z6A+U++zWsB21hoE # pc5Hg7XrxMxJNMvzRWW5+adkFiYJ+9UyUnkuyWPCE5u2hj8BBZJmbyGr1XEQeYf0 # RirNxFrJ29ddSU1yVg/cyeNTmDoqHvzOWEnTv/M5u7mkI0Ks0BXDf56iXNc48Ray # cNOjxN+zxXKsLgp3/A2UUrf8H5VzJD0BKLwPDU+zkQGObp0ndVXRFzs0IXuXAZSv # f4DP0REKV4TJf1bgvUacgr6Unb+0ILBgfrhN9Q0/29DqhYyKVnHRLZRMyIw80xSi # nL0m/9NTIMdgaZtYClT0Bef9Maz5yIUXx7gpGaQpL0bj3duRX58/Nj4OMGcrRrc1 # r5a+2kxgzKi7nw0U1BjEMJh0giHPYla1IXMSHv2qyghYh3ekFesZVf/QOVQtJu5F # GjpvzdeE8NfwKMVPZIMC1Pvi3vG8Aij0bdonigbSlofe6GsO8Ft96XZpkyAcSpcs # dxkrk5WYnJee647BeFbGRCXfBhKaBi2fA179g6JTZ8qx+o2hZMmIklnLqEbAyfKm # /31X2xJ2+opBJNQb/HKlFKLUrUMcpEmLQTkUAx4p+hulIq6lw02C0I3aa7fb9xhA # V3PwcaP7Sn1FNsH3jYL6uckNU4B9+rY5WDLvbxhQiddPnTO9GrWdod6VQXqngwID # AQABo4IBWjCCAVYwHwYDVR0jBBgwFoAUU3m/WqorSs9UgOHYm8Cd8rIDZsswHQYD # VR0OBBYEFBqh+GEZIA/DQXdFKI7RNV8GEgRVMA4GA1UdDwEB/wQEAwIBhjASBgNV # HRMBAf8ECDAGAQH/AgEAMBMGA1UdJQQMMAoGCCsGAQUFBwMIMBEGA1UdIAQKMAgw # BgYEVR0gADBQBgNVHR8ESTBHMEWgQ6BBhj9odHRwOi8vY3JsLnVzZXJ0cnVzdC5j # b20vVVNFUlRydXN0UlNBQ2VydGlmaWNhdGlvbkF1dGhvcml0eS5jcmwwdgYIKwYB # BQUHAQEEajBoMD8GCCsGAQUFBzAChjNodHRwOi8vY3J0LnVzZXJ0cnVzdC5jb20v # VVNFUlRydXN0UlNBQWRkVHJ1c3RDQS5jcnQwJQYIKwYBBQUHMAGGGWh0dHA6Ly9v # Y3NwLnVzZXJ0cnVzdC5jb20wDQYJKoZIhvcNAQEMBQADggIBAG1UgaUzXRbhtVOB # kXXfA3oyCy0lhBGysNsqfSoF9bw7J/RaoLlJWZApbGHLtVDb4n35nwDvQMOt0+Lk # VvlYQc/xQuUQff+wdB+PxlwJ+TNe6qAcJlhc87QRD9XVw+K81Vh4v0h24URnbY+w # QxAPjeT5OGK/EwHFhaNMxcyyUzCVpNb0llYIuM1cfwGWvnJSajtCN3wWeDmTk5Sb # sdyybUFtZ83Jb5A9f0VywRsj1sJVhGbks8VmBvbz1kteraMrQoohkv6ob1olcGKB # c2NeoLvY3NdK0z2vgwY4Eh0khy3k/ALWPncEvAQ2ted3y5wujSMYuaPCRx3wXdah # c1cFaJqnyTdlHb7qvNhCg0MFpYumCf/RoZSmTqo9CfUFbLfSZFrYKiLCS53xOV5M # 3kg9mzSWmglfjv33sVKRzj+J9hyhtal1H3G/W0NdZT1QgW6r8NDT/LKzH7aZlib0 # PHmLXGTMze4nmuWgwAxyh8FuTVrTHurwROYybxzrF06Uw3hlIDsPQaof6aFBnf6x # uKBlKjTg3qj5PObBMLvAoGMs/FwWAKjQxH/qEZ0eBsambTJdtDgJK0kHqv3sMNrx # py/Pt/360KOE2See+wFmd7lWEOEgbsausfm2usg1XTN2jvF8IAwqd661ogKGuinu # tFoAsYyr4/kKyVRd1LlqdJ69SK6YMIIG9TCCBN2gAwIBAgIQOUwl4XygbSeoZeI7 # 2R0i1DANBgkqhkiG9w0BAQwFADB9MQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl # YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRgwFgYDVQQKEw9TZWN0 # aWdvIExpbWl0ZWQxJTAjBgNVBAMTHFNlY3RpZ28gUlNBIFRpbWUgU3RhbXBpbmcg # Q0EwHhcNMjMwNTAzMDAwMDAwWhcNMzQwODAyMjM1OTU5WjBqMQswCQYDVQQGEwJH # QjETMBEGA1UECBMKTWFuY2hlc3RlcjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVk # MSwwKgYDVQQDDCNTZWN0aWdvIFJTQSBUaW1lIFN0YW1waW5nIFNpZ25lciAjNDCC # AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKSTKFJLzyeHdqQpHJk4wOcO # 1NEc7GjLAWTkis13sHFlgryf/Iu7u5WY+yURjlqICWYRFFiyuiJb5vYy8V0twHqi # DuDgVmTtoeWBIHIgZEFsx8MI+vN9Xe8hmsJ+1yzDuhGYHvzTIAhCs1+/f4hYMqsw # s9iMepZKGRNcrPznq+kcFi6wsDiVSs+FUKtnAyWhuzjpD2+pWpqRKBM1uR/zPeEk # yGuxmegN77tN5T2MVAOR0Pwtz1UzOHoJHAfRIuBjhqe+/dKDcxIUm5pMCUa9NLzh # S1B7cuBb/Rm7HzxqGXtuuy1EKr48TMysigSTxleGoHM2K4GX+hubfoiH2FJ5if5u # dzfXu1Cf+hglTxPyXnypsSBaKaujQod34PRMAkjdWKVTpqOg7RmWZRUpxe0zMCXm # loOBmvZgZpBYB4DNQnWs+7SR0MXdAUBqtqgQ7vaNereeda/TpUsYoQyfV7BeJUeR # dM11EtGcb+ReDZvsdSbu/tP1ki9ShejaRFEqoswAyodmQ6MbAO+itZadYq0nC/Ib # SsnDlEI3iCCEqIeuw7ojcnv4VO/4ayewhfWnQ4XYKzl021p3AtGk+vXNnD3MH65R # 0Hts2B0tEUJTcXTC5TWqLVIS2SXP8NPQkUMS1zJ9mGzjd0HI/x8kVO9urcY+VXvx # XIc6ZPFgSwVP77kv7AkTAgMBAAGjggGCMIIBfjAfBgNVHSMEGDAWgBQaofhhGSAP # w0F3RSiO0TVfBhIEVTAdBgNVHQ4EFgQUAw8xyJEqk71j89FdTaQ0D9KVARgwDgYD # VR0PAQH/BAQDAgbAMAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUH # AwgwSgYDVR0gBEMwQTA1BgwrBgEEAbIxAQIBAwgwJTAjBggrBgEFBQcCARYXaHR0 # cHM6Ly9zZWN0aWdvLmNvbS9DUFMwCAYGZ4EMAQQCMEQGA1UdHwQ9MDswOaA3oDWG # M2h0dHA6Ly9jcmwuc2VjdGlnby5jb20vU2VjdGlnb1JTQVRpbWVTdGFtcGluZ0NB # LmNybDB0BggrBgEFBQcBAQRoMGYwPwYIKwYBBQUHMAKGM2h0dHA6Ly9jcnQuc2Vj # dGlnby5jb20vU2VjdGlnb1JTQVRpbWVTdGFtcGluZ0NBLmNydDAjBggrBgEFBQcw # AYYXaHR0cDovL29jc3Auc2VjdGlnby5jb20wDQYJKoZIhvcNAQEMBQADggIBAEyb # ZVj64HnP7xXDMm3eM5Hrd1ji673LSjx13n6UbcMixwSV32VpYRMM9gye9YkgXsGH # xwMkysel8Cbf+PgxZQ3g621RV6aMhFIIRhwqwt7y2opF87739i7Efu347Wi/elZI # 6WHlmjl3vL66kWSIdf9dhRY0J9Ipy//tLdr/vpMM7G2iDczD8W69IZEaIwBSrZfU # YngqhHmo1z2sIY9wwyR5OpfxDaOjW1PYqwC6WPs1gE9fKHFsGV7Cg3KQruDG2PKZ # ++q0kmV8B3w1RB2tWBhrYvvebMQKqWzTIUZw3C+NdUwjwkHQepY7w0vdzZImdHZc # N6CaJJ5OX07Tjw/lE09ZRGVLQ2TPSPhnZ7lNv8wNsTow0KE9SK16ZeTs3+AB8LMq # SjmswaT5qX010DJAoLEZKhghssh9BXEaSyc2quCYHIN158d+S4RDzUP7kJd2KhKs # QMFwW5kKQPqAbZRhe8huuchnZyRcUI0BIN4H9wHU+C4RzZ2D5fjKJRxEPSflsIZH # KgsbhHZ9e2hPjbf3E7TtoC3ucw/ZELqdmSx813UfjxDElOZ+JOWVSoiMJ9aFZh35 # rmR2kehI/shVCu0pwx/eOKbAFPsyPfipg2I2yMO+AIccq/pKQhyJA9z1XHxw2V14 # Tu6fXiDmCWp8KwijSPUV/ARP380hHHrl9Y4a1LlAMYIGajCCBmYCAQEwaTBUMQsw # CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSswKQYDVQQDEyJT # ZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgQ0EgUjM2AhEA4ikD7Bz5tV4p2sDA # 6k14ITANBglghkgBZQMEAgEFAKCBhDAYBgorBgEEAYI3AgEMMQowCKACgAChAoAA # MBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgor # BgEEAYI3AgEVMC8GCSqGSIb3DQEJBDEiBCB1hiobMbzwB6HqPgZfvueHCfC2dl3L # ZNCI8CN/V3erBzANBgkqhkiG9w0BAQEFAASCAgAsdp0iDSzTZphDFfbmI4McFZaX # X/HGK/W42uHwCexw9F9wW2o8TtLhrbNk3XXrVUWVVjrgeMcBlXd33Iuf0lwmgRv7 # Z5yfYkCerr4Rn7fW+1ONBW3LfD4bNNiLG36rW4kiIpWDcR+nZZ2A+pXLLkr5JD3y # C20KFYoI032AVPuxvM6rCHnZqDX6wysYWbjcMi1AqmHpNHeSLEeid/IgtRMkCSOt # ROFMOAouPAi4xJHh9MMaQPSnaBUJEFnCy7hAcPxszWuiqn+e/RIUZqZanqGJRZ3T # W+vKG5qY9+JTRnFepguy+xOa+SV3+P6H2faV0UPObY2Tkw4bvRQUQk52csGr2yye # 8WdfwHYlxvSC9Cxx9pqj9FtQ5LcG2hw7F5TICVNxX9WYGbevmj8jh/tOJc0WnwX3 # dUvO/W9Ca6DmOWVqRl3YShG0bPSm2mDyMTCQW5lCCDrz5024L7ur5tuVYlZZVo10 # GTCA0JSpy+qK3BHu55Ud1JuRcLvIk6D/HYTg940XIAdLz3FRzVurhShpRItNxBHC # qIAYPbeZ/nUrw6/zr144SCIWH4Cn+RmwSbsAQCa/TcE0zFvKLP4PdxRPy0/Keqf0 # bICFCtDdAFb5AwL34SGbALxBwt/1KiFir4KgNR0nJhK695ZAMal4frovlBhwPVWG # APsa0xVEe0IK+46QdaGCA0swggNHBgkqhkiG9w0BCQYxggM4MIIDNAIBATCBkTB9 # MQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYD # VQQHEwdTYWxmb3JkMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxJTAjBgNVBAMT # HFNlY3RpZ28gUlNBIFRpbWUgU3RhbXBpbmcgQ0ECEDlMJeF8oG0nqGXiO9kdItQw # DQYJYIZIAWUDBAICBQCgeTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqG # SIb3DQEJBTEPFw0yMzEwMDMwODU3MTBaMD8GCSqGSIb3DQEJBDEyBDA6xiOD5dBJ # A+rYNZ5ujNZ1rGsydnUSfCQHQ6ffrpMOV5HVvS7p7/QjWit8bEgUgNswDQYJKoZI # hvcNAQEBBQAEggIATCUBihH6kAQqg+7uDheIJWIY6nR7mBqeudpnSJM4TwWTfSEB # /Xsfuu3CTsrr4M/72FhnMUeVYk+yBc7zMHkrqwCQzKZttH04wEjDe0OaKxlmOoF0 # dq4I1oyV9hJY8PSNujyUiAXj1XsyqN9RenVarwpd741j63dJJ6+1292azIgvsfWB # Wpf95UQemlfRL46YfJKu758CSh/8ByHSHoOK6PGgyuwrmrS/U5kLoQ26vDBC6ST5 # 3B9xod2/E6r+XaisC04ENlgyk4v75LWwt6lXafUsReZdUp7kdY9F5rc2l8wwWUTM # LjfsUkUkuxmmGaKEydhiSfQB9h5a2NoJdd92raEmNxrpczLapdINJ1SPPU+AXGwf # dPSolLxCpd74mDs3YhcuIljZolXmhsUnORY7msaqowSGKU1/fDYUpbdd3Rwcaptc # /WHEUZLDsvRX/zDDZgrgOhByecTeWBLaEJ3huZUzaf54tOmo2uJ4BsH7tQCgBXuY # V4gfIirloahDO4XR+21EgQYnOC5GvfRYDrGgV7EZsjpfmWBU2vTji+OwZAR9d1h1 # zYVqh9S22d2JM9qLtEZJ3El6WKuKUHTwqlyxlqUJuP9OZNe1K9HIek10vYTarZ1d # oF7nt2yRBQf7yah+5+cKcjjcxeegHOd28a0CDhpltpcymq+aG1a9hvFjZ0s= # SIG # End signature block |