SetupBase.TaskScheduler.ps1

function Private-IsAdmin {
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseApprovedVerbs", "")]
    [OutputType([bool])]
    param()
    $currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
    $IsAdmin = $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
    return $IsAdmin
}

function Private-IsNotAdminWarning {
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseApprovedVerbs", "")]
    [OutputType([bool])]
    param()

    $IsAdmin = Private-IsAdmin
    if ($IsAdmin -eq $false)
    {
        Write-Warning "This command can only be executed with elevated administrator rights."
    }

    return $IsAdmin
}

Add-Type @'
public enum LogonUserType {
    SYSTEM = 0,
    CURRENTUSER = 1,
    ANYUSER = 2,
}
'@


Add-Type @'
public enum ScheduleType{
    TIME = 0,
    LOGON = 1,
}
'@


function Private-New-SubTask {
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseApprovedVerbs", "")]
    param (
        [Parameter(Mandatory)]
        [string]$Name,
        [Parameter(Mandatory)]
        [string]$Program,
        [string]$Arguments = "",

        [ScheduleType]$ScheduleType = [ScheduleType]::LOGON,
        [LogonUserType]$LogonUserType = [LogonUserType]::CURRENTUSER,
        [bool]$HideScripts = $false,

        [timespan]$Time,
        [dayofweek[]]$day = ('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday')

    )

    #starTime is required for a task to start the operations at a specific date, calculating a default at current day 00:00 if no starttime was givven
    [datetime]$startTime = $(Get-Date)
    if ($Time -eq $null)
    {
        $startTime = $($(Get-Date) - $(Get-Date).TimeOfDay)
    }
    else {
        $startTime = $($(Get-Date) - $(Get-Date).TimeOfDay) + $Time
    }

    Private-Script-Task-Helper -Program ([ref]$Program) -Arguments ([ref]$Arguments) -HideScripts $HideScripts

    if ($Arguments.Trim() -eq "")
    {
        $actions = (New-ScheduledTaskAction -Execute "$Program" -Id "$Name")
    }
    else {
        $actions = (New-ScheduledTaskAction -Execute "$Program" -Argument "$Arguments" -Id "$Name")
    }

    if ($LogonUserType -eq [LogonUserType]::SYSTEM)
    {
        $principal = New-ScheduledTaskPrincipal -UserId "NT AUTHORITY\SYSTEM" -LogonType ServiceAccount -RunLevel Highest
    }
    elseif ($LogonUserType -eq [LogonUserType]::CURRENTUSER) {
        $principal = New-ScheduledTaskPrincipal -UserId "$([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)" -LogonType Interactive
    }
    elseif ($LogonUserType -eq [LogonUserType]::ANYUSER) {
        $principal = New-ScheduledTaskPrincipal -GroupId "NT AUTHORITY\Interactive"
    }

    if ($ScheduleType -eq [ScheduleType]::TIME)
    {
        $trigger = New-ScheduledTaskTrigger -Weekly -WeeksInterval 1 -DaysOfWeek $day -At $startTime
        $settings = New-ScheduledTaskSettingsSet -StartWhenAvailable
    }
    elseif ($ScheduleType -eq [ScheduleType]::LOGON)
    {
        if ($LogonUserType -eq [LogonUserType]::SYSTEM)
        {
            $trigger = New-ScheduledTaskTrigger -AtLogon
            $settings = New-ScheduledTaskSettingsSet
        }
        elseif ($LogonUserType -eq [LogonUserType]::CURRENTUSER) {
            $trigger = New-ScheduledTaskTrigger -AtLogon -User "$([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)"
            $settings = New-ScheduledTaskSettingsSet
        }
        elseif ($LogonUserType -eq [LogonUserType]::ANYUSER) {
            $trigger = New-ScheduledTaskTrigger -AtLogon
            $settings = New-ScheduledTaskSettingsSet
        }
    }

    $task = New-ScheduledTask -Action $actions -Principal $principal -Trigger $trigger -Settings $settings

    Register-ScheduledTask "$Name" -Force -InputObject $task | Out-Null
}

function Private-Script-Task-Helper {
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseApprovedVerbs", "")]
    param (
        [Parameter(Mandatory)]
        [ref]$Program,
        [Parameter(Mandatory)]
        [ref]$Arguments,
        [Parameter(Mandatory)]
        [bool]$HideScripts
    )

    if (Test-Path "$env:LOCALAPPDATA\SetupBase\bin\SubSystemWin.exe" -PathType Leaf)
    {
        $InstalledVer = [System.Diagnostics.FileVersionInfo]::GetVersionInfo("$env:LOCALAPPDATA\SetupBase\bin\SubSystemWin.exe").FileVersion
        $LocalVer = [System.Diagnostics.FileVersionInfo]::GetVersionInfo("$PSScriptRoot\SubSystemWin.exe").FileVersion
        if ($LocalVer -gt $InstalledVer)
        {
            $path = "$env:LOCALAPPDATA\SetupBase\bin"
            if(!(test-path -PathType container $path))
            {
                New-Item -ItemType Directory -Path $path | Out-Null
            }
            Copy-Item "$PSScriptRoot\SubSystemWin.exe" -Destination "$env:LOCALAPPDATA\SetupBase\bin\SubSystemWin.exe" -Force
        }
    }
    else {
        $path = "$env:LOCALAPPDATA\SetupBase\bin"
        if(!(test-path -PathType container $path))
        {
            New-Item -ItemType Directory -Path $path | Out-Null
        }
        Copy-Item "$PSScriptRoot\SubSystemWin.exe" -Destination "$env:LOCALAPPDATA\SetupBase\bin\SubSystemWin.exe" -Force
    }

    if ($Program.Value.EndsWith(".ps1") -and ($HideScripts -eq $false))
    {
        $NewProgram = "$([System.Diagnostics.Process]::GetCurrentProcess().MainModule.FileName)"
        $NewArguments = "-ExecutionPolicy Bypass -File $($Program.Value) $($Arguments.Value)"
    }
    elseif ($Program.Value.EndsWith(".ps1") -and ($HideScripts -eq $true))
    {
        $NewProgram = "$env:LOCALAPPDATA\SetupBase\bin\SubSystemWin.exe"
        $NewArguments = """$([System.Diagnostics.Process]::GetCurrentProcess().MainModule.FileName)"" -NonInteractive -ExecutionPolicy Bypass -File $($Program.Value) $($Arguments.Value)"
    }
    elseif (($Program.Value.EndsWith(".bat") -or $Program.Value.EndsWith(".cmd")) -and ($HideScripts -eq $false))
    {
        $NewProgram = "$($env:comspec)"
        $NewArguments = "/c $($Program.Value) $($Arguments.Value)"
    }
    elseif (($Program.Value.EndsWith(".bat") -or $Program.Value.EndsWith(".cmd"))  -and ($HideScripts -eq $true))
    {
        $NewProgram = "$env:LOCALAPPDATA\SetupBase\bin\SubSystemWin.exe"
        $NewArguments = """$($env:comspec)"" /c ""$($Program.Value)"" $($Arguments.Value)"
    }
    else {
        $NewProgram = $Program.Value
        $NewArguments = $Arguments.Value 
    }

    $Program.Value = $NewProgram
    $Arguments.Value = $NewArguments

}

function Private-Script-CreateSampleScript {
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseApprovedVerbs", "")]
    param(
        [Parameter(Mandatory)]
        [string]$Location
    )
    


    if ($Location.EndsWith(".ps1"))
    {
$sample = `
@"
`$ErrorActionPreference="SilentlyContinue"
Stop-Transcript | out-null
`$ErrorActionPreference = "Continue"
`$logFileTime = [System.DateTime]::UtcNow.ToString("yyyy_MM_dd_HH_mm_ss_fff")
Start-Transcript -path "`$PSScriptRoot\`$(`$MyInvocation.MyCommand.Name)_`$logFileTime.log" -append -Force -IncludeInvocationHeader
 
Write-Host "Hello form `$PSScriptRoot\`$(`$MyInvocation.MyCommand.Name)"
Write-Host "Our commands here"
 
Stop-Transcript
"@

    }
    elseif ($Location.EndsWith(".bat") -or $Location.EndsWith(".cmd")) {
$sample = `
@"
@echo off
echo hello > %~dp0foo.log
echo %0 >> %~dp0foo.log
echo 1 >> %~dp0foo.log
echo 2 >> %~dp0foo.log
echo 3 >> %~dp0foo.log
"@
       
    }

    New-Item -path "$Location" -ItemType "file" -Force -value "$sample"  | Out-Null

}

function Private-New-SubCreateDefaultLogonTask {
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseApprovedVerbs", "")]
    param(
        [Parameter(Mandatory)]
        [string]$Name,
        [Parameter(Mandatory)]
        [string]$Location,
        [bool]$HideScript = $false
    )
    Private-Script-CreateSampleScript -Location "$Location"
    Private-New-SubTask -Name "$Name" -Program "$Location" -HideScript $HideScript
}

function EnableTaskSchedulerEventLog {
    $logName = 'Microsoft-Windows-TaskScheduler/Operational'
    $log = New-Object System.Diagnostics.Eventing.Reader.EventLogConfiguration $logName
    $log.IsEnabled=$true
    $log.SaveChanges()
}

# SIG # Begin signature block
# MIIb1wYJKoZIhvcNAQcCoIIbyDCCG8QCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUPzIZWVxnsEg5KESrzIFiGd38
# baagghY7MIIDKjCCAhKgAwIBAgIQL6HHqwoFIaBK+v4IX7cvUDANBgkqhkiG9w0B
# AQsFADAtMSswKQYDVQQDDCJTZXR1cEJhc2UgQ29kZSBTaWduaW5nIENlcnRpZmlj
# YXRlMB4XDTIyMDgyNDE3MjEzOFoXDTI0MDgyNDE3MzEzOFowLTErMCkGA1UEAwwi
# U2V0dXBCYXNlIENvZGUgU2lnbmluZyBDZXJ0aWZpY2F0ZTCCASIwDQYJKoZIhvcN
# AQEBBQADggEPADCCAQoCggEBAK+riPnD6ghFJKZrD9Pr8ExR1Q8GhMfR6yccf1dA
# ucHMs9E3RydQpQPIhIWBFej9GJPWSoZSz7bja22Y1D3j+yHArYmjd62JaZH2dw0A
# WBixvXBmcdzrzA5+CR03P3Ey2gSJNxZL5XfQB+oJ4Wq1vr68N+5oqdS0kDaxfY9x
# J6EOiLv85bF487zNOOMzewH9lpHvb23jqjpiauWF7K3JhlO0aNl201/nrYuoaabX
# sMce+agFt7YkTbouSkAwkDAl1fvcxxJ4aid6Tpcs3lm2HwL91LMCncTp6RCQTQ7S
# pfcelI0nazSfsCuMPs3LcMho0k13gE4uWDhgh4NGbsYYNtECAwEAAaNGMEQwDgYD
# VR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMB0GA1UdDgQWBBTjh0nl
# V516/ZVRhSQi+cKSfVsIuDANBgkqhkiG9w0BAQsFAAOCAQEAhzpMoTObmPQUu1lz
# qiArE4v62EsayGYfCQbc/gNucMjpjoj4oqtSPtYLuTb62RlteuWzYh1nFmTt2K+P
# PbM3HkYMJ0tX6jSRzDyZSa2ENVGL81vWOFpBANFRf4JD7Fnzler0Xi2OUoulRJAw
# DoQ3HKrdYgAOI8PcGZq+HT5CkZNNgWtMFDS2iPI3MHTM4aGEMvKQNMr6WXpdA/uk
# A8mA/UdOgyA4C+BEZwn0UPZR/mNtCSG/XIwE/thEqlZpskt8eCVyQ+AG/tdIIXpG
# jZRATGJ2gx0+ZXvAZH8qHHYh0RG9ESwfdmYoILoaeuvh0fRGP9ed+yz9DEknNGjB
# X6J3BzCCBY0wggR1oAMCAQICEA6bGI750C3n79tQ4ghAGFowDQYJKoZIhvcNAQEM
# BQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UE
# CxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNzdXJlZCBJ
# RCBSb290IENBMB4XDTIyMDgwMTAwMDAwMFoXDTMxMTEwOTIzNTk1OVowYjELMAkG
# A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
# Z2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgVHJ1c3RlZCBSb290IEc0MIIC
# IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAv+aQc2jeu+RdSjwwIjBpM+zC
# pyUuySE98orYWcLhKac9WKt2ms2uexuEDcQwH/MbpDgW61bGl20dq7J58soR0uRf
# 1gU8Ug9SH8aeFaV+vp+pVxZZVXKvaJNwwrK6dZlqczKU0RBEEC7fgvMHhOZ0O21x
# 4i0MG+4g1ckgHWMpLc7sXk7Ik/ghYZs06wXGXuxbGrzryc/NrDRAX7F6Zu53yEio
# ZldXn1RYjgwrt0+nMNlW7sp7XeOtyU9e5TXnMcvak17cjo+A2raRmECQecN4x7ax
# xLVqGDgDEI3Y1DekLgV9iPWCPhCRcKtVgkEy19sEcypukQF8IUzUvK4bA3VdeGbZ
# OjFEmjNAvwjXWkmkwuapoGfdpCe8oU85tRFYF/ckXEaPZPfBaYh2mHY9WV1CdoeJ
# l2l6SPDgohIbZpp0yt5LHucOY67m1O+SkjqePdwA5EUlibaaRBkrfsCUtNJhbesz
# 2cXfSwQAzH0clcOP9yGyshG3u3/y1YxwLEFgqrFjGESVGnZifvaAsPvoZKYz0YkH
# 4b235kOkGLimdwHhD5QMIR2yVCkliWzlDlJRR3S+Jqy2QXXeeqxfjT/JvNNBERJb
# 5RBQ6zHFynIWIgnffEx1P2PsIV/EIFFrb7GrhotPwtZFX50g/KEexcCPorF+CiaZ
# 9eRpL5gdLfXZqbId5RsCAwEAAaOCATowggE2MA8GA1UdEwEB/wQFMAMBAf8wHQYD
# VR0OBBYEFOzX44LScV1kTN8uZz/nupiuHA9PMB8GA1UdIwQYMBaAFEXroq/0ksuC
# MS1Ri6enIZ3zbcgPMA4GA1UdDwEB/wQEAwIBhjB5BggrBgEFBQcBAQRtMGswJAYI
# KwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBDBggrBgEFBQcwAoY3
# aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
# dENBLmNydDBFBgNVHR8EPjA8MDqgOKA2hjRodHRwOi8vY3JsMy5kaWdpY2VydC5j
# b20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3JsMBEGA1UdIAQKMAgwBgYEVR0g
# ADANBgkqhkiG9w0BAQwFAAOCAQEAcKC/Q1xV5zhfoKN0Gz22Ftf3v1cHvZqsoYcs
# 7IVeqRq7IviHGmlUIu2kiHdtvRoU9BNKei8ttzjv9P+Aufih9/Jy3iS8UgPITtAq
# 3votVs/59PesMHqai7Je1M/RQ0SbQyHrlnKhSLSZy51PpwYDE3cnRNTnf+hZqPC/
# Lwum6fI0POz3A8eHqNJMQBk1RmppVLC4oVaO7KTVPeix3P0c2PR3WlxUjG/voVA9
# /HYJaISfb8rbII01YBwCA8sgsKxYoA5AY8WYIsGyWfVVa88nq2x2zm8jLfR+cWoj
# ayL/ErhULSd+2DrZ8LaHlv1b0VysGMNNn3O3AamfV6peKOK5lDCCBq4wggSWoAMC
# AQICEAc2N7ckVHzYR6z9KGYqXlswDQYJKoZIhvcNAQELBQAwYjELMAkGA1UEBhMC
# VVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0
# LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgVHJ1c3RlZCBSb290IEc0MB4XDTIyMDMy
# MzAwMDAwMFoXDTM3MDMyMjIzNTk1OVowYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoT
# DkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJT
# QTQwOTYgU0hBMjU2IFRpbWVTdGFtcGluZyBDQTCCAiIwDQYJKoZIhvcNAQEBBQAD
# ggIPADCCAgoCggIBAMaGNQZJs8E9cklRVcclA8TykTepl1Gh1tKD0Z5Mom2gsMyD
# +Vr2EaFEFUJfpIjzaPp985yJC3+dH54PMx9QEwsmc5Zt+FeoAn39Q7SE2hHxc7Gz
# 7iuAhIoiGN/r2j3EF3+rGSs+QtxnjupRPfDWVtTnKC3r07G1decfBmWNlCnT2exp
# 39mQh0YAe9tEQYncfGpXevA3eZ9drMvohGS0UvJ2R/dhgxndX7RUCyFobjchu0Cs
# X7LeSn3O9TkSZ+8OpWNs5KbFHc02DVzV5huowWR0QKfAcsW6Th+xtVhNef7Xj3OT
# rCw54qVI1vCwMROpVymWJy71h6aPTnYVVSZwmCZ/oBpHIEPjQ2OAe3VuJyWQmDo4
# EbP29p7mO1vsgd4iFNmCKseSv6De4z6ic/rnH1pslPJSlRErWHRAKKtzQ87fSqEc
# azjFKfPKqpZzQmiftkaznTqj1QPgv/CiPMpC3BhIfxQ0z9JMq++bPf4OuGQq+nUo
# JEHtQr8FnGZJUlD0UfM2SU2LINIsVzV5K6jzRWC8I41Y99xh3pP+OcD5sjClTNfp
# mEpYPtMDiP6zj9NeS3YSUZPJjAw7W4oiqMEmCPkUEBIDfV8ju2TjY+Cm4T72wnSy
# Px4JduyrXUZ14mCjWAkBKAAOhFTuzuldyF4wEr1GnrXTdrnSDmuZDNIztM2xAgMB
# AAGjggFdMIIBWTASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBS6FtltTYUv
# cyl2mi91jGogj57IbzAfBgNVHSMEGDAWgBTs1+OC0nFdZEzfLmc/57qYrhwPTzAO
# BgNVHQ8BAf8EBAMCAYYwEwYDVR0lBAwwCgYIKwYBBQUHAwgwdwYIKwYBBQUHAQEE
# azBpMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQQYIKwYB
# BQUHMAKGNWh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0
# ZWRSb290RzQuY3J0MEMGA1UdHwQ8MDowOKA2oDSGMmh0dHA6Ly9jcmwzLmRpZ2lj
# ZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRSb290RzQuY3JsMCAGA1UdIAQZMBcwCAYG
# Z4EMAQQCMAsGCWCGSAGG/WwHATANBgkqhkiG9w0BAQsFAAOCAgEAfVmOwJO2b5ip
# RCIBfmbW2CFC4bAYLhBNE88wU86/GPvHUF3iSyn7cIoNqilp/GnBzx0H6T5gyNgL
# 5Vxb122H+oQgJTQxZ822EpZvxFBMYh0MCIKoFr2pVs8Vc40BIiXOlWk/R3f7cnQU
# 1/+rT4osequFzUNf7WC2qk+RZp4snuCKrOX9jLxkJodskr2dfNBwCnzvqLx1T7pa
# 96kQsl3p/yhUifDVinF2ZdrM8HKjI/rAJ4JErpknG6skHibBt94q6/aesXmZgaNW
# hqsKRcnfxI2g55j7+6adcq/Ex8HBanHZxhOACcS2n82HhyS7T6NJuXdmkfFynOlL
# AlKnN36TU6w7HQhJD5TNOXrd/yVjmScsPT9rp/Fmw0HNT7ZAmyEhQNC3EyTN3B14
# OuSereU0cZLXJmvkOHOrpgFPvT87eK1MrfvElXvtCl8zOYdBeHo46Zzh3SP9HSjT
# x/no8Zhf+yvYfvJGnXUsHicsJttvFXseGYs2uJPU5vIXmVnKcPA3v5gA3yAWTyf7
# YGcWoWa63VXAOimGsJigK+2VQbc61RWYMbRiCQ8KvYHZE/6/pNHzV9m8BPqC3jLf
# BInwAM1dwvnQI38AC+R2AibZ8GV2QqYphwlHK+Z/GqSFD/yYlvZVVCsfgPrA8g4r
# 5db7qS9EFUrnEw4d2zc4GqEr9u3WfPwwggbGMIIErqADAgECAhAKekqInsmZQpAG
# YzhNhpedMA0GCSqGSIb3DQEBCwUAMGMxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5E
# aWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0
# MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0EwHhcNMjIwMzI5MDAwMDAwWhcNMzMw
# MzE0MjM1OTU5WjBMMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIElu
# Yy4xJDAiBgNVBAMTG0RpZ2lDZXJ0IFRpbWVzdGFtcCAyMDIyIC0gMjCCAiIwDQYJ
# KoZIhvcNAQEBBQADggIPADCCAgoCggIBALkqliOmXLxf1knwFYIY9DPuzFxs4+Al
# LtIx5DxArvurxON4XX5cNur1JY1Do4HrOGP5PIhp3jzSMFENMQe6Rm7po0tI6IlB
# fw2y1vmE8Zg+C78KhBJxbKFiJgHTzsNs/aw7ftwqHKm9MMYW2Nq867Lxg9GfzQnF
# uUFqRUIjQVr4YNNlLD5+Xr2Wp/D8sfT0KM9CeR87x5MHaGjlRDRSXw9Q3tRZLER0
# wDJHGVvimC6P0Mo//8ZnzzyTlU6E6XYYmJkRFMUrDKAz200kheiClOEvA+5/hQLJ
# huHVGBS3BEXz4Di9or16cZjsFef9LuzSmwCKrB2NO4Bo/tBZmCbO4O2ufyguwp7g
# C0vICNEyu4P6IzzZ/9KMu/dDI9/nw1oFYn5wLOUrsj1j6siugSBrQ4nIfl+wGt0Z
# vZ90QQqvuY4J03ShL7BUdsGQT5TshmH/2xEvkgMwzjC3iw9dRLNDHSNQzZHXL537
# /M2xwafEDsTvQD4ZOgLUMalpoEn5deGb6GjkagyP6+SxIXuGZ1h+fx/oK+QUshbW
# gaHK2jCQa+5vdcCwNiayCDv/vb5/bBMY38ZtpHlJrYt/YYcFaPfUcONCleieu5tL
# suK2QT3nr6caKMmtYbCgQRgZTu1Hm2GV7T4LYVrqPnqYklHNP8lE54CLKUJy93my
# 3YTqJ+7+fXprAgMBAAGjggGLMIIBhzAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/
# BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAgBgNVHSAEGTAXMAgGBmeBDAEE
# AjALBglghkgBhv1sBwEwHwYDVR0jBBgwFoAUuhbZbU2FL3MpdpovdYxqII+eyG8w
# HQYDVR0OBBYEFI1kt4kh/lZYRIRhp+pvHDaP3a8NMFoGA1UdHwRTMFEwT6BNoEuG
# SWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQw
# OTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5jcmwwgZAGCCsGAQUFBwEBBIGDMIGAMCQG
# CCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wWAYIKwYBBQUHMAKG
# TGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFJT
# QTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5jcnQwDQYJKoZIhvcNAQELBQADggIB
# AA0tI3Sm0fX46kuZPwHk9gzkrxad2bOMl4IpnENvAS2rOLVwEb+EGYs/XeWGT76T
# Ot4qOVo5TtiEWaW8G5iq6Gzv0UhpGThbz4k5HXBw2U7fIyJs1d/2WcuhwupMdsqh
# 3KErlribVakaa33R9QIJT4LWpXOIxJiA3+5JlbezzMWn7g7h7x44ip/vEckxSli2
# 3zh8y/pc9+RTv24KfH7X3pjVKWWJD6KcwGX0ASJlx+pedKZbNZJQfPQXpodkTz5G
# iRZjIGvL8nvQNeNKcEiptucdYL0EIhUlcAZyqUQ7aUcR0+7px6A+TxC5MDbk86pp
# CaiLfmSiZZQR+24y8fW7OK3NwJMR1TJ4Sks3KkzzXNy2hcC7cDBVeNaY/lRtf3Gp
# SBp43UZ3Lht6wDOK+EoojBKoc88t+dMj8p4Z4A2UKKDr2xpRoJWCjihrpM6ddt6p
# c6pIallDrl/q+A8GQp3fBmiW/iqgdFtjZt5rLLh4qk1wbfAs8QcVfjW05rUMopml
# 1xVrNQ6F1uAszOAMJLh8UgsemXzvyMjFjFhpr6s94c/MfRWuFL+Kcd/Kl7HYR+oc
# heBFThIcFClYzG/Tf8u+wQ5KbyCcrtlzMlkI5y2SoRoR/jKYpl0rl+CL05zMbbUN
# rkdjOEcXW28T2moQbh9Jt0RbtAgKh1pZBHYRoad3AhMcMYIFBjCCBQICAQEwQTAt
# MSswKQYDVQQDDCJTZXR1cEJhc2UgQ29kZSBTaWduaW5nIENlcnRpZmljYXRlAhAv
# ocerCgUhoEr6/ghfty9QMAkGBSsOAwIaBQCgeDAYBgorBgEEAYI3AgEMMQowCKAC
# gAChAoAAMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsx
# DjAMBgorBgEEAYI3AgEVMCMGCSqGSIb3DQEJBDEWBBRZp78hfp+xxxD7EjMI3Ujp
# FmnsaDANBgkqhkiG9w0BAQEFAASCAQBfgrCgS9hhGSbvw+s/8Cf9rxDrdEkf5erl
# Wsngz4cWLhUojNd3hVFdFchTrpoZkNlqNK7DqHqdIkw4QYnieiW+8vejFeX0uI0f
# RSPMFSoH9EklvbyMGMCdSOjDpr8JYJ+WKeVu0F6B/Z9tz7bCqRkJmbzS5tCB+8Bw
# YFRv6G26KJQ29uIuGY3bvGrymVIZuBjNtOzn6+xStK1xp8F7eq8/UWu84fpcvpIC
# aE0yBPgeTFktZia+NsQil1yhY1tVBPytN9fCtvGndgdssdRIoDQtBhs1eEWDqCVx
# vC0B81W5UzwbDYFDFsMLKoT4Su8Zx7q/bUo5Y08AZHm13XL/9xWWoYIDIDCCAxwG
# CSqGSIb3DQEJBjGCAw0wggMJAgEBMHcwYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoT
# DkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJT
# QTQwOTYgU0hBMjU2IFRpbWVTdGFtcGluZyBDQQIQCnpKiJ7JmUKQBmM4TYaXnTAN
# BglghkgBZQMEAgEFAKBpMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZI
# hvcNAQkFMQ8XDTIyMDgyNDE4MTUyOVowLwYJKoZIhvcNAQkEMSIEICUCZ7Mq8kPO
# 5jw/4CERMcthTaQi0sj5KMnTa1X6PsPpMA0GCSqGSIb3DQEBAQUABIICAF/gs+tt
# JVr5i4gC+GARVdnURtzcSzbZjm48x8JEu0FPUJbRSGVHawxChuhYk2WO1+HfUNvP
# 3s8hZEjbzqqRw1vVJn+xOR6tkWmwz0i1a/vv+kMCqo47XtKfyY/iYtG97XEb7sSZ
# YHspxrxn5YPn/N4caTUhKrk63mrEZtOuzPxOJbi1IIOtr+0XzKGWYIgPAwovokw+
# esLsQ4nS9GxDoPInwIF3MIfHrniKcdEgNq13fBHeU/HKIahYUEcAoUa4cFbo3uz3
# vusOP5kTrRJzomNf7NUaDfCTbLKti4EGJnrDn9E9gDN07HI9rftlLPABI8gq0IKs
# lZ+C5vtr9ynERD5EWbx2nR5q8soX+4oSRhGG/KiPITq/97JHcvQu5T3LEICs2FgZ
# klobfyESe4YxfXcMgwpSfeCKmJrmhCd1GrVHC3fB8TUegfjUSvrhpR7+BO1RIrqt
# uzQ4A2lj/Ch+kUwYV5kbPltE6/8T+i7HtGXgNa670Llu2M4bToSgYWcVecMljVFG
# r5mnUIDZCL7Z9TjMVzLRdnxIFlNS/LhEtaASTpFaLFcmzWVY276g2xqLYvNaVViE
# ndoaDZPFq6P0bXm4M3AXNWTQrNMDGMWByIQCLpgia9/BW6o3jDTDFNl7XXexwWty
# ONN6P2L74woQSiKWkigrB7lvLjL5nbUhCaUW
# SIG # End signature block