ServerHealth.psm1
<#
Copyright Microsoft Corporation. All rights reserved. Licensed under the MIT License. #> Set-StrictMode -Version Latest Import-LocalizedData -BindingVariable message -ErrorAction Stop $versionId = '1.0.2.1810' $controlId = @{ Start = 'start'; Stop = 'stop'; Cancel = 'cancel' } <# .Synopsis Captures a performance trace on a Windows Server system using the Windows Performance Recorder. .Description The Trace-Performance cmdlet captures a performance trace on a Windows Server system by utilizing the Windows Performance Recorder. The cmdlet supports using either a time-based capture or can be controlled manually by specifying both start and stop options. The default capture uses a time-based method. The captured trace can be used to understand performance problems. .Parameter Profile Specifies the name of the profile to use to capture a performance trace. If this parameter is omitted, the Trace-Performance cmdlet uses the General profile. .Parameter Duration Specifies the duration in seconds that the performance trace should be captured. If this parameter is omitted, a default period of 30 seconds is used. .Parameter Detail Specifies the level of detail that the performance trace should capture. If this parameter is omitted, the level of detail is set to Low. Use caution when selecting a higher level as it may have a performance impact. .Parameter Mode Specifies the recording mode that is used to capture the performance trace. The cmdlet supports both Memory and File modes. If this parameter is omitted, the default is Memory mode. .Parameter Start Starts a performance trace on a Windows Server system using the Windows Performance Recorder. .Parameter Stop Stops capturing a Windows Server performance trace. .Inputs None .Outputs System.IO.FileInfo An object that represents a captured trace is returned if a time-based capture or a manual stop is specified. .Example C:\PS> Trace-Performance Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 6/2/2018 8:00 AM 1070138 TracePerformance{546F937E-923D-57E7-7BE3-135DC4C3EF38}.etl This example uses the General profile to capture a 30-second performance trace. .Example C:\PS> Trace-Performance -Profile Networking -Duration 10 -Detail High Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 6/2/2018 8:00 AM 1866958 TracePerformance{546F937E-923D-57E7-7BE3-135DC4C3EF38}.etl This example uses the Networking profile with a High level of detail to capture a 10-second performance trace. .Example C:\PS> Trace-Performance -Profile Storage -Start This example starts a manual performance trace that uses the Storage profile. .Example C:\PS> Trace-Performance -Stop Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 6/2/2018 8:00 AM 986283 TracePerformance{546F937E-923D-57E7-7BE3-135DC4C3EF38}.etl This example stops a manually initiated performance trace. .Link https://go.microsoft.com/fwlink/?linkid=2009254 #> function Trace-Performance { [CmdletBinding(DefaultParameterSetName = 'Trace')] [OutputType([System.IO.FileInfo], ParameterSetName = 'Stop')] [OutputType([System.IO.FileInfo], ParameterSetName = 'Trace')] [OutputType('None', ParameterSetName = 'Start')] Param ( [Parameter(ParameterSetName = 'Trace')] [Parameter(ParameterSetName = 'Start')] [ValidateSet('Custom', 'General', 'Networking', 'Storage')] [string]$Profile = 'General', [Parameter(ParameterSetName = 'Trace')] [ValidateRange(1, 300)] [int]$Duration = 30, [Parameter(ParameterSetName = 'Trace')] [Parameter(ParameterSetName = 'Start')] [ValidateSet('Low', 'High')] [string]$Detail = 'Low', [Parameter(ParameterSetName = 'Trace')] [Parameter(ParameterSetName = 'Start')] [ValidateSet('File', 'Memory')] [string]$Mode = 'Memory', [Parameter(ParameterSetName = 'Start', Mandatory = $true)] [switch]$Start, [Parameter(ParameterSetName ='Stop', Mandatory = $true)] [switch]$Stop ) $recorderProcess = Get-Command -Name 'wpr.exe' -ErrorAction SilentlyContinue if ($recorderProcess -eq $null) { throw $message.RecorderNotInstalled } if ($recorderProcess.FileVersionInfo.FileMajorPart -lt 10) { throw $message.IncorrectRecorderVersion } if (-not (Test-IsAdministrator)) { throw $message.InsufficientPrivileges } $settings = Get-TraceProfileParameters -TraceType 'TracePerformance' -ProfileName $Profile $parameters = $settings.RecorderParameters try { if ($PSCmdlet.ParameterSetName -eq 'Start' -or $PSCmdlet.ParameterSetName -eq 'Trace') { $null = Control-WindowsRecorder -Action $controlId.Cancel -Status $message.ResettingRecorder ` -PercentComplete 0 } } catch { throw $message.UnableToLaunchRecorder } try { if ($PSCmdlet.ParameterSetName -eq 'Start' -or $PSCmdlet.ParameterSetName -eq 'Trace') { $offset = @{ $true = 100 / ($Duration + 1); $false = 100 }[$PSCmdlet.ParameterSetName -eq 'Trace'] $completedTracing = $false $startedTracing = Control-WindowsRecorder -Action $controlId.Start -Status $message.StartingRecorder ` -PercentComplete $offset -Parameters $parameters if ($PSCmdlet.ParameterSetName -eq 'Trace' -and $startedTracing) { Wait-ForDuration -Duration $Duration -Status $message.TracingPerformance $completedTracing = $true } } } finally { if ($PSCmdlet.ParameterSetName -eq 'Stop' -or $PSCmdlet.ParameterSetName -eq 'Trace') { if ($PSCmdlet.ParameterSetName -eq 'Stop' -or $completedTracing -eq $true) { $parameters = Get-RecorderParameters $settings.TraceFile $null = Control-WindowsRecorder -Action $controlId.Stop -Status $message.StoppingRecorder ` -PercentComplete 100 -Parameters $parameters } else { $null = Control-WindowsRecorder -Action $controlId.Cancel -Status $message.CancelingRecorder ` -PercentComplete 100 } } } if ($PSCmdlet.ParameterSetName -eq 'Stop' -or $PSCmdlet.ParameterSetName -eq 'Trace') { if (Test-Path -Path $settings.TraceFile) { return [System.IO.FileInfo]$settings.TraceFile } throw $message.UnableToRecordCapture } } function Get-TraceProfileParameters($traceType, $profileName) { $traceFile = Get-TraceName -TraceType $traceType $traceProfile = Get-TraceProfile -ProfileName $profileName $recorderParameters = '"' + (Get-RecorderProfile -TraceProfile $traceProfile) + '"' if ($Mode -eq 'File') { $recorderParameters += ' -filemode' } return @{ TraceFile = $traceFile; RecorderParameters = $recorderParameters } } function Get-TraceProfile($profileName) { $traceProfile = Get-TraceProfileContent -ProfileName $profileName if ($traceProfile.Performance.EventTracing -eq $null) { throw $message.MalformedProfile } return $traceProfile } function Get-TraceProfileContent($profileName) { $profilePath = Get-TraceProfilePath -ProfileName $profileName $content = Get-Content -Path $profilePath -Raw -ErrorAction Stop return & ([ScriptBlock]::Create($content)) } function Get-TraceName($traceType) { $traceFile = "$traceType{$([Guid]::NewGuid().ToString().ToUpper())}.etl" return Join-Path -Path (Convert-Path -Path '.') -ChildPath $traceFile } function Get-TraceProfilePath($profileName) { return Join-Path -Path $PSScriptRoot -ChildPath "Profile-$profileName.ps1" } function Get-RecorderParameters($traceFile) { $marker = @{ $true = 'M' ; $false = $Duration }[$PSCmdlet.ParameterSetName -eq 'Stop'] return '"' + $traceFile + '"' + ' ' + ($message.TelemetryRecorderMarker -f $versionId, $marker) } function Get-RecorderProfile($traceProfile) { $recorderProfile = Join-Path -Path $PSScriptRoot -ChildPath $traceProfile.Performance.EventTracing return $recorderProfile + @{ $true = '.Light' ; $false = '.Verbose' }[$Detail -eq 'Low'] } function Control-WindowsRecorder($action, $status, $percentComplete, $parameters = $null) { $startInfo = New-Object -TypeName System.Diagnostics.ProcessStartInfo $startInfo.FileName = $recorderProcess.Name $startInfo.Arguments = '-' + $action + ' ' + $parameters $startInfo.RedirectStandardError = $true $startInfo.UseShellExecute = $false Update-Progress -Status $status -PercentComplete $percentComplete return Start-WindowsRecorder -StartInfo $startInfo } function Start-WindowsRecorder($startInfo) { $process = New-Object -TypeName System.Diagnostics.Process $process.StartInfo = $startInfo $process.Start() $process.WaitForExit() if ($process.ExitCode -eq 0) { return $true } return $false } function Test-IsAdministrator { return ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()). ` IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) } function Update-Progress($status, $percentComplete) { Write-Progress -Activity $message.WindowsServerDiagnosticsPerformance -Status $status ` -PercentComplete $percentComplete } function Wait-ForDuration($duration, $status) { for ($i = 1; $i -ne $duration; $i++) { $interval = 100 / ($duration + 1) Update-Progress -Status $status -PercentComplete ($i * $interval + $interval) Start-Sleep -Seconds 1 } } Export-ModuleMember -Function Trace-Performance # SIG # Begin signature block # MIIkmgYJKoZIhvcNAQcCoIIkizCCJIcCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCC0H0kefQhOisoR # o76vmbFZFyP9NEMRs7JuQoH5quQEa6CCDYEwggX/MIID56ADAgECAhMzAAABA14l # HJkfox64AAAAAAEDMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p # bmcgUENBIDIwMTEwHhcNMTgwNzEyMjAwODQ4WhcNMTkwNzI2MjAwODQ4WjB0MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB # AQDRlHY25oarNv5p+UZ8i4hQy5Bwf7BVqSQdfjnnBZ8PrHuXss5zCvvUmyRcFrU5 # 3Rt+M2wR/Dsm85iqXVNrqsPsE7jS789Xf8xly69NLjKxVitONAeJ/mkhvT5E+94S # nYW/fHaGfXKxdpth5opkTEbOttU6jHeTd2chnLZaBl5HhvU80QnKDT3NsumhUHjR # hIjiATwi/K+WCMxdmcDt66VamJL1yEBOanOv3uN0etNfRpe84mcod5mswQ4xFo8A # DwH+S15UD8rEZT8K46NG2/YsAzoZvmgFFpzmfzS/p4eNZTkmyWPU78XdvSX+/Sj0 # NIZ5rCrVXzCRO+QUauuxygQjAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUR77Ay+GmP/1l1jjyA123r3f3QP8w # UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1 # ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDM3OTY1MB8GA1UdIwQYMBaAFEhu # ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu # bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w # Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3 # Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx # MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAn/XJ # Uw0/DSbsokTYDdGfY5YGSz8eXMUzo6TDbK8fwAG662XsnjMQD6esW9S9kGEX5zHn # wya0rPUn00iThoj+EjWRZCLRay07qCwVlCnSN5bmNf8MzsgGFhaeJLHiOfluDnjY # DBu2KWAndjQkm925l3XLATutghIWIoCJFYS7mFAgsBcmhkmvzn1FFUM0ls+BXBgs # 1JPyZ6vic8g9o838Mh5gHOmwGzD7LLsHLpaEk0UoVFzNlv2g24HYtjDKQ7HzSMCy # RhxdXnYqWJ/U7vL0+khMtWGLsIxB6aq4nZD0/2pCD7k+6Q7slPyNgLt44yOneFuy # bR/5WcF9ttE5yXnggxxgCto9sNHtNr9FB+kbNm7lPTsFA6fUpyUSj+Z2oxOzRVpD # MYLa2ISuubAfdfX2HX1RETcn6LU1hHH3V6qu+olxyZjSnlpkdr6Mw30VapHxFPTy # 2TUxuNty+rR1yIibar+YRcdmstf/zpKQdeTr5obSyBvbJ8BblW9Jb1hdaSreU0v4 # 6Mp79mwV+QMZDxGFqk+av6pX3WDG9XEg9FGomsrp0es0Rz11+iLsVT9qGTlrEOla # P470I3gwsvKmOMs1jaqYWSRAuDpnpAdfoP7YO0kT+wzh7Qttg1DO8H8+4NkI6Iwh # SkHC3uuOW+4Dwx1ubuZUNWZncnwa6lL2IsRyP64wggd6MIIFYqADAgECAgphDpDS # AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK # V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0 # IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0 # ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla # MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS # ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT # H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB # AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG # OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S # 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz # y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7 # 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u # M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33 # X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl # XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP # 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB # l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF # RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM # CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ # BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud # DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO # 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0 # LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y # Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p # Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y # Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB # FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw # cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA # XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY # 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj # 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd # d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ # Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf # wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ # aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j # NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B # xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96 # eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7 # r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I # RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIWbzCCFmsCAQEwgZUwfjELMAkG # A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx # HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z # b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAQNeJRyZH6MeuAAAAAABAzAN # BglghkgBZQMEAgEFAKCB1jAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor # BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQghr039oZd # KMMScZFZHu0BDBhGOzfyakq2XST7Y5sEwnEwagYKKwYBBAGCNwIBDDFcMFqgPoA8 # AFMAZQByAHYAZQByAEgAZQBhAGwAdABoACAAUABvAHcAZQByAFMAaABlAGwAbAAg # AE0AbwBkAHUAbABloRiAFmh0dHBzOi8vbWljcm9zb2Z0LmNvbSAwDQYJKoZIhvcN # AQEBBQAEggEAuxzo8x0UhYn0fZuK0IqDZNAmYquOSZGKB7SBZ13z114n3AinmocQ # iC7yqWSuRStGFeNhEUZJYrhfTGRsAgqrhpaPPFTCASYTPB3bPJovb4a3bnG188aS # LRarzQhw6VTMNZa1bsGrhyQvlgfxknpsmdBj7Ys4LlcnO3GYO9FoPbMB7+Xd6xh3 # r87gIi65lQgpi6XjpxENsUbuFfg7Y+WduHerGsSK9lDcXXE+nAZOiQexzBkCxLzq # gFrHtiz1HZ+nWS4m94NdeufdT+yQoVGbeBeEYmnWnZHu1zIan7KCmDKY8brrFfxm # f1iJ420GL69PjzXHOc4SsxVOGiphLoMmQ6GCE9EwghPNBgorBgEEAYI3AwMBMYIT # vTCCE7kGCSqGSIb3DQEHAqCCE6owghOmAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFX # BgsqhkiG9w0BCRABBKCCAUYEggFCMIIBPgIBAQYKKwYBBAGEWQoDATAxMA0GCWCG # SAFlAwQCAQUABCC4ljPTM7k+RSYn27DMjgRDux/sL+R9rn6g0Z4rVHszXwIGW60D # 90mMGBIyMDE4MTAwMzA1MTQ1OS4zMlowBwIBAYACAfSggdSkgdEwgc4xCzAJBgNV # BAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4w # HAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29m # dCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVT # Tjo5OEZELUM2MUUtRTY0MTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAg # U2VydmljZaCCDyIwggT1MIID3aADAgECAhMzAAAAy194yyMOlJfDAAAAAADLMA0G # CSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u # MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp # b24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMB4XDTE4 # MDgyMzIwMjYyNFoXDTE5MTEyMzIwMjYyNFowgc4xCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25z # IFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo5OEZELUM2MUUt # RTY0MTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZTCCASIw # DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMV4yB3v8B1BcBxtNEo/VALKGniz # A1WCEIU22DCpyy838O0VlW7D3KUomZPIU3nsx3MxaQXpai0OiVs+DPuHqdoKtsuY # CaMxeDHhodCgPWdPT9NN0hngnC07R2nDB2NhvtRBpr4V36791Pqi3CssKDdLjBrO # QUhqEn8S0VP5xldDQPfMIpqRFQdP6Ut4dvaI/Mva5e86HbawJxdGKrTdHp7LOae3 # YHX25khbhuNatqp3dDu3Do6xDE1BIa2GuUGZa4oHVNwWIWk3SZ4xZlarT3eAi712 # yWyeTrjGv56Ryje8yDiBtd+1UCn67t0TwQpTa+a2ZPP2v8HyQxQegc+9ThUCAwEA # AaOCARswggEXMB0GA1UdDgQWBBQo5PLm9snRTa5uyNsqlr8xw/vZdjAfBgNVHSME # GDAWgBTVYzpcijGQ80N7fEYbxTNoWoVtVTBWBgNVHR8ETzBNMEugSaBHhkVodHRw # Oi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNUaW1TdGFQ # Q0FfMjAxMC0wNy0wMS5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5o # dHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1RpbVN0YVBDQV8y # MDEwLTA3LTAxLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMI # MA0GCSqGSIb3DQEBCwUAA4IBAQCL9GGFgwVibMsUlJfD6SUDbHKxL9pN6ZYMg+aO # TE8AyCh9oD6HcuinUjkj6afQU63TvgVRWExYJLzrQBysAh2GgbGkKIPtdV6yQQMl # JxclXpR48t1jS1VvBX0KksR5Bq/4/0e58+jXvUaU2JcUQVw3lHn9I/YtQJeuAvnN # fLENxJKE3A7FOjOAw+fEH49OGK1IBR9yhXS+r6HslFuFLfjK7DU89+Cu1zAg9JTC # CrqlWSydWApAYh/ACInONLHHp9OZdilC42zGjB8Ro/07YqMAjPhK7Ze12lWThiZI # Fqc5fZTxCi3L2T8pQI91/Nxu4CnpIzLXUwSXUxkIpfSNsK7OMIIGcTCCBFmgAwIB # AgIKYQmBKgAAAAAAAjANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzAR # BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p # Y3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2Vy # dGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMTAwNzAxMjEzNjU1WhcNMjUwNzAx # MjE0NjU1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4G # A1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYw # JAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCASIwDQYJKoZI # hvcNAQEBBQADggEPADCCAQoCggEBAKkdDbx3EYo6IOz8E5f1+n9plGt0VBDVpQoA # goX77XxoSyxfxcPlYcJ2tz5mK1vwFVMnBDEfQRsalR3OCROOfGEwWbEwRA/xYIiE # VEMM1024OAizQt2TrNZzMFcmgqNFDdDq9UeBzb8kYDJYYEbyWEeGMoQedGFnkV+B # VLHPk0ySwcSmXdFhE24oxhr5hoC732H8RsEnHSRnEnIaIYqvS2SJUGKxXf13Hz3w # V3WsvYpCTUBR0Q+cBj5nf/VmwAOWRH7v0Ev9buWayrGo8noqCjHw2k4GkbaICDXo # eByw6ZnNPOcvRLqn9NxkvaQBwSAJk3jN/LzAyURdXhacAQVPIk0CAwEAAaOCAeYw # ggHiMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBTVYzpcijGQ80N7fEYbxTNo # WoVtVTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYD # VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvXzpoYxDBW # BgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2Ny # bC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYIKwYBBQUH # AQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtp # L2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDCBoAYDVR0gAQH/BIGV # MIGSMIGPBgkrBgEEAYI3LgMwgYEwPQYIKwYBBQUHAgEWMWh0dHA6Ly93d3cubWlj # cm9zb2Z0LmNvbS9QS0kvZG9jcy9DUFMvZGVmYXVsdC5odG0wQAYIKwYBBQUHAgIw # NB4yIB0ATABlAGcAYQBsAF8AUABvAGwAaQBjAHkAXwBTAHQAYQB0AGUAbQBlAG4A # dAAuIB0wDQYJKoZIhvcNAQELBQADggIBAAfmiFEN4sbgmD+BcQM9naOhIW+z66bM # 9TG+zwXiqf76V20ZMLPCxWbJat/15/B4vceoniXj+bzta1RXCCtRgkQS+7lTjMz0 # YBKKdsxAQEGb3FwX/1z5Xhc1mCRWS3TvQhDIr79/xn/yN31aPxzymXlKkVIArzgP # F/UveYFl2am1a+THzvbKegBvSzBEJCI8z+0DpZaPWSm8tv0E4XCfMkon/VWvL/62 # 5Y4zu2JfmttXQOnxzplmkIz/amJ/3cVKC5Em4jnsGUpxY517IW3DnKOiPPp/fZZq # kHimbdLhnPkd/DjYlPTGpQqWhqS9nhquBEKDuLWAmyI4ILUl5WTs9/S/fmNZJQ96 # LjlXdqJxqgaKD4kWumGnEcua2A5HmoDF0M2n0O99g/DhO3EJ3110mCIIYdqwUB5v # vfHhAN/nMQekkzr3ZUd46PioSKv33nJ+YWtvd6mBy6cJrDm77MbL2IK0cs0d9LiF # AR6A+xuJKlQ5slvayA1VmXqHczsI5pgt6o3gMy4SKfXAL1QnIffIrE7aKLixqduW # sqdCosnPGUFN4Ib5KpqjEWYw07t0MkvfY3v1mYovG8chr1m1rtxEPJdQcdeh0sVV # 42neV8HR3jDA/czmTfsNv11P6Z0eGTgvvM9YBS7vDaBQNdrvCScc1bN+NR4Iuto2 # 29Nfj950iEkSoYIDsDCCApgCAQEwgf6hgdSkgdEwgc4xCzAJBgNVBAYTAlVTMRMw # EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN # aWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRp # b25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo5OEZELUM2 # MUUtRTY0MTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZaIl # CgEBMAkGBSsOAwIaBQADFQC5o5PSQHbRtx8VowRRl644K9uaIaCB3jCB26SB2DCB # 1TELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl # ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEpMCcGA1UECxMg # TWljcm9zb2Z0IE9wZXJhdGlvbnMgUHVlcnRvIFJpY28xJzAlBgNVBAsTHm5DaXBo # ZXIgTlRTIEVTTjo1N0Y2LUMxRTAtNTU0QzErMCkGA1UEAxMiTWljcm9zb2Z0IFRp # bWUgU291cmNlIE1hc3RlciBDbG9jazANBgkqhkiG9w0BAQUFAAIFAN9eynAwIhgP # MjAxODEwMDMxMjU2MTZaGA8yMDE4MTAwNDEyNTYxNlowdzA9BgorBgEEAYRZCgQB # MS8wLTAKAgUA317KcAIBADAKAgEAAgIgYAIB/zAHAgEAAgIXeDAKAgUA32Ab8AIB # ADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMBoAowCAIBAAIDFuNgoQow # CAIBAAIDB6EgMA0GCSqGSIb3DQEBBQUAA4IBAQCWROM4SMFaudr63nyjsrU/QiuX # r0+kvird8m4QPiw3UoGOXYDzrXl7mWH6PYvK+6V9iXo650Bo6HSInst2FG/kQrCo # hRHolKXi7yq1QgNCk+U7QRoLMbtdNFH4L8KJSm78z6eX+rAsrjaRcWNS4wJCgv/+ # Iv9aAOMUqYDYmj4njEmAC0huGyL1D+8Mm6mmjsJpBmzP/Ma9Efe+Lt9C2bc0LcnX # mBMn0xqWwWGinHZixUxFmqkC+tnMfDtfAtfqOZg77RD3541J/I2Vhu5bDLJUyn+N # Kdpqwk9wVngZPQVTmef9kUa+uilI6BlmV4DOwXIfXfwPBc1bVo+F7sBz2HGIMYID # DTCCAwkCAQEwgZMwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x # EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv # bjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAADL # X3jLIw6Ul8MAAAAAAMswDQYJYIZIAWUDBAIBBQCgggFKMBoGCSqGSIb3DQEJAzEN # BgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQxIgQgjdhAlLQ8VB3r7sPRtpp/lHX6 # abuORfXDvhmHURO+et8wgfoGCyqGSIb3DQEJEAIvMYHqMIHnMIHkMIG9BCA2JyGq # qWCnXutz0KS9S3wuF/afS9Mu7hRHXqpg3cEdZDCBmDCBgKR+MHwxCzAJBgNVBAYT # AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBU # aW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAAy194yyMOlJfDAAAAAADLMCIEIH314Hks # ZDboOtk5s0e/+Bhl/Gcqs7SojFcikG6Nf63uMA0GCSqGSIb3DQEBCwUABIIBAGN/ # fS6Za8ANJe//StYeB+7oPWME1dsGuEs0zeiGRYLTed1QqM0Nq1pwmnHI7DSI2BQS # hgh5aqu6+kOr3KTbJ3dp0jJfTHFM2PMQBvdomJYSv1FtrFumC3+FazwbFNenzlsw # vlAqMk6H4YFCQzJKyw+ihyXdnMrb6Fu80Rztp9O/LF4PBkFSQgo4mt1euslt/RTQ # YQ2c3RQSY7gjOezjKDokBDmcJs8pMtUoIXncBUK8/TT9XhJ4DpIsq3LpN9/l5aFs # GL7UmwpkBKlP6718J4uTQ+29yNzO4JNzK350fN6tunriqopnE0azu/QsIoRxGJdH # irytMBFIMYuyzIzvJMk= # SIG # End signature block |