Private/Write-ADFSTkLog.ps1


function Write-ADFSTkLog {
[CmdletBinding(DefaultParametersetName="Default")]
param (        
    [Parameter(Mandatory=$false,
                ParameterSetName="Set",
                ValueFromPipelineByPropertyName=$false)]
    [string]
    #The path to the logfile. This needs to be set once in the script. The path will be stored in a global variable 'LogFilePath'
    $SetLogFilePath,
    [Parameter(Mandatory=$false,
                ParameterSetName="Set",
                ValueFromPipelineByPropertyName=$false)]
    [string]
    #The name of the eventlog. This needs to be set once in the script. The name will be stored in a global variable 'EventLogName'
    $SetEventLogName,
    [Parameter(Mandatory=$false,
                ParameterSetName="Set",
                ValueFromPipelineByPropertyName=$false)]
    [string]
    <#The Source that will be used in the eventlog.
     
    Use New-EventLog -LogName <EventLogName> -Source <NewSource> to add a new source to a eventlog.
     
    This needs to be set once in the script. The name will be stored in a global variable 'EventLogSource'#>

    $SetEventLogSource,
    [Parameter(Mandatory=$false,
                ParameterSetName="Get",
                ValueFromPipelineByPropertyName=$false)]
    [switch]
    #Returns the path to the LogFile.
    $GetLogFilePath,
    [Parameter(Mandatory=$false,
                ParameterSetName="Get",
                ValueFromPipelineByPropertyName=$false)]
    [switch]
    #Returns the name of the EventLog that will be used.
    $GetEventLogName,
    [Parameter(Mandatory=$false,
                ParameterSetName="Get",
                ValueFromPipelineByPropertyName=$false)]
    [switch]
    #Returns the Source of the EventLog that will be used.
    $GetEventLogSource,
    
    [Parameter(Mandatory=$false,
                ParameterSetName="Default",
                ValueFromPipelineByPropertyName=$true,
                Position=0)]
    [ValidateNotNullOrEmpty()]
    [string]
    #The message to be written in the log...
    $Message,
    
    [Parameter(Mandatory=$false,
                ParameterSetName="Default",
                ValueFromPipelineByPropertyName=$true)]
    [int]
    #The EventID if EventLog is used
    $EventID,
    [Parameter(Mandatory=$false,
                ParameterSetName="Default",
                ValueFromPipelineByPropertyName=$true)]
    [string]
    #Used in LogFile and on Screen to clarify the message. In EventLog the Level on the event is set to EntryType. Default is Information
    [ValidateSet("Information", "Error", "Warning")]
    $EntryType="Information",
    [Parameter(Mandatory=$false,
                ParameterSetName="Default",
                ValueFromPipelineByPropertyName=$true)]
    [switch]
    #If used the EntryType will be set as "Error" the message will be thown as an error.
    $MajorFault,
    [Parameter(Mandatory=$false,
                ParameterSetName="Default",
                ValueFromPipelineByPropertyName=$true)]
    [int]
    #Only for EventLog. Task Category on the event is set to Category. If -Verbose is used, Category will be set to 4
    $Category=1,
    [Parameter(Mandatory=$false,
                ParameterSetName="Default",
                ValueFromPipelineByPropertyName=$false)]
    [switch]
    #Used in LogFile and on Screen make the message underlined
    $Underline,
    [Parameter(Mandatory=$false,
                ParameterSetName="Default",
                ValueFromPipelineByPropertyName=$false)]
    [char]
    #The char used to make the underline (see parameter Underline). Default is '-'
    $UnderlineChar='-',
    [Parameter(Mandatory=$false,
                ParameterSetName="Default",
                ValueFromPipelineByPropertyName=$true)]
    [switch]
    #Use this to get output on the screen
    $Screen,
    [Parameter(Mandatory=$false,
                ParameterSetName="Default",
                ValueFromPipelineByPropertyName=$true)]
    [switch]
    #Use this to log to file
    $File,
    [Parameter(Mandatory=$false,
                ParameterSetName="Default",
                ValueFromPipelineByPropertyName=$true)]
    [switch]
    #Use this to log to EventLog
    $EventLog,
    [Parameter(Mandatory=$false,
                ParameterSetName="Default",
                ValueFromPipelineByPropertyName=$true)]
    [switch]
    #Doesn't write Date and Time in the beginning of the row
    $SkipDateTime,
    [Parameter(Mandatory=$false,
                ParameterSetName="Default",
                ValueFromPipelineByPropertyName=$true)]
    [ConsoleColor]
    #Sets the color the screen-text should be written in
    $ForegroundColor = [ConsoleColor]::Gray
)
       
Begin {
    
    if ($PsCmdlet.ParameterSetName -eq "Set")
    {
        if ($SetLogFilePath -ne [string]::Empty) 
        {
            $FilePath = $SetLogFilePath.SubString(0,$SetLogFilePath.LastIndexOf('\'))
            if (! (Test-Path ($FilePath)))
            {
                Write-Warning (Get-ADFSTkLanguageText logPathNotFound -f $FilePath)
            }
            else
            {
                Write-Verbose (Get-ADFSTkLanguageText logSettingXPathTo -f 'LogFilePath', $SetLogFilePath)
                $global:LogFilePath = $SetLogFilePath                    
            }
        }
        
        if ($SetEventLogName -ne [string]::Empty)
        {
            try
            {
                $TestEventLog = Get-EventLog $SetEventLogName -Newest 1
                
                Write-Verbose (Get-ADFSTkLanguageText logSettingXPathTo -f 'EventLogName', $SetEventLogName)
                $global:EventLogName = $SetEventLogName 
            }
            catch
            {
                Write-Warning (Get-ADFSTkLanguageText logEventLogNameNotExist)
            }
        }
        
        if ($SetEventLogSource -ne [string]::Empty)
        { 
            Write-Verbose (Get-ADFSTkLanguageText logSettingXPathTo -f 'SetEventLogSource', $SetLogFilePath)
            $global:EventLogSource = $SetEventLogSource
        }
    }
    elseif ($PsCmdlet.ParameterSetName -eq "Get")
    {
        if ($GetLogFilePath) { $LogFilePath }
        if ($GetEventLogName) { $EventLogName }
        if ($GetEventLogSource) { $EventLogSource }
    }
}
Process {
    ### Write main script below ###
    if ($PsCmdlet.ParameterSetName -eq "Default")
    {
        if ($MajorFault) { $EntryType = "Error" }
        if ($verbosePreference -eq "Continue") { $Category = 4 }
        
        $CurrentTime = (Get-Date).ToString()
        
        if (!$Screen.IsPresent -and !$File.IsPresent -and !$EventLog.IsPresent)
        {
            $Screen = $true

            if ($EventLogName -ne $null -and $EventLogSource -ne $null)
            {
                $EventLog = $true
            }

            if ($LogFilePath -ne $null)
            {
                $File = $true
            }
        }
        
        if ($Screen -and -not $MajorFault -and -not $Silent)
        { 
            #Write-Verbose "Logging to Screen..."
            
            if (!$SkipDateTime) 
            {
                Write-Host "$($CurrentTime): " -ForegroundColor DarkYellow -NoNewline
            }
            
            if ($EntryType -eq "Error")
            { 
                Write-Error $Message
                if ($Underline) { Write-Error "$([string]::Empty.PadLeft($ScreenMessage.Length,$UnderlineChar))" }
            }
            elseif ($EntryType -eq "Warning")
            {
                Write-Warning $Message
                if ($Underline) { Write-Warning "$([string]::Empty.PadLeft($ScreenMessage.Length,$UnderlineChar))" }
            }
            else
            {
                if ($verbosePreference -eq "Continue")
                { 
                    Write-Verbose $Message
                    if ($Underline) { Write-Verbose "$([string]::Empty.PadLeft($ScreenMessage.Length,$UnderlineChar))" }
                }
                else 
                { 
                    Write-Host $Message -ForegroundColor $ForegroundColor
                    if ($Underline) { Write-Host "$([string]::Empty.PadLeft($ScreenMessage.Length,$UnderlineChar))" }
                    
                }
            }
        }
        
        if ($File) 
        {
            if ($LogFilePath -eq [string]::Empty) { Write-Warning (Get-ADFSTkLanguageText logLogFilePathNotSet) }
            else
            {
                $FileMessage = ""
                if (!$SkipDateTime) 
                {
                    $FileMessage = "$CurrentTime - "
                }
                 $FileMessage += "$($EntryType): $Message"

                #Write-Verbose "Logging to File `'$LoggFilePath`'..."
                Add-Content -Path $LogFilePath -Value $FileMessage
                if ($Underline) { Add-Content -Path $LogFilePath -Value "$([string]::Empty.PadLeft($FileMessage.Length,$UnderlineChar))" }
            }
        }
        
        if ($EventLog)
        { 
            if ($EventLogName -eq [string]::Empty) { Write-Warning (Get-ADFSTkLanguageText logEventLogNameNotSet) }
            elseif ($EventLogSource -eq [string]::Empty) { Write-Warning (Get-ADFSTkLanguageText logEventSourceNotSet) }
            else
            {
                #Write-Verbose "Logging to EventLog `'$EventLogName`' as Source `'$EventLogSource`'..."
            
                Write-EventLog -LogName $EventLogName -Source $EventLogSource -EventId $EventID -Message $Message -EntryType $EntryType -Category $Category    
            }
        }

        if($EntryType -eq "Warning")
        {
            $global:Warnings++
            $global:LastWarning = $Message
        }
        elseif($EntryType -eq "Error")
        {
            $global:Errors++
            $global:LastError = $Message
        }
        
        if ($MajorFault) { throw $Message }   
    }
}
<#
.SYNOPSIS
Use this cmdlet to add logging to your script. Can log to Screen/File and EventLog
 
.DESCRIPTION
Start by setting FilePath and/or EventLogName/EventLogSource. The values are stored in global variables and don't need to be set again.
 
Call Write-ADFSTkLog with one or more parameters depending on how much logging needed.
 
If a Warning is logged the following global variables will be changed:
$Warnings will increase with 1
$LastWarning will be set to $Message
 
If an Error is logged the following global variables will be changed:
$Errors will increase with 1
$LastError will be set to $Message
 
If -MajorFault is provided, EntryType will automatically be set as Error and after logging has been done, the Message will be thrown.
 
If a variable namned $Silent is used and equals $true in the script calling Write-ADFSTkLog, no logging to screen will be done
 
.EXAMPLE
C:\PS> Write-ADFSTkLog -Message "Hello World!"
2012-02-02 16:40:16: Hello World!
 
-Message parameter are not needed as long as the message is written first
 
C:\PS> Write-ADFSTkLog "Hello World!" -EntryType Warning
WARNING: 2012-02-02 16:41:23: Hello World!
 
C:\PS> Write-ADFSTkLog -SetLogFilePath C:\Logs\myLogfile.txt
C:\PS> Write-ADFSTkLog "Hello textfile!" -File -Screen -Underline
2012-02-02 16:46:31: Hello textfile!
------------------------------------
.EXAMPLE
If none of the parameters (-Screen, -File or -EventLog) is provided, all defined ways will be used.
Default will only be the screen, a -SetLogFilePath has been set, the logging will be to screen and file, etc
 
C:\PS> Write-ADFSTkLog -SetLogFilePath C:\Logs\myLogfile.txt
C:\PS> Write-ADFSTkLog "Look, I don't use any parameters! :)"
2012-02-02 16:59:46: Look, I don't use any parameters! :)
 
C:\PS> Get-Content $LogFilePath
2012-02-02 16:46:31 - Information: Hello textfile!
--------------------------------------------------
2012-02-02 16:59:46 - Information: Look, I don't use any parameters! :)
 
C:\PS> Write-ADFSTkLog "Something isn't quite right!" -EntryType Warning
WARNING: 2012-02-02 17:00:45: Something isn't quite right!
 
C:\PS> Get-Content $LogFilePath
2012-02-02 16:46:31 - Information: Hello textfile!
--------------------------------------------------
2012-02-02 16:59:46 - Information: Look, I don't use any parameters! :)
2012-02-02 17:00:45 - Warning: Something isn't quite right!
C:PS> $Warnings
2
C:PS> $Errors
0
C:PS> $LastWarning
Something isn't quite right!
#>

}

function Write-ADFSTkVerboseLog {
[CmdletBinding(SupportsShouldProcess=$true)] 
param (
    [parameter(Position=0)]
    [ValidateNotNullOrEmpty()]
    [string]
    #The message to be written in the log...
    $Message,
    [string]
    #Used in LogFile and on Screen to clarify the message. In EventLog the Level on the event is set to EntryType. Default is Information
    [ValidateSet("Information", "Error", "Warning")]
    $EntryType="Information",
    [switch]
    #Use this to log to EventLog
    $EventLog,
    [switch]
    #Use this to log to file
    $File,
    [int]
    #The EventID if EventLog is used
    $EventID
)
    if ($verbosePreference -eq "Continue")
    { 
        if (!$File.IsPresent -and !$EventLog.IsPresent)
        {
            if ($EventLogName -ne $null -and $EventLogSource -ne $null)
            {
                $EventLog = $true
            }

            if ($LogFilePath -ne $null)
            {
                $File = $true
            }
        }

        if ($EventLog)
        {
            Write-ADFSTkLog -Message $Message -EventLog -EventID $EventID -EntryType $EntryType
        }
        
        if($File)
        {
            Write-ADFSTkLog -Message $Message -File -EventID $EventID -EntryType $EntryType
        }
        
        Write-ADFSTkLog -Message $Message -EntryType $EntryType -Screen
        
    }
<#
.SYNOPSIS
Use this cmdlet to add Verbose-logging to your script. Logging will always be to screen, but can also be done to File and/or EventLog
 
.DESCRIPTION
Start by setting FilePath and/or EventLogName/EventLogSource with Write-ADFSTkLog.
 
Category will always be set to 4
 
.EXAMPLE
Scriptfile below (Test-Script.ps1)
---
[CmdletBinding(SupportsShouldProcess=$true)]
param()
 
Write-VerboseLiULog "This is a verbose message"
---
 
C:\PS> .\Test-Script.ps1
 
C:\PS> .\Test-Script.ps1 -Verbose
VERBOSE: This is a verbose message
.EXAMPLE
Scriptfile below (Test-Script.ps1)
---
[CmdletBinding(SupportsShouldProcess=$true)]
param()
 
Write-ADFSTkLog -SetLogFilePath .\myLogfile.txt
Write-VerboseLiULog "This is a verbose message"
---
 
C:\PS> .\Test-Script.ps1 -File -Verbose
VERBOSE: Setting LogFilePath to '.\myLogfile.txt'...
VERBOSE: 2012-01-04 12:56:50: This is a verbose message
 
C:\PS> Get-Content .\myLogfile.txt
2012-01-04 12:58:13 - Information: This is a verbose message
#>

}


# SIG # Begin signature block
# MIIRbgYJKoZIhvcNAQcCoIIRXzCCEVsCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUXwqcMZkt0Snjugjmsr/POsrX
# 13iggg51MIIEfTCCA2WgAwIBAgIDG+cVMA0GCSqGSIb3DQEBCwUAMGMxCzAJBgNV
# BAYTAlVTMSEwHwYDVQQKExhUaGUgR28gRGFkZHkgR3JvdXAsIEluYy4xMTAvBgNV
# BAsTKEdvIERhZGR5IENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcN
# MTQwMTAxMDcwMDAwWhcNMzEwNTMwMDcwMDAwWjCBgzELMAkGA1UEBhMCVVMxEDAO
# BgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdv
# RGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmlj
# YXRlIEF1dGhvcml0eSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
# AQEAv3FiCPH6WTT3G8kYo/eASVjpIoMTpsUgQwE7hPHmhUmfJ+r2hBtOoLTbcJjH
# MgGxBT4HTu70+k8vWTAi56sZVmvigAf88xZ1gDlRe+X5NbZ0TqmNghPktj+pA4P6
# or6KFWp/3gvDthkUBcrqw6gElDtGfDIN8wBmIsiNaW02jBEYt9OyHGC0OPoCjM7T
# 3UYH3go+6118yHz7sCtTpJJiaVElBWEaRIGMLKlDliPfrDqBmg4pxRyp6V0etp6e
# MAo5zvGIgPtLXcwy7IViQyU0AlYnAZG0O3AqP26x6JyIAX2f1PnbU21gnb8s51ir
# uF9G/M7EGwM8CetJMVxpRrPgRwIDAQABo4IBFzCCARMwDwYDVR0TAQH/BAUwAwEB
# /zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9BUFuIMGU2g/e
# MB8GA1UdIwQYMBaAFNLEsNKR1EwRcbNhyz2h/t2oatTjMDQGCCsGAQUFBwEBBCgw
# JjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZ29kYWRkeS5jb20vMDIGA1UdHwQr
# MCkwJ6AloCOGIWh0dHA6Ly9jcmwuZ29kYWRkeS5jb20vZ2Ryb290LmNybDBGBgNV
# HSAEPzA9MDsGBFUdIAAwMzAxBggrBgEFBQcCARYlaHR0cHM6Ly9jZXJ0cy5nb2Rh
# ZGR5LmNvbS9yZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsFAAOCAQEAWQtTvZKGEack
# e+1bMc8dH2xwxbhuvk679r6XUOEwf7ooXGKUwuN+M/f7QnaF25UcjCJYdQkMiGVn
# OQoWCcWgOJekxSOTP7QYpgEGRJHjp2kntFolfzq3Ms3dhP8qOCkzpN1nsoX+oYgg
# HFCJyNwq9kIDN0zmiN/VryTyscPfzLXs4Jlet0lUIDyUGAzHHFIYSaRt4bNYC8nY
# 7NmuHDKOKHAN4v6mF56ED71XcLNa6R+ghlO773z/aQvgSMO3kwvIClTErF0UZzds
# yqUvMQg3qm5vjLyb4lddJIGvl5echK1srDdMZvNhkREg5L4wn3qkKQmw4TRfZHcY
# QFHfjDCmrzCCBNAwggO4oAMCAQICAQcwDQYJKoZIhvcNAQELBQAwgYMxCzAJBgNV
# BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRow
# GAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UEAxMoR28gRGFkZHkgUm9v
# dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjAeFw0xMTA1MDMwNzAwMDBaFw0z
# MTA1MDMwNzAwMDBaMIG0MQswCQYDVQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTET
# MBEGA1UEBxMKU2NvdHRzZGFsZTEaMBgGA1UEChMRR29EYWRkeS5jb20sIEluYy4x
# LTArBgNVBAsTJGh0dHA6Ly9jZXJ0cy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5LzEz
# MDEGA1UEAxMqR28gRGFkZHkgU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eSAt
# IEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAueDLENSvdr3Uk2Lr
# MGS4gQhswwTZYheOL/8+Zc+PzmLmPFIc2hZFS1WreGtjg2KQzg9pbJnIGhSLTMxF
# M+qI3J6jryv+gGGdeVfEzy70PzA8XUf8mha8wzeWQVGOEUtU+Ci+0Iy+8DA4HvOw
# JvhmR2Nt3nEmR484R1PRRh2049wA6kWsvbxx2apvANvbzTA6eU9fTEf4He9bwsSd
# YDuxskOR2KQzTuqz1idPrSWKpcb01dCmrnQFZFeItURV1C0qOj74uL3pMgoClGTE
# FjpQ8Uqu53kzrwwgB3/o3wQ5wmkCbGNS+nfBG8h0h8i5kxhQVDVLaU68O9NJLh/c
# wdJS+wIDAQABo4IBGjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
# AQYwHQYDVR0OBBYEFEDCvSeOzDSDMKIz1/tss/C0LIDOMB8GA1UdIwQYMBaAFDqa
# hQcQZyi27/a9BUFuIMGU2g/eMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYY
# aHR0cDovL29jc3AuZ29kYWRkeS5jb20vMDUGA1UdHwQuMCwwKqAooCaGJGh0dHA6
# Ly9jcmwuZ29kYWRkeS5jb20vZ2Ryb290LWcyLmNybDBGBgNVHSAEPzA9MDsGBFUd
# IAAwMzAxBggrBgEFBQcCARYlaHR0cHM6Ly9jZXJ0cy5nb2RhZGR5LmNvbS9yZXBv
# c2l0b3J5LzANBgkqhkiG9w0BAQsFAAOCAQEACH5skxDIOLiWqZBL/6FfTwTvbD6c
# iAbJUI+mc/dXMRu+vOQv2/i601vgtOfmeWIODKLXamNzMbX1qEikOwgtol2Q17R8
# JU8RVjDEtkSdeyyd5V7m7wxhqr/kKhvuhJ64g33BQ85EpxNwDZEf9MgTrYNg2dhy
# qHMkHrWsIg7KF4liWEQbq4klAQAPzcQbYttRtNMPUSqb9Lxz/HbONqTN2dgs6q6b
# 9SqykNFNdRiKP4pBkCN9W0v+pANYm0ayw2Bgg/h9UEHOwqGQw7vvAi/SFVTuRBXZ
# Cq6nijPtsS12NibcBOuf92EfFdyHb+5GliitoSZ9CgmnLgSjjbz4vAQwATCCBRww
# ggQEoAMCAQICCDeMqUwECkf0MA0GCSqGSIb3DQEBCwUAMIG0MQswCQYDVQQGEwJV
# UzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEaMBgGA1UE
# ChMRR29EYWRkeS5jb20sIEluYy4xLTArBgNVBAsTJGh0dHA6Ly9jZXJ0cy5nb2Rh
# ZGR5LmNvbS9yZXBvc2l0b3J5LzEzMDEGA1UEAxMqR28gRGFkZHkgU2VjdXJlIENl
# cnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTIwMDEwODExMjIyNFoXDTIxMDMw
# ODE4NTgwMFowXjELMAkGA1UEBhMCQ0ExEDAOBgNVBAgTB09udGFyaW8xDzANBgNV
# BAcTBk90dGF3YTEVMBMGA1UEChMMQ0FOQVJJRSBJbmMuMRUwEwYDVQQDEwxDQU5B
# UklFIEluYy4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZhfCjFqiT
# mN1uLoySixnwaOjf/ZAL9P6SvjlCaBA2mutoorEgnzUP8HnOIcvMRgEMPmpaZ8eg
# M93Bmx9d41xoarsQpCN3DhYOo+b3fWnPucVtpxbul2OFePv63mw/uvr+dqkv4b/f
# 3Tg+ilQbpsNonbvh9MKEFv8Pn9koj0ySV+qxz34PxTVAe6g//pel3/3i9fqilCnI
# Ecx4zg/+NKBeOWROSs4oXo3IvBjVrunmz+YuieSr78TqIE6hD8JF2q1wKwfMB3+x
# 7dEXZAus9WtIU/qITATtEfO9QAgrrYL4F1MLN+osSp8my5eCOjnLTQc47q574V3z
# QhsIHW7yBXLdAgMBAAGjggGFMIIBgTAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoG
# CCsGAQUFBwMDMA4GA1UdDwEB/wQEAwIHgDA1BgNVHR8ELjAsMCqgKKAmhiRodHRw
# Oi8vY3JsLmdvZGFkZHkuY29tL2dkaWcyczUtNS5jcmwwXQYDVR0gBFYwVDBIBgtg
# hkgBhv1tAQcXAjA5MDcGCCsGAQUFBwIBFitodHRwOi8vY2VydGlmaWNhdGVzLmdv
# ZGFkZHkuY29tL3JlcG9zaXRvcnkvMAgGBmeBDAEEATB2BggrBgEFBQcBAQRqMGgw
# JAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmdvZGFkZHkuY29tLzBABggrBgEFBQcw
# AoY0aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5L2dk
# aWcyLmNydDAfBgNVHSMEGDAWgBRAwr0njsw0gzCiM9f7bLPwtCyAzjAdBgNVHQ4E
# FgQUUPnMg2nmYS8l7rmax3weVkrgz5AwDQYJKoZIhvcNAQELBQADggEBAIYabiAR
# aY4KhO6oWgNHPOBjoHuqUH7NwRGN/ztYJznRBZbdD50smoK5GR0FvUZ8TXhYoZOa
# zXe4NlFM4e6YcudU+EA/OF+sZHFBWziz1VS6U3sS+cGyJcxvelSoid0q3W3i9/Zy
# 6Nv2kk/DEJp49O47mPNovpL15yykX3Vo26GwC9peo4s/cKMzthmgrcF2uLkT+LW4
# 4xKhaL7nBTGDMhjno+a3t00SWCId7wzgQadIJ1QlFOKm0xgmuiW3LIqCG0apvaOf
# vWKTPKq68q+FbDPOO48oKrvw1c9K/m8gcnBLz6PX1REVIs5u3pvdOYBCz6uXyKxn
# t+Q5jDEK0NskLu0xggJjMIICXwIBATCBwTCBtDELMAkGA1UEBhMCVVMxEDAOBgNV
# BAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFk
# ZHkuY29tLCBJbmMuMS0wKwYDVQQLEyRodHRwOi8vY2VydHMuZ29kYWRkeS5jb20v
# cmVwb3NpdG9yeS8xMzAxBgNVBAMTKkdvIERhZGR5IFNlY3VyZSBDZXJ0aWZpY2F0
# ZSBBdXRob3JpdHkgLSBHMgIIN4ypTAQKR/QwCQYFKw4DAhoFAKB4MBgGCisGAQQB
# gjcCAQwxCjAIoAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYK
# KwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkEMRYEFPkyQxl3
# 6Mc9syfpz+9/MpOVMMGDMA0GCSqGSIb3DQEBAQUABIIBAHgM0oaXUqZ2Ns7983wA
# hWTbcbf9yRionmaL9jSrqMWCpMjpAIosWesZSIWNCQlfquH6yiy/sIKv7mcpJNNQ
# sy1ER+UKb3a/YolpZ82MSBkS6V7qYYefyGdmwEf850wTXQ9u3lv+2F0+6NAvrzeV
# KmzTETQ4TqMftxiZyq396HmrppnHrT+7Goip+RS10JjBUo2aPo+jHxOLHsGqovgP
# bv/ZORl8CfMzXRfVdvU1RaWrwApJqzueKXWveYLimzQTOb2OLhre1n9zjEMU6nqi
# y9Dbgkve64qiDyumeu+cAzff6Vn8uV1bvSbKGOivtZKfqrnw6zabMyGqxSmQ5Qh0
# 8EA=
# SIG # End signature block