ozo-windows-event-log-provider-setup.ps1

#Requires -RunAsAdministrator

<#PSScriptInfo
    .VERSION 1.0.0
    .GUID 0e6ba28d-02be-4527-9412-bc0547b1a2be
    .AUTHOR Andy Lievertz <alievertz@onezeroone.dev>
    .COMPANYNAME One Zero One
    .COPYRIGHT This script is released under the terms of the GNU General Public License ("GPL") version 2.0.
    .TAGS
    .LICENSEURI https://github.com/onezeroone-dev/OZO-Windows-Event-Log-Provider-Setup/blob/main/LICENSE
    .PROJECTURI https://github.com/onezeroone-dev/OZO-Windows-Event-Log-Provider-Setup
    .ICONURI
    .EXTERNALMODULEDEPENDENCIES
    .REQUIREDSCRIPTS
    .EXTERNALSCRIPTDEPENDENCIES
    .RELEASENOTES https://github.com/onezeroone-dev/OZO-Windows-Event-Log-Provider-Setup/blob/main/CHANGELOG.md
    .PRIVATEDATA
#>


<#
    .SYNOPSIS
    See description.
    .DESCRIPTION
    A non-interactive script that creates a "One Zero One" Windows event log provider. Implementing this provider supports the optimal use of the New-OZOLogger function (available in the OZOLogger PowerShell Module).
    .PARAMETER Remove
    Removes the "One Zero One" provider.
    .LINK
    https://github.com/onezeroone-dev/OZO-Windows-Event-Log-Provider-Setup/blob/main/README.md
    .NOTES
    This script requires an x86 or x64 processor.
#>
 
[CmdletBinding(SupportsShouldProcess = $true)]
param (
    [Parameter(HelpMessage='Removes the "One Zero One" provider')][Switch]$Remove
)

# CLASSES
Class OZOESConfiguration {
    # PROPERTIES
    [Array]   $channelNames    = $null
    [Array]   $installModules  = $null
    [Boolean] $dllChanged      = $true
    [Boolean] $manifestChanged = $true
    [Boolean] $providerExists  = $true
    [Boolean] $Validates       = $true
    [Int16]   $processorArch   = $null
    [String]  $dllBase64       = $null
    [String]  $dllx86Base64    = $null
    [String]  $dllx64Base64    = $null
    [String]  $manifestXML     = $null
    [String]  $providerName    = $null
    [String]  $ozoEventLogDir  = $null
    [String]  $dllPath         = $null
    [String]  $manifestPath    = $null
    [String]  $wEvtUtilPath    = $null
    # METHODS
    # Constructor method
    OZOESConfiguration($dllx86Base64,$dllx64Base64,$manifestXML) {
        # Set properties
        $this.channelNames   = @("Operational")
        $this.installModules = @("OZOLogger")
        $this.processorArch  = (Get-CimInstance -ClassName CIM_Processor).Architecture
        $this.dllx86Base64   = $dllx86Base64
        $this.dllx64Base64   = $dllx64Base64
        $this.manifestXML    = $manifestXML
        $this.providerName   = "One Zero One"
        $this.ozoEventLogDir = (Join-Path -Path $Env:ProgramFiles -ChildPath (Join-Path -Path $this.providerName -ChildPath "OZO-Windows-Event-Log-Provider"))
        $this.dllPath        = (Join-Path -Path $this.ozoEventLogDir -ChildPath "ozo-messages.dll")
        $this.manifestPath   = (Join-Path -Path $this.ozoEventLogDir -ChildPath "ozo-messages.man")
        $this.wEvtUtilPath   = (Join-Path -Path $Env:windir -ChildPath (Join-Path -Path "System32" -ChildPath "wevtutil.exe"))
        # Call ValidateEnvironment to set Validates
        If ($this.ValidateEnvironment() -eq $true) {
            # Environment validated
            Write-OZOProvider -Message "Environment validated." -Level "Information"
            $this.Validates = $true
            # Inspect the DLL and manifest for changes
            $this.dllChanged      = $this.InspectDLL()
            $this.manifestChanged = $this.InspectManifest()
        } Else {
            # Environment did not validate
            Write-OZOProvider -Message "Environment did not validate." -Level "Error"
            $this.Validates = $false
        }
    }
    # Environment validation method
    Hidden [Boolean] ValidateEnvironment() {
        [Boolean] $Return = $true
        # Try to get the provider (detemine if it exists)
        Try {
            Get-WinEvent -ListProvider $this.providerName -ErrorAction Stop
            # Success
            Write-OZOProvider -Message "Provider exists." -Level "Information"
        } Catch {
            # Failure
            Write-OZOProvider -Message "Provider does not exist." -Level "Information"
            $this.providerExists = $false
        }
        # Determine if processor architecture is supported; see https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-processor to translate processor architectures to the relevant Int16
        If ($this.processorArch -eq 0) {
            # Processor is x86
            $this.dllBase64 = $this.dllx86Base64
        } ElseIf ($this.processorArch -eq 9) {
            # Processor is x64
            $this.dllBase64 = $this.dllx64Base64
        } Else {
            # Processor architecture is not supported
            Write-OZOProvider -Message "Processor is not supported." -Level "Error"
            $Return = $false
        }
        # Return
        return $Return
    }
    # DLL inspection method
    Hidden [Boolean] InspectDLL() {
        [Boolean] $Return = $true
        # Determine if the DLL exists
        If ((Test-Path -Path $this.dllPath) -eq $true) {
            # DLL exists
            Write-OZOProvider -Message "DLL exists." -Level "Information"
            # Determine if there are differences between the DLLs
            If ((Compare-Object -ReferenceObject $this.dllBase64 -DifferenceObject ([System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes($this.dllPath)))) -eq $true) {
                # Differences
                Write-OZOProvider -Message "There are differences between the DLLs." -Level "Information"
            } Else {
                # No differences
                Write-OZOProvider -Message "The DLL has not changed." -Level "Information"
                $Return = $false
            }
        } Else {
            # DLL does not exist
            Write-OZOProvider -Message "DLL does not exist." -Level "Information"
        }
        # Return
        return $Return
    }
    # Manifest inspection method
    Hidden [Boolean] InspectManifest() {
        [Boolean] $Return = $true
        # Determine if the manifest exists
        If ((Test-Path -Path $this.manifestPath) -eq $true) {
            # Manifest exists
            Write-OZOProvider -Message "Manifest exists." -Level "Information"
            # Determine if there are differences between the manifests
            If ((Compare-Object -ReferenceObject $this.manifestXML -DifferenceObject (Get-Content -Path $this.manifestPath)) -eq $true) {
                # Differences
                Write-OZOProvider -Message "There are differences between the manifests." -Level "Information"
            } Else {
                # No differences
                Write-OZOProvider -Message "The manifest has not changed." -Level "Information"
                $Return = $false
            }
        } Else {
            # Manifest does not exist
            Write-OZOProvider -Message "Manifest does not exist." -Level "Information"
        }
        # Return
        return $Return
    }
}

Class OESMain {
    # METHODS
    # Constructor method
    OESMain($Remove) {
        # Determine if we are removing, updating, or adding
        If ($Global:oesConfiguration.providerExists -eq $true -And $Remove -eq $true) {
            # Log exists and operator requested remove; call RemoveProvider
            $this.RemoveProvider()
            Write-OZOProvider -Message "Provider removed." -Level "Information"
        } ElseIf ($Global:oesConfiguration.providerExists -eq $true -And ($Global:oesConfiguration.dllChanged -Or $Global:oesConfiguration.manifestChanged) -eq $true) {
            # Log exists and the DLL or manifest has changed; call RemoveProvider + AddProvider + InstallModules
            $this.RemoveProvider()
            $this.AddProvider()
            $this.InstallModules()
            Write-OZOProvider -Message "Thank you for updating the One Zero One Windows event log provider." -Level "Information"
        } ElseIf ($Global:oesConfiguration.providerExists -eq $false) {
            # Log does not exist; call AddProvider + InstallModules
            $this.AddProvider()
            $this.InstallModules()
            Write-OZOProvider -Message "Thank you for installing the One Zero One Windows event log provider." -Level "Information"
        } ElseIf ($Global:oesConfiguration.providerExists -eq $true -And ($Global:oesConfiguration.dllChanged -And $Global:oesConfiguration.manifestChanged) -eq $false) {
            Write-OZOProvider -Message "Provider exists and the configuration has not changed; skipping." -Level "Information"
        } Else {
            # No conditions matched
            Write-OZOProvider -Message "No conditions matched." -Level "Warning"
        }
    }
    # Remove provider method
    Hidden [Void] RemoveProvider() {
        Write-OZOProvider -Message "Removing provider." -Level "Information"
        # Determine that manifest exists
        If ((Test-Path -Path $Global:oesConfiguration.manifestPath) -eq $false) {
            # Manifest does not exist; write payload manifest to disk and attempt to remove
            Write-OZOProvider -Message "Provider exists but manifest is missing; attempting to remove based on the payload manifest." -Level "Warning"
            # Export the payload manifest to an XML file in the Program Files directory
            $Global:oesConfiguration.manifestXML | Out-File -FilePath $Global:oesConfiguration.manifestPath
        }
        # Uninstall the manifest
        Start-Process -NoNewWindow -Wait -FilePath $Global:oesConfiguration.wEvtUtilPath -ArgumentList ('um "' + $Global:oesConfiguration.manifestPath + '"')
    }
    # Add provider method
    Hidden [Void] AddProvider() {
        Write-OZOProvider -Message "Adding provider." -Level "Information"
        # Create the Program Files directory
        New-Item -ItemType Directory -Path $Global:oesConfiguration.ozoEventLogDir -Force
        # Convert the payload base64 DLL to a binary file in the Program Files directory
        [System.IO.File]::WriteAllBytes($Global:oesConfiguration.dllPath,[Convert]::FromBase64String($Global:oesConfiguration.dllBase64))
        # Export the payload manifest to an XML file in the Program Files directory
        $Global:oesConfiguration.manifestXML | Out-File -FilePath $Global:oesConfiguration.manifestPath
        # Install the manifest
        Start-Process -NoNewWindow -Wait -FilePath $Global:oesConfiguration.wEvtUtilPath -ArgumentList ('im "' + $Global:oesConfiguration.manifestPath + '"')
        # Iterate through the channels
        ForEach ($channelName in $Global:oesConfiguration.channelNames) {
            # Enable the channel
            Start-Process -NoNewWindow -Wait -FilePath $Global:oesConfiguration.wEvtUtilPath -ArgumentList ('sl "' + $Global:oesConfiguration.providerName + '/' + $channelName + '" /e:true')
        }
    }
    # Install modules method
    Hidden [Void] InstallModules() {
        # Iterate through the list of modules to install
        ForEach ($module in $Global:oesConfiguration.InstallModules) {
            If ([Boolean](Get-Module -Name $module) -eq $true) {
                # Module available; try to update the OZOLogger module
                Try {
                    Update-Module -Name $module -ErrorAction Stop
                    # Success
                    Write-OZOProvider -Message ("Updated the " + $module + " module.") -Level "Information"
                } Catch {
                    # Failure; try to install the OZOLogger module
                    Write-OZOProvider -Message ("The " + $module + " module does not appear to be installed; attempting to install.")
                    Try {
                        Install-Module -Name $module -ErrorAction Stop
                        # Success
                        Write-OZOProvider -Message ("Installed the " + $module + " module.") -Level "Information"
                    } Catch {
                        # Failure
                        Write-OZOProvider -Message ("Unable to install the " + $module + " module.") -Level "Warning"
                    }
                }
            } Else {
                # Module unavailable
                Write-OZOProvider -Message ("The " + $module + " module is not available.") -Level "Warning"
            }
        }
    }
}

# FUNCTIONS
Function Write-OZOProvider {
    param(
        [Parameter(Mandatory=$true)][String]$Message,
        [Parameter(Mandatory=$false)][String]$Level = "Information"
    )
    [Int32]$Id = 0000
    Switch($Level) {
        "Information" { $Id = 1000 }
        "Warning"     { $Id = 1001 }
        "Error"       { $Id = 1002 }
        default       { $Id = 1000 }
    }
    # Try to write to the One Zero One provider
    Try {
        New-WinEvent -ProviderName "One Zero One" -Id $Id -Payload (Split-Path -Path $PSCommandPath -Leaf),$Message -ErrorAction Stop
    } Catch {
        New-WinEvent -ProviderName "Microsoft-Windows-PowerShell" -Id 4100 (Split-Path -Path $PSCommandPath -Leaf),"Script output.",$Message
    }
}

# MAIN
# Variables
[String] $dllx86Base64 = "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"
[String] $dllx64Base64 = "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"
[String] $manifestXML  = @'
<?xml version="1.0"?>
<instrumentationManifest xsi:schemaLocation="http://schemas.microsoft.com/win/2004/08/events eventman.xsd" xmlns="http://schemas.microsoft.com/win/2004/08/events" xmlns:win="http://manifests.microsoft.com/win/2004/08/windows/events" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:trace="http://schemas.microsoft.com/win/2004/08/events/trace">
    <instrumentation>
        <events>
            <provider name="One Zero One" guid="{1A87849A-29DF-464E-8AE9-71D981A0667C}" symbol="One_Zero_One" resourceFileName="%PROGRAMDATA%\One Zero One\OZO-EventLog\ozo-messages.dll" messageFileName="%PROGRAMDATA%\One Zero One\OZO-EventLog\ozo-messages.dll">
                <events>
                    <event symbol="Information" value="1000" version="1" channel="One Zero One/Operational" level="win:Informational" template="OZOEventTemplate" message="$(string.OneZeroOne.event.1000.message)"></event>
                    <event symbol="Warning" value="1001" version="1" channel="One Zero One/Operational" level="win:Warning" template="OZOEventTemplate" message="$(string.OneZeroOne.event.1001.message)"></event>
                    <event symbol="Error" value="1002" version="1" channel="One Zero One/Operational" level="win:Error" template="OZOEventTemplate" message="$(string.OneZeroOne.event.1002.message)"></event>
                </events>
                <levels></levels>
                <channels>
                    <channel name="One Zero One/Operational" chid="One Zero One/Operational" symbol="One_Zero_One_Operational" type="Operational" enabled="false"></channel>
                </channels>
                <templates>
                    <template tid="OZOEventTemplate">
                        <data name="Source" inType="win:UnicodeString" outType="xs:string"></data>
                        <data name="Message" inType="win:UnicodeString" outType="xs:string"></data>
                    </template>
                </templates>
            </provider>
        </events>
    </instrumentation>
    <localization>
        <resources culture="en-US">
            <stringTable>
                <string id="level.Warning" value="Warning"></string>
                <string id="level.Informational" value="Information"></string>
                <string id="level.Error" value="Error"></string>
                <string id="OneZeroOne.event.1002.message" value="%1%r%2"></string>
                <string id="OneZeroOne.event.1001.message" value="%1%r%2"></string>
                <string id="OneZeroOne.event.1000.message" value="%1%r%2"></string>
            </stringTable>
        </resources>
    </localization>
</instrumentationManifest>
'@

# Create an object of the OESCOnfiguration class
[PSCustomObject]$Global:oesConfiguration = [OZOESConfiguration]::new($dllx86Base64,$dllx64Base64,$manifestXML)
# Determine if the configuration is valid
If ($Global:oesConfiguration.Validates -eq $true) {
    # Configuration validates
    Write-OZOProvider -Message "Configuration validates." -Level "Information"
    # Set oesConfiguration to read-only
    Set-Variable -Name $Global:oesConfiguration -Option ReadOnly
    # Create an object of the OESMain class
    [OESMain]::new($Remove) | Out-Null
} Else {
    # Configuration did not validate
    Write-OZOProvider -Message "Configuration did not validate." -Level "Error"
}

# SIG # Begin signature block
# MIIfcQYJKoZIhvcNAQcCoIIfYjCCH14CAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBv/EcY+1E9Lp/q
# gKvPha4a50M6Mg/iqwxBquDAFfkXC6CCDPgwggZyMIIEWqADAgECAghkM1HTxzif
# CDANBgkqhkiG9w0BAQsFADB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMx
# EDAOBgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8G
# A1UEAwwoU1NMLmNvbSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTAe
# Fw0xNjA2MjQyMDQ0MzBaFw0zMTA2MjQyMDQ0MzBaMHgxCzAJBgNVBAYTAlVTMQ4w
# DAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjERMA8GA1UECgwIU1NMIENv
# cnAxNDAyBgNVBAMMK1NTTC5jb20gQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBD
# QSBSU0EgUjEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCfgxNzqrDG
# bSHL24t6h3TQcdyOl3Ka5LuINLTdgAPGL0WkdJq/Hg9Q6p5tePOf+lEmqT2d0bKU
# Vz77OYkbkStW72fL5gvjDjmMxjX0jD3dJekBrBdCfVgWQNz51ShEHZVkMGE6ZPKX
# 13NMfXsjAm3zdetVPW+qLcSvvnSsXf5qtvzqXHnpD0OctVIFD+8+sbGP0EmtpuNC
# GVQ/8y8Ooct8/hP5IznaJRy4PgBKOm8yMDdkHseudQfYVdIYyQ6KvKNc8HwKp4WB
# wg6vj5lc02AlvINaaRwlE81y9eucgJvcLGfE3ckJmNVz68Qho+Uyjj4vUpjGYDdk
# jLJvSlRyGMwnh/rNdaJjIUy1PWT9K6abVa8mTGC0uVz+q0O9rdATZlAfC9KJpv/X
# gAbxwxECMzNhF/dWH44vO2jnFfF3VkopngPawismYTJboFblSSmNNqf1x1KiVgMg
# Lzh4gL32Bq5BNMuURb2bx4kYHwu6/6muakCZE93vUN8BuvIE1tAx3zQ4XldbyDge
# VtSsSKbt//m4wTvtwiS+RGCnd83VPZhZtEPqqmB9zcLlL/Hr9dQg1Zc0bl0EawUR
# 0tOSjAknRO1PNTFGfnQZBWLsiePqI3CY5NEv1IoTGEaTZeVYc9NMPSd6Ij/D+KNV
# t/nmh4LsRR7Fbjp8sU65q2j3m2PVkUG8qQIDAQABo4H7MIH4MA8GA1UdEwEB/wQF
# MAMBAf8wHwYDVR0jBBgwFoAU3QQJB6L1en1SUxKSle44gCUNplkwMAYIKwYBBQUH
# AQEEJDAiMCAGCCsGAQUFBzABhhRodHRwOi8vb2NzcHMuc3NsLmNvbTARBgNVHSAE
# CjAIMAYGBFUdIAAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwOwYDVR0fBDQwMjAwoC6g
# LIYqaHR0cDovL2NybHMuc3NsLmNvbS9zc2wuY29tLXJzYS1Sb290Q0EuY3JsMB0G
# A1UdDgQWBBRUwv4QlQCTzWr158DX2bJLuI8M4zAOBgNVHQ8BAf8EBAMCAYYwDQYJ
# KoZIhvcNAQELBQADggIBAPUPJodwr5miyvXWyfCNZj05gtOII9iCv49UhCe204MH
# 154niU2EjlTRIO5gQ9tXQjzHsJX2vszqoz2OTwbGK1mGf+tzG8rlQCbgPW/M9r1x
# xs19DiBAOdYF0q+UCL9/wlG3K7V7gyHwY9rlnOFpLnUdTsthHvWlM98CnRXZ7WmT
# V7pGRS6AvGW+5xI+3kf/kJwQrfZWsqTU+tb8LryXIbN2g9KR+gZQ0bGAKID+260P
# Z+34fdzZcFt6umi1s0pmF4/n8OdX3Wn+vF7h1YyfE7uVmhX7eSuF1W0+Z0duGwdc
# +1RFDxYRLhHDsLy1bhwzV5Qe/kI0Ro4xUE7bM1eV+jjk5hLbq1guRbfZIsr0WkdJ
# LCjoT4xCPGRo6eZDrBmRqccTgl/8cQo3t51Qezxd96JSgjXktefTCm9r/o35pNfV
# HUvnfWII+NnXrJlJ27WEQRQu9i5gl1NLmv7xiHp0up516eDap8nMLDt7TAp4z5T3
# NmC2gzyKVMtODWgqlBF1JhTqIDfM63kXdlV4cW3iSTgzN9vkbFnHI2LmvM4uVEv9
# XgMqyN0eS3FE0HU+MWJliymm7STheh2ENH+kF3y0rH0/NVjLw78a3Z9UVm1F5VPz
# iIorMaPKPlDRADTsJwjDZ8Zc6Gi/zy4WZbg8Zv87spWrmo2dzJTw7XhQf+xkR6Od
# MIIGfjCCBGagAwIBAgIQZ2iSsNbwOsjnLExSAX6F6DANBgkqhkiG9w0BAQsFADB4
# MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0b24x
# ETAPBgNVBAoMCFNTTCBDb3JwMTQwMgYDVQQDDCtTU0wuY29tIENvZGUgU2lnbmlu
# ZyBJbnRlcm1lZGlhdGUgQ0EgUlNBIFIxMB4XDTI0MTExNjEwMzUyOFoXDTI1MTEx
# NjEwMzUyOFowZTELMAkGA1UEBhMCVVMxETAPBgNVBAgMCENvbG9yYWRvMQ8wDQYD
# VQQHDAZEZW52ZXIxGDAWBgNVBAoMD0FuZHJldyBMaWV2ZXJ0ejEYMBYGA1UEAwwP
# QW5kcmV3IExpZXZlcnR6MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA
# vIBAQzK0aahepOrPmvCEqfd6dMZC4GvV7kflKwrn4QPJGfqhFmUtadP1e3ange8O
# QZ3/w7UjOTAUNUHfhjbSgUBlKjbS6EWQKZuRFzI3SNkMJkcjTX4uS2P4QsnwM+SW
# IE5me3CTssdjtgue+Iiy53TMgW8JpoxiULVxmm3bhCRUAgxWeT6tzjytR1UyGcMc
# cm/YE6TOgsCHiZoo4X4HJD9iHDrNldArq04Jl6FsADxEswttKyfqpIRJLoAysVl1
# f8CEDBwhszJrEXBnAlWViJFfNY+dKP4jhf7lLqSvPCuADqP2jvM0Ym5I8qDGMz9j
# XPSMLF58MFB4vM4viS7nLRFJ8S1Q98vQvB8W4kk0WPuiZbZTHsROzohE1VSbLnIY
# ag5dDOWI8L6yutAsfdZFYFmSTKcMSiOj5VbK4LhAJUL2G8vPwpTGFgr+cEp0p62F
# P0WXK+/cRfGqodI5S+bg+9rQTD9zf829DwraSRAt5P5zrQk4WPst3JW/vIKNx7cV
# AgMBAAGjggGVMIIBkTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFFTC/hCVAJPN
# avXnwNfZsku4jwzjMHoGCCsGAQUFBwEBBG4wbDBIBggrBgEFBQcwAoY8aHR0cDov
# L2NlcnQuc3NsLmNvbS9TU0xjb20tU3ViQ0EtQ29kZVNpZ25pbmctUlNBLTQwOTYt
# UjEuY2VyMCAGCCsGAQUFBzABhhRodHRwOi8vb2NzcHMuc3NsLmNvbTBRBgNVHSAE
# SjBIMAgGBmeBDAEEATA8BgwrBgEEAYKpMAEDAwEwLDAqBggrBgEFBQcCARYeaHR0
# cHM6Ly93d3cuc3NsLmNvbS9yZXBvc2l0b3J5MBMGA1UdJQQMMAoGCCsGAQUFBwMD
# ME0GA1UdHwRGMEQwQqBAoD6GPGh0dHA6Ly9jcmxzLnNzbC5jb20vU1NMY29tLVN1
# YkNBLUNvZGVTaWduaW5nLVJTQS00MDk2LVIxLmNybDAdBgNVHQ4EFgQUSj8HrSK7
# f/j+Dz31jJFhOF7rJUMwDgYDVR0PAQH/BAQDAgeAMA0GCSqGSIb3DQEBCwUAA4IC
# AQBf4lcc6FUJ1W/opNz8yjS9qLUy9cQt0s35BhasB5QoTbDaW4jv9xnFGhQVg6n+
# jhL0i94Vsywd/MRBb8lYGpuBZnS/7LHuRZu7qUuud+IMDyRHIyBK6koN5bfyA5VY
# c7bFbNpbe1s1hMWke8di4qgMLZKDfyG/RtA0swf5t4UgQLPP0h+koZ8X8V5+P0V0
# 1HsdXyXd+ojo38EoZyCKfQL2aAwMPwzZfCbmI5SRXNOc6K8oqXzQcendhlKSfVBo
# Zgpi+1updqbD4jmJfYdK5AYPxJ3YH6td6ETtr8owL+bmX8lQjlXPOwVnC11rVlNB
# VjqtaJRUClLtiNiYSTKVfjdmGVJ4+sNov0dWhHc0A9o5NX/05VVYTlImuJpnG5Og
# o7w6kWRdsgE8gM58jWf7XfI6aQS0Np/z2B+ZBj0K93khEHBX7cvvORa92LCHiVeP
# km+zEAMXgxIPs/e8cmcc/o3CORgzEwxlH9Z3UOWCuXSHD3P2RPNDAY+WPdjSHm9f
# JFlGq+f9iKyedxYa/NNjNag/5EbZ+Z2NldtSMNeFdsejGJ/TJHF1PyJd4aXx9J1i
# B/IZBOoJYyh9xpQ3ljZUKE/4otPi7INpuDFwgWiUHZZJVvrGTWwxH1Yhf8P+VpFf
# aNqsBuvklUcUDs3RNE0f1qlgFfcnAepFF+RiBRqmsj29fjGCEc8wghHLAgEBMIGM
# MHgxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3Rv
# bjERMA8GA1UECgwIU1NMIENvcnAxNDAyBgNVBAMMK1NTTC5jb20gQ29kZSBTaWdu
# aW5nIEludGVybWVkaWF0ZSBDQSBSU0EgUjECEGdokrDW8DrI5yxMUgF+hegwDQYJ
# YIZIAWUDBAIBBQCgfDAQBgorBgEEAYI3AgEMMQIwADAZBgkqhkiG9w0BCQMxDAYK
# KwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG
# 9w0BCQQxIgQgwUtaOaYNkwEOl+Ipq3mHqWypMVCk3MwdiDnVBbT+4ZYwDQYJKoZI
# hvcNAQEBBQAEggGAavZxZalkEsmT72W3IcXIkWdB/3j14aU0uN/5lUptzsok1S/P
# fndOapIu7gD/OMJ/3uaRgDA5zMxmGPepDE1gN/yOLeZROLRU1S8pTiokR7NMEnq9
# sqg9Hbg1awKlkPp6rq+h/YQtYBjq0hHcz8JSkmztFfnkwUUzuA1nScgd+0RqGHa/
# GkGrWr+X/FZ55Y8vITnZPljEomBuDzGDw8+K651eafibRjIJnYKyvXvJWJ2Qv4j7
# O+l+n2Qs29U63kaZnleGN7LVjE1YypRq/CJu7i7gdhQr8G16ppVfG+i2gnOMHU2r
# jySXoZPia0PRKJzW33TIbBQyBmUlW48xIOMqYndT1CKCmA0dzyuZTQPhnHjL/yq9
# QVKm4j9zeR9S9DO6YRIKW+r5APmb4F//rVcvr3iyLJ4slo90lrilUiCS5LeRANAb
# vyq1OV2Md+8H/+b75b3jYAexL8DDpiWYn/t+eD+Bjbwi9/xYu9gf5T59uYabr/Vp
# 6fC55DwWzDp4LMjmoYIPFTCCDxEGCisGAQQBgjcDAwExgg8BMIIO/QYJKoZIhvcN
# AQcCoIIO7jCCDuoCAQMxDTALBglghkgBZQMEAgEwdwYLKoZIhvcNAQkQAQSgaARm
# MGQCAQEGDCsGAQQBgqkwAQMGATAxMA0GCWCGSAFlAwQCAQUABCCpxxe6DQPTp1hK
# iEBBJVD/rfubB9RfRZosWdZ1sJQrZQIICeAqepAhgDoYDzIwMjQxMjE0MDY1MDQw
# WjADAgEBoIIMADCCBPwwggLkoAMCAQICEFparOgaNW60YoaNV33gPccwDQYJKoZI
# hvcNAQELBQAwczELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQH
# DAdIb3VzdG9uMREwDwYDVQQKDAhTU0wgQ29ycDEvMC0GA1UEAwwmU1NMLmNvbSBU
# aW1lc3RhbXBpbmcgSXNzdWluZyBSU0EgQ0EgUjEwHhcNMjQwMjE5MTYxODE5WhcN
# MzQwMjE2MTYxODE4WjBuMQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAO
# BgNVBAcMB0hvdXN0b24xETAPBgNVBAoMCFNTTCBDb3JwMSowKAYDVQQDDCFTU0wu
# Y29tIFRpbWVzdGFtcGluZyBVbml0IDIwMjQgRTEwWTATBgcqhkjOPQIBBggqhkjO
# PQMBBwNCAASnYXL1MOl6xIMUlgVC49zonduUbdkyb0piy2i8t3JlQEwA74cjK8g9
# mRC8GH1cAAVMIr8M2HdZpVgkV1LXBLB8o4IBWjCCAVYwHwYDVR0jBBgwFoAUDJ0Q
# JY6apxuZh0PPCH7hvYGQ9M8wUQYIKwYBBQUHAQEERTBDMEEGCCsGAQUFBzAChjVo
# dHRwOi8vY2VydC5zc2wuY29tL1NTTC5jb20tdGltZVN0YW1waW5nLUktUlNBLVIx
# LmNlcjBRBgNVHSAESjBIMDwGDCsGAQQBgqkwAQMGATAsMCoGCCsGAQUFBwIBFh5o
# dHRwczovL3d3dy5zc2wuY29tL3JlcG9zaXRvcnkwCAYGZ4EMAQQCMBYGA1UdJQEB
# /wQMMAoGCCsGAQUFBwMIMEYGA1UdHwQ/MD0wO6A5oDeGNWh0dHA6Ly9jcmxzLnNz
# bC5jb20vU1NMLmNvbS10aW1lU3RhbXBpbmctSS1SU0EtUjEuY3JsMB0GA1UdDgQW
# BBRQTySs77U+YxMjCZIm7Lo6luRdIjAOBgNVHQ8BAf8EBAMCB4AwDQYJKoZIhvcN
# AQELBQADggIBAJigjwMAkbyrxGRBf0Ih4r+rbCB57lTuwViC6nH2fZSciMogpqSz
# rSeVZ2eIb5vhj9rT7jqWXZn02Fncs4YTrA1QyxJW36yjC4jl5/bsFCaWuXzGXt2Y
# 6Ifp//A3Z0sNTMWTTBobmceM3sqnovdX9ToRFP+29r5yQnPcgRTI2PvrVSqLxY9E
# yk9/0cviM3W29YBl080ENblRcu3Y8RsfzRtVT/2snuDocRxvRYmd0TPaMgIj2xII
# 651QnPp1hiq9xU0AyovLzbsi5wlR5Ip4i/i8+x+HwYJNety5cYtdWJ7uQP6YaZtW
# /jNoHp76qNftq/IlSx6xEYBRjFBxHSq2fzhUQ5oBawk2OsZ2j0wOf7q7AqjCt6t/
# +fbmWjrAWYWZGj/RLjltqdFPBpIKqdhjVIxaGgzVhaE/xHKBg4k4DfFZkBYJ9BWu
# P93Tm+paWBDwXI7Fg3alGsboErWPWlvwMAmpeJUjeKLZY26JPLt9ZWceTVWuIyuj
# erqb5IMmeqLJm5iFq/Qy4YPGyPiolw5w1k9OeO4ErmS2FKvk1ejvw4SWR+S1VyWn
# ktY442WaoStxBCCVWZdMWFeB+EpL8uoQNq1MhSt/sIUjUudkyZLIbMVQjj7b6gPX
# nD6mS8FgWiCAhuM1a/hgA+6o1sJWizHdmcpYDhyNzorf9KVRE6iR7rcmMIIG/DCC
# BOSgAwIBAgIQbVIYcIfoI02FYADQgI+TVjANBgkqhkiG9w0BAQsFADB8MQswCQYD
# VQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0b24xGDAWBgNV
# BAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBSb290IENlcnRp
# ZmljYXRpb24gQXV0aG9yaXR5IFJTQTAeFw0xOTExMTMxODUwMDVaFw0zNDExMTIx
# ODUwMDVaMHMxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwH
# SG91c3RvbjERMA8GA1UECgwIU1NMIENvcnAxLzAtBgNVBAMMJlNTTC5jb20gVGlt
# ZXN0YW1waW5nIElzc3VpbmcgUlNBIENBIFIxMIICIjANBgkqhkiG9w0BAQEFAAOC
# Ag8AMIICCgKCAgEArlEQE9L5PCCgIIXeyVAcZMnh/cXpNP8KfzFI6HJaxV6oYf3x
# h/dRXPu35tDBwhOwPsJjoqgY/Tg6yQGBqt65t94wpx0rAgTVgEGMqGri6vCI6rEt
# SZVy9vagzTDHcGfFDc0Eu71mTAyeNCUhjaYTBkyANqp9m6IRrYEXOKdd/eREsqVD
# mhryd7dBTS9wbipm+mHLTHEFBdrKqKDM3fPYdBOro3bwQ6OmcDZ1qMY+2Jn1o0l4
# N9wORrmPcpuEGTOThFYKPHm8/wfoMocgizTYYeDG/+MbwkwjFZjWKwb4hoHT2WK8
# pvGW/OE0Apkrl9CZSy2ulitWjuqpcCEm2/W1RofOunpCm5Qv10T9tIALtQo73GHI
# lIDU6xhYPH/ACYEDzgnNfwgnWiUmMISaUnYXijp0IBEoDZmGT4RTguiCmjAFF5OV
# NbY03BQoBb7wK17SuGswFlDjtWN33ZXSAS+i45My1AmCTZBV6obAVXDzLgdJ1A1r
# yyXz4prLYyfJReEuhAsVp5VouzhJVcE57dRrUanmPcnb7xi57VPhXnCuw26hw1Hd
# +ulK3jJEgbc3rwHPWqqGT541TI7xaldaWDo85k4lR2bQHPNGwHxXuSy3yczyOg57
# TcqqG6cE3r0KR6jwzfaqjTvN695GsPAPY/h2YksNgF+XBnUD9JBtL4c34AcCAwEA
# AaOCAYEwggF9MBIGA1UdEwEB/wQIMAYBAf8CAQAwHwYDVR0jBBgwFoAU3QQJB6L1
# en1SUxKSle44gCUNplkwgYMGCCsGAQUFBwEBBHcwdTBRBggrBgEFBQcwAoZFaHR0
# cDovL3d3dy5zc2wuY29tL3JlcG9zaXRvcnkvU1NMY29tUm9vdENlcnRpZmljYXRp
# b25BdXRob3JpdHlSU0EuY3J0MCAGCCsGAQUFBzABhhRodHRwOi8vb2NzcHMuc3Ns
# LmNvbTA/BgNVHSAEODA2MDQGBFUdIAAwLDAqBggrBgEFBQcCARYeaHR0cHM6Ly93
# d3cuc3NsLmNvbS9yZXBvc2l0b3J5MBMGA1UdJQQMMAoGCCsGAQUFBwMIMDsGA1Ud
# HwQ0MDIwMKAuoCyGKmh0dHA6Ly9jcmxzLnNzbC5jb20vc3NsLmNvbS1yc2EtUm9v
# dENBLmNybDAdBgNVHQ4EFgQUDJ0QJY6apxuZh0PPCH7hvYGQ9M8wDgYDVR0PAQH/
# BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQCSGXUNplpCzxkH2fL8lPrAm/AV6USW
# Wi9xM91Q5RN7mZN3D8T7cm1Xy7qmnItFukgdtiUzLbQokDJyFTrF1pyLgGw/2hU3
# FJEywSN8crPsBGo812lyWFgAg0uOwUYw7WJQ1teICycX/Fug0KB94xwxhsvJBiRT
# pQyhu/2Kyu1Bnx7QQBA1XupcmfhbQrK5O3Q/yIi//kN0OkhQEiS0NlyPPYoRboHW
# C++wogzV6yNjBbKUBrMFxABqR7mkA0x1Kfy3Ud08qyLC5Z86C7JFBrMBfyhfPpKV
# lIiiTQuKz1rTa8ZW12ERoHRHcfEjI1EwwpZXXK5J5RcW6h7FZq/cZE9kLRZhvnRK
# tb+X7CCtLx2h61ozDJmifYvuKhiUg9LLWH0Or9D3XU+xKRsRnfOuwHWuhWch8G7k
# EmnTG9CtD9Dgtq+68KgVHtAWjKk2ui1s1iLYAYxnDm13jMZm0KpRM9mLQHBK5Gb4
# dFgAQwxOFPBslf99hXWgLyYE33vTIi9p0gYqGHv4OZh1ElgGsvyKdUUJkAr5hfbD
# X6pYScJI8v9VNYm1JEyFAV9x4MpskL6kE2Sy8rOqS9rQnVnIyPWLi8N9K4GZvPit
# /Oy+8nFL6q5kN2SZbox5d69YYFe+rN1sDD4CpNWwBBTI/q0V4pkgvhL99IV2Xasj
# HZf4peSrHdL4RjGCAlcwggJTAgEBMIGHMHMxCzAJBgNVBAYTAlVTMQ4wDAYDVQQI
# DAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjERMA8GA1UECgwIU1NMIENvcnAxLzAt
# BgNVBAMMJlNTTC5jb20gVGltZXN0YW1waW5nIElzc3VpbmcgUlNBIENBIFIxAhBa
# WqzoGjVutGKGjVd94D3HMAsGCWCGSAFlAwQCAaCCAWEwGgYJKoZIhvcNAQkDMQ0G
# CyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0yNDEyMTQwNjUwNDBaMCgGCSqG
# SIb3DQEJNDEbMBkwCwYJYIZIAWUDBAIBoQoGCCqGSM49BAMCMC8GCSqGSIb3DQEJ
# BDEiBCD1IPoFP3HBig2adf1S9YULH9ZtZrrE4eVAnKhlQLYwVTCByQYLKoZIhvcN
# AQkQAi8xgbkwgbYwgbMwgbAEIJ1xf43CN2Wqzl5KsOH1ddeaF9Qc7tj9r+8D/T29
# iUfnMIGLMHekdTBzMQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNV
# BAcMB0hvdXN0b24xETAPBgNVBAoMCFNTTCBDb3JwMS8wLQYDVQQDDCZTU0wuY29t
# IFRpbWVzdGFtcGluZyBJc3N1aW5nIFJTQSBDQSBSMQIQWlqs6Bo1brRiho1XfeA9
# xzAKBggqhkjOPQQDAgRGMEQCIEdKv1SISw+elIbqD21UglHGct/UH14MhyghpdPx
# as+lAiBpITgTHySe8AJbmflPvcOWm8TPyxVJmCYxPZM+HEWpDA==
# SIG # End signature block