AuditPolicy.psm1

function Get-PSRegistry {
    <#
    .SYNOPSIS
    Get registry key values.
 
    .DESCRIPTION
    Get registry key values.
 
    .PARAMETER RegistryPath
    The registry path to get the values from.
 
    .PARAMETER ComputerName
    The computer to get the values from. If not specified, the local computer is used.
 
    .EXAMPLE
    Get-PSRegistry -RegistryPath 'HKLM\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters' -ComputerName AD1
 
    .EXAMPLE
    Get-PSRegistry -RegistryPath 'HKLM\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters'
 
    .EXAMPLE
    Get-PSRegistry -RegistryPath "HKLM\SYSTEM\CurrentControlSet\Services\DFSR\Parameters" -ComputerName AD1,AD2,AD3 | ft -AutoSize
 
    .EXAMPLE
    Get-PSRegistry -RegistryPath 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Directory Service'
 
    .EXAMPLE
    Get-PSRegistry -RegistryPath 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Windows PowerShell' | Format-Table -AutoSize
 
    .EXAMPLE
    Get-PSRegistry -RegistryPath 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Directory Service' -ComputerName AD1 -Advanced
 
    .EXAMPLE
    Get-PSRegistry -RegistryPath "HKLM:\Software\Microsoft\Powershell\1\Shellids\Microsoft.Powershell\"
 
    .EXAMPLE
    # Get default key and it's value
    Get-PSRegistry -RegistryPath "HKEY_CURRENT_USER\Tests" -Key ""
 
    .EXAMPLE
    # Get default key and it's value (alternative)
o Get-PSRegistry -RegistryPath "HKEY_CURRENT_USER\Tests" -DefaultKey
 
    .NOTES
    General notes
    #>

    [cmdletbinding()]
    param([alias('Path')][string[]] $RegistryPath,
        [string[]] $ComputerName = $Env:COMPUTERNAME,
        [string] $Key,
        [switch] $Advanced,
        [switch] $DefaultKey)
    Get-PSRegistryDictionaries
    $RegistryPath = foreach ($R in $RegistryPath) {
        If ($R -like '*:*') {
            foreach ($DictionaryKey in $Script:Dictionary.Keys) {
                if ($R.StartsWith($DictionaryKey, [System.StringComparison]::CurrentCultureIgnoreCase)) {
                    $R -replace $DictionaryKey, $Script:Dictionary[$DictionaryKey]
                    break
                }
            }
        } else { $R }
    }
    [Array] $Computers = Get-ComputerSplit -ComputerName $ComputerName
    [Array] $RegistryTranslated = Get-PSConvertSpecialRegistry -RegistryPath $RegistryPath -Computers $ComputerName -HiveDictionary $Script:HiveDictionary
    if ($PSBoundParameters.ContainsKey("Key") -or $DefaultKey) {
        [Array] $RegistryValues = Get-PSSubRegistryTranslated -RegistryPath $RegistryTranslated -HiveDictionary $Script:HiveDictionary -Key $Key
        foreach ($Computer in $Computers[0]) { foreach ($R in $RegistryValues) { Get-PSSubRegistry -Registry $R -ComputerName $Computer } }
        foreach ($Computer in $Computers[1]) { foreach ($R in $RegistryValues) { Get-PSSubRegistry -Registry $R -ComputerName $Computer -Remote } }
    } else {
        [Array] $RegistryValues = Get-PSSubRegistryTranslated -RegistryPath $RegistryTranslated -HiveDictionary $Script:HiveDictionary
        foreach ($Computer in $Computers[0]) { foreach ($R in $RegistryValues) { Get-PSSubRegistryComplete -Registry $R -ComputerName $Computer -Advanced:$Advanced } }
        foreach ($Computer in $Computers[1]) { foreach ($R in $RegistryValues) { Get-PSSubRegistryComplete -Registry $R -ComputerName $Computer -Remote -Advanced:$Advanced } }
    }
}
function Set-PSRegistry {
    <#
    .SYNOPSIS
    Sets/Updates registry entries locally and remotely using .NET methods.
 
    .DESCRIPTION
    Sets/Updates registry entries locally and remotely using .NET methods. If the registry path to key doesn't exists it will be created.
 
    .PARAMETER ComputerName
    The computer to run the command on. Defaults to local computer.
 
    .PARAMETER RegistryPath
    Registry Path to Update
 
    .PARAMETER Type
    Registry type to use. Options are: REG_SZ, REG_EXPAND_SZ, REG_BINARY, REG_DWORD, REG_MULTI_SZ, REG_QWORD, string, expandstring, binary, dword, multistring, qword
 
    .PARAMETER Key
    Registry key to set. If the path to registry key doesn't exists it will be created.
 
    .PARAMETER Value
    Registry value to set.
 
    .PARAMETER Suppress
    Suppresses the output of the command. By default the command outputs PSObject with the results of the operation.
 
    .EXAMPLE
    Set-PSRegistry -RegistryPath 'HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Diagnostics' -Type REG_DWORD -Key "16 LDAP Interface Events" -Value 2 -ComputerName AD1
 
    .EXAMPLE
    Set-PSRegistry -RegistryPath 'HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Diagnostics' -Type REG_SZ -Key "LDAP Interface Events" -Value 'test' -ComputerName AD1
 
    .EXAMPLE
    Set-PSRegistry -RegistryPath "HKCU:\\Tests" -Key "LimitBlankPass1wordUse" -Value "0" -Type REG_DWORD
 
    .EXAMPLE
    Set-PSRegistry -RegistryPath "HKCU:\\Tests\MoreTests\Tests1" -Key "LimitBlankPass1wordUse" -Value "0" -Type REG_DWORD
 
    .EXAMPLE
    # Setting default value
 
    $ValueData = [byte[]] @(
        0, 1, 0, 0, 9, 0, 0, 0, 128, 0, 0, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3,
        0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3,
        0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3,
        0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3,
        0, 3, 0, 0, 0, 5, 0, 10, 0, 14, 0, 3, 0, 5, 0, 6, 0, 6, 0, 4, 0, 4, 0
    )
    Set-PSRegistry -RegistryPath "HKEY_CURRENT_USER\Tests" -Key '' -Value $ValueData -Type 'NONE'
 
    .NOTES
    General notes
    #>

    [cmdletbinding(SupportsShouldProcess)]
    param([string[]] $ComputerName = $Env:COMPUTERNAME,
        [Parameter(Mandatory)][string] $RegistryPath,
        [Parameter(Mandatory)][ValidateSet('REG_SZ', 'REG_NONE', 'None', 'REG_EXPAND_SZ', 'REG_BINARY', 'REG_DWORD', 'REG_MULTI_SZ', 'REG_QWORD', 'string', 'binary', 'dword', 'qword', 'multistring', 'expandstring')][string] $Type,
        [Parameter()][string] $Key,
        [Parameter(Mandatory)][object] $Value,
        [switch] $Suppress)
    Get-PSRegistryDictionaries
    [Array] $ComputersSplit = Get-ComputerSplit -ComputerName $ComputerName
    If ($RegistryPath -like '*:*') {
        foreach ($DictionaryKey in $Script:Dictionary.Keys) {
            if ($RegistryPath.StartsWith($DictionaryKey, [System.StringComparison]::CurrentCultureIgnoreCase)) {
                $RegistryPath = $RegistryPath -replace $DictionaryKey, $Script:Dictionary[$DictionaryKey]
                break
            }
        }
    }
    $RegistryPath = $RegistryPath.Replace("\\", "\").Replace("\\", "\")
    [Array] $RegistryTranslated = Get-PSConvertSpecialRegistry -RegistryPath $RegistryPath -Computers $ComputerName -HiveDictionary $Script:HiveDictionary
    foreach ($Registry in $RegistryTranslated) {
        $RegistryValue = Get-PrivateRegistryTranslated -RegistryPath $Registry -HiveDictionary $Script:HiveDictionary -Key $Key -Value $Value -Type $Type -ReverseTypesDictionary $Script:ReverseTypesDictionary
        if ($RegistryValue.HiveKey) {
            foreach ($Computer in $ComputersSplit[0]) { Set-PrivateRegistry -RegistryValue $RegistryValue -Computer $Computer -Suppress:$Suppress.IsPresent -ErrorAction $ErrorActionPreference -WhatIf:$WhatIfPreference }
            foreach ($Computer in $ComputersSplit[1]) { Set-PrivateRegistry -RegistryValue $RegistryValue -Computer $Computer -Remote -Suppress:$Suppress.IsPresent -ErrorAction $ErrorActionPreference -WhatIf:$WhatIfPreference }
        } else { if ($PSBoundParameters.ErrorAction -eq 'Stop') { throw } else { Write-Warning "Set-PSRegistry - Setting registry to $Registry have failed. Couldn't translate HIVE." } }
    }
}
function Get-ComputerSplit {
    [CmdletBinding()]
    param([string[]] $ComputerName)
    if ($null -eq $ComputerName) { $ComputerName = $Env:COMPUTERNAME }
    try { $LocalComputerDNSName = [System.Net.Dns]::GetHostByName($Env:COMPUTERNAME).HostName } catch { $LocalComputerDNSName = $Env:COMPUTERNAME }
    $ComputersLocal = $null
    [Array] $Computers = foreach ($Computer in $ComputerName) {
        if ($Computer -eq '' -or $null -eq $Computer) { $Computer = $Env:COMPUTERNAME }
        if ($Computer -ne $Env:COMPUTERNAME -and $Computer -ne $LocalComputerDNSName) { $Computer } else { $ComputersLocal = $Computer }
    }
    , @($ComputersLocal, $Computers)
}
function Get-PrivateRegistryTranslated {
    [cmdletBinding()]
    param([Array] $RegistryPath,
        [System.Collections.IDictionary] $HiveDictionary,
        [System.Collections.IDictionary] $ReverseTypesDictionary,
        [Parameter(Mandatory)][ValidateSet('REG_SZ', 'REG_NONE', 'None', 'REG_EXPAND_SZ', 'REG_BINARY', 'REG_DWORD', 'REG_MULTI_SZ', 'REG_QWORD', 'string', 'binary', 'dword', 'qword', 'multistring', 'expandstring')][string] $Type,
        [Parameter()][string] $Key,
        [Parameter(Mandatory)][object] $Value)
    foreach ($Registry in $RegistryPath) {
        if ($Registry -is [string]) { $Registry = $Registry.Replace("\\", "\").Replace("\\", "\").TrimStart("\").TrimEnd("\") } else { $Registry.RegistryPath = $Registry.RegistryPath.Replace("\\", "\").Replace("\\", "\").TrimStart("\").TrimEnd("\") }
        foreach ($Hive in $HiveDictionary.Keys) {
            if ($Registry -is [string] -and $Registry.StartsWith($Hive, [System.StringComparison]::CurrentCultureIgnoreCase)) {
                if ($Hive.Length -eq $Registry.Length) {
                    [ordered] @{HiveKey = $HiveDictionary[$Hive]
                        SubKeyName      = $null
                        ValueKind       = [Microsoft.Win32.RegistryValueKind]::($ReverseTypesDictionary[$Type])
                        Key             = $Key
                        Value           = $Value
                    }
                } else {
                    [ordered] @{HiveKey = $HiveDictionary[$Hive]
                        SubKeyName      = $Registry.substring($Hive.Length + 1)
                        ValueKind       = [Microsoft.Win32.RegistryValueKind]::($ReverseTypesDictionary[$Type])
                        Key             = $Key
                        Value           = $Value
                    }
                }
                break
            } elseif ($Registry -isnot [string] -and $Registry.RegistryPath.StartsWith($Hive, [System.StringComparison]::CurrentCultureIgnoreCase)) {
                if ($Hive.Length -eq $Registry.RegistryPath.Length) {
                    [ordered] @{ComputerName = $Registry.ComputerName
                        HiveKey              = $HiveDictionary[$Hive]
                        SubKeyName           = $null
                        ValueKind            = [Microsoft.Win32.RegistryValueKind]::($ReverseTypesDictionary[$Type])
                        Key                  = $Key
                        Value                = $Value
                    }
                } else {
                    [ordered] @{ComputerName = $Registry.ComputerName
                        HiveKey              = $HiveDictionary[$Hive]
                        SubKeyName           = $Registry.RegistryPath.substring($Hive.Length + 1)
                        ValueKind            = [Microsoft.Win32.RegistryValueKind]::($ReverseTypesDictionary[$Type])
                        Key                  = $Key
                        Value                = $Value
                    }
                }
                break
            }
        }
    }
}
function Get-PSConvertSpecialRegistry {
    [cmdletbinding()]
    param([Array] $RegistryPath,
        [Array] $Computers,
        [System.Collections.IDictionary] $HiveDictionary)
    $FixedPath = foreach ($R in $RegistryPath) {
        foreach ($DictionaryKey in $HiveDictionary.Keys) {
            if ($R.StartsWith($DictionaryKey, [System.StringComparison]::CurrentCultureIgnoreCase)) {
                if ($HiveDictionary[$DictionaryKey] -in 'All', 'All+Default', 'Default', 'AllDomain+Default', 'AllDomain') {
                    foreach ($Computer in $Computers) {
                        $SubKeys = Get-PSRegistry -RegistryPath "HKEY_USERS" -ComputerName $Computer
                        if ($SubKeys.PSSubKeys) {
                            $RegistryKeys = ConvertTo-HKeyUser -SubKeys ($SubKeys.PSSubKeys | Sort-Object) -HiveDictionary $HiveDictionary -DictionaryKey $DictionaryKey
                            foreach ($S in $RegistryKeys) {
                                [PSCustomObject] @{ComputerName = $Computer
                                    RegistryPath                = $S
                                    Error                       = $null
                                    ErrorMessage                = $null
                                }
                            }
                        } else {
                            [PSCustomObject] @{ComputerName = $Computer
                                RegistryPath                = $R
                                Error                       = $true
                                ErrorMessage                = "Couldn't connect to $Computer to list HKEY_USERS"
                            }
                        }
                    }
                } else { $R }
                break
            }
        }
    }
    $FixedPath
}
function Get-PSRegistryDictionaries {
    [cmdletBinding()]
    param()
    if ($Script:Dictionary) { return }
    $Script:Dictionary = @{'HKUAD:' = 'HKEY_ALL_USERS_DEFAULT'
        'HKUA:'                     = 'HKEY_ALL_USERS'
        'HKUD:'                     = 'HKEY_DEFAULT_USER'
        'HKUDUD:'                   = 'HKEY_ALL_DOMAIN_USERS_DEFAULT'
        'HKUDU:'                    = 'HKEY_ALL_DOMAIN_USERS'
        'HKCR:'                     = 'HKEY_CLASSES_ROOT'
        'HKCU:'                     = 'HKEY_CURRENT_USER'
        'HKLM:'                     = 'HKEY_LOCAL_MACHINE'
        'HKU:'                      = 'HKEY_USERS'
        'HKCC:'                     = 'HKEY_CURRENT_CONFIG'
        'HKDD:'                     = 'HKEY_DYN_DATA'
        'HKPD:'                     = 'HKEY_PERFORMANCE_DATA'
    }
    $Script:HiveDictionary = [ordered] @{'HKEY_ALL_USERS_DEFAULT' = 'All+Default'
        'HKUAD'                                                   = 'All+Default'
        'HKEY_ALL_USERS'                                          = 'All'
        'HKUA'                                                    = 'All'
        'HKEY_ALL_DOMAIN_USERS_DEFAULT'                           = 'AllDomain+Default'
        'HKUDUD'                                                  = 'AllDomain+Default'
        'HKEY_ALL_DOMAIN_USERS'                                   = 'AllDomain'
        'HKUDU'                                                   = 'AllDomain'
        'HKEY_DEFAULT_USER'                                       = 'Default'
        'HKUD'                                                    = 'Default'
        'HKEY_CLASSES_ROOT'                                       = 'ClassesRoot'
        'HKCR'                                                    = 'ClassesRoot'
        'ClassesRoot'                                             = 'ClassesRoot'
        'HKCU'                                                    = 'CurrentUser'
        'HKEY_CURRENT_USER'                                       = 'CurrentUser'
        'CurrentUser'                                             = 'CurrentUser'
        'HKLM'                                                    = 'LocalMachine'
        'HKEY_LOCAL_MACHINE'                                      = 'LocalMachine'
        'LocalMachine'                                            = 'LocalMachine'
        'HKU'                                                     = 'Users'
        'HKEY_USERS'                                              = 'Users'
        'Users'                                                   = 'Users'
        'HKCC'                                                    = 'CurrentConfig'
        'HKEY_CURRENT_CONFIG'                                     = 'CurrentConfig'
        'CurrentConfig'                                           = 'CurrentConfig'
        'HKDD'                                                    = 'DynData'
        'HKEY_DYN_DATA'                                           = 'DynData'
        'DynData'                                                 = 'DynData'
        'HKPD'                                                    = 'PerformanceData'
        'HKEY_PERFORMANCE_DATA '                                  = 'PerformanceData'
        'PerformanceData'                                         = 'PerformanceData'
    }
    $Script:ReverseTypesDictionary = [ordered] @{'REG_SZ' = 'string'
        'REG_NONE'                                        = 'none'
        'REG_EXPAND_SZ'                                   = 'expandstring'
        'REG_BINARY'                                      = 'binary'
        'REG_DWORD'                                       = 'dword'
        'REG_MULTI_SZ'                                    = 'multistring'
        'REG_QWORD'                                       = 'qword'
        'string'                                          = 'string'
        'expandstring'                                    = 'expandstring'
        'binary'                                          = 'binary'
        'dword'                                           = 'dword'
        'multistring'                                     = 'multistring'
        'qword'                                           = 'qword'
        'none'                                            = 'none'
    }
}
function Get-PSSubRegistry {
    [cmdletBinding()]
    param([System.Collections.IDictionary] $Registry,
        [string] $ComputerName,
        [switch] $Remote)
    if ($Registry.ComputerName) { if ($Registry.ComputerName -ne $ComputerName) { return } }
    if (-not $Registry.Error) {
        try {
            if ($Remote) { $BaseHive = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($Registry.HiveKey, $ComputerName, 0) } else { $BaseHive = [Microsoft.Win32.RegistryKey]::OpenBaseKey($Registry.HiveKey, 0) }
            $PSConnection = $true
            $PSError = $null
        } catch {
            $PSConnection = $false
            $PSError = $($_.Exception.Message)
        }
    } else {
        $PSConnection = $false
        $PSError = $($Registry.ErrorMessage)
    }
    if ($PSError) {
        [PSCustomObject] @{PSComputerName = $ComputerName
            PSConnection                  = $PSConnection
            PSError                       = $true
            PSErrorMessage                = $PSError
            PSPath                        = $Registry.Registry
            PSKey                         = $Registry.Key
            PSValue                       = $null
            PSType                        = $null
        }
    } else {
        try {
            $SubKey = $BaseHive.OpenSubKey($Registry.SubKeyName, $false)
            if ($null -ne $SubKey) {
                [PSCustomObject] @{PSComputerName = $ComputerName
                    PSConnection                  = $PSConnection
                    PSError                       = $false
                    PSErrorMessage                = $null
                    PSPath                        = $Registry.Registry
                    PSKey                         = $Registry.Key
                    PSValue                       = $SubKey.GetValue($Registry.Key)
                    PSType                        = $SubKey.GetValueKind($Registry.Key)
                }
            } else {
                [PSCustomObject] @{PSComputerName = $ComputerName
                    PSConnection                  = $PSConnection
                    PSError                       = $true
                    PSErrorMessage                = "Registry path $($Registry.Registry) doesn't exists."
                    PSPath                        = $Registry.Registry
                    PSKey                         = $Registry.Key
                    PSValue                       = $null
                    PSType                        = $null
                }
            }
        } catch {
            [PSCustomObject] @{PSComputerName = $ComputerName
                PSConnection                  = $PSConnection
                PSError                       = $true
                PSErrorMessage                = $_.Exception.Message
                PSPath                        = $Registry.Registry
                PSKey                         = $Registry.Key
                PSValue                       = $null
                PSType                        = $null
            }
        }
    }
}
function Get-PSSubRegistryComplete {
    [cmdletBinding()]
    param([System.Collections.IDictionary] $Registry,
        [string] $ComputerName,
        [switch] $Remote,
        [switch] $Advanced)
    if ($Registry.ComputerName) { if ($Registry.ComputerName -ne $ComputerName) { return } }
    if (-not $Registry.Error) {
        try {
            if ($Remote) { $BaseHive = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($R.HiveKey, $ComputerName, 0) } else { $BaseHive = [Microsoft.Win32.RegistryKey]::OpenBaseKey($R.HiveKey, 0) }
            $PSConnection = $true
            $PSError = $null
        } catch {
            $PSConnection = $false
            $PSError = $($_.Exception.Message)
        }
    } else {
        $PSConnection = $false
        $PSError = $($Registry.ErrorMessage)
    }
    if ($PSError) {
        [PSCustomObject] @{PSComputerName = $ComputerName
            PSConnection                  = $PSConnection
            PSError                       = $true
            PSErrorMessage                = $PSError
            PSSubKeys                     = $null
            PSPath                        = $Registry.Registry
            PSKey                         = $Registry.Key
        }
    } else {
        try {
            $SubKey = $BaseHive.OpenSubKey($Registry.SubKeyName, $false)
            if ($null -ne $SubKey) {
                $Object = [ordered] @{PSComputerName = $ComputerName
                    PSConnection                     = $PSConnection
                    PSError                          = $false
                    PSErrorMessage                   = $null
                    PSSubKeys                        = $SubKey.GetSubKeyNames()
                    PSPath                           = $Registry.Registry
                }
                $Keys = $SubKey.GetValueNames()
                foreach ($K in $Keys) {
                    if ($K -eq "") {
                        if ($Advanced) {
                            $Object['DefaultKey'] = [ordered] @{Value = $SubKey.GetValue($K)
                                Type                                  = $SubKey.GetValueKind($K)
                            }
                        } else { $Object['DefaultKey'] = $SubKey.GetValue($K) }
                    } else {
                        if ($Advanced) {
                            $Object[$K] = [ordered] @{Value = $SubKey.GetValue($K)
                                Type                        = $SubKey.GetValueKind($K)
                            }
                        } else { $Object[$K] = $SubKey.GetValue($K) }
                    }
                }
                [PSCustomObject] $Object
            } else {
                [PSCustomObject] @{PSComputerName = $ComputerName
                    PSConnection                  = $PSConnection
                    PSError                       = $true
                    PSErrorMessage                = "Registry path $($Registry.Registry) doesn't exists."
                    PSSubKeys                     = $null
                    PSPath                        = $Registry.Registry
                }
            }
        } catch {
            [PSCustomObject] @{PSComputerName = $ComputerName
                PSConnection                  = $PSConnection
                PSError                       = $true
                PSErrorMessage                = $_.Exception.Message
                PSSubKeys                     = $null
                PSPath                        = $Registry.Registry
            }
        }
    }
}
function Get-PSSubRegistryTranslated {
    [cmdletBinding()]
    param([Array] $RegistryPath,
        [System.Collections.IDictionary] $HiveDictionary,
        [string] $Key)
    foreach ($Registry in $RegistryPath) {
        if ($Registry -is [string]) { $Registry = $Registry.Replace("\\", "\").Replace("\\", "\").TrimStart("\").TrimEnd("\") } else { $Registry.RegistryPath = $Registry.RegistryPath.Replace("\\", "\").Replace("\\", "\").TrimStart("\").TrimEnd("\") }
        foreach ($Hive in $HiveDictionary.Keys) {
            if ($Registry -is [string] -and $Registry.StartsWith($Hive, [System.StringComparison]::CurrentCultureIgnoreCase)) {
                if ($Hive.Length -eq $Registry.Length) {
                    [ordered] @{Registry = $Registry
                        HiveKey          = $HiveDictionary[$Hive]
                        SubKeyName       = $null
                        Key              = if ($Key -eq "") { $null } else { $Key }
                        Error            = $null
                        ErrorMessage     = $null
                    }
                } else {
                    [ordered] @{Registry = $Registry
                        HiveKey          = $HiveDictionary[$Hive]
                        SubKeyName       = $Registry.substring($Hive.Length + 1)
                        Key              = if ($Key -eq "") { $null } else { $Key }
                        Error            = $null
                        ErrorMessage     = $null
                    }
                }
                break
            } elseif ($Registry -isnot [string] -and $Registry.RegistryPath.StartsWith($Hive, [System.StringComparison]::CurrentCultureIgnoreCase)) {
                if ($Hive.Length -eq $Registry.RegistryPath.Length) {
                    [ordered] @{ComputerName = $Registry.ComputerName
                        Registry             = $Registry.RegistryPath
                        HiveKey              = $HiveDictionary[$Hive]
                        SubKeyName           = $null
                        Key                  = if ($Key -eq "") { $null } else { $Key }
                        Error                = $Registry.Error
                        ErrorMessage         = $Registry.ErrorMessage
                    }
                } else {
                    [ordered] @{ComputerName = $Registry.ComputerName
                        Registry             = $Registry.RegistryPath
                        HiveKey              = $HiveDictionary[$Hive]
                        SubKeyName           = $Registry.RegistryPath.substring($Hive.Length + 1)
                        Key                  = if ($Key -eq "") { $null } else { $Key }
                        Error                = $Registry.Error
                        ErrorMessage         = $Registry.ErrorMessage
                    }
                }
                break
            }
        }
    }
}
function Set-PrivateRegistry {
    [cmdletBinding(SupportsShouldProcess)]
    param([System.Collections.IDictionary] $RegistryValue,
        [string] $Computer,
        [switch] $Remote,
        [switch] $Suppress)
    if ($RegistryValue.ComputerName) { if ($RegistryValue.ComputerName -ne $Computer) { return } }
    if ($PSCmdlet.ShouldProcess($Computer, "Setting registry $($RegistryValue.HiveKey)\$($RegistryValue.SubKeyName) on $($RegistryValue.Key) to $($RegistryValue.Value) of $($RegistryValue.ValueKind)")) {
        try {
            if ($Remote) { $BaseHive = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($RegistryValue.HiveKey, $Computer, 0) } else { $BaseHive = [Microsoft.Win32.RegistryKey]::OpenBaseKey($RegistryValue.HiveKey, 0) }
            $PSConnection = $true
            $PSError = $null
        } catch {
            $PSConnection = $false
            $PSError = $($_.Exception.Message)
            if ($PSBoundParameters.ErrorAction -eq 'Stop') { throw } else { Write-Warning "Set-PSRegistry - Setting registry $($RegistryValue.HiveKey)\$($RegistryValue.SubKeyName) on $($RegistryValue.Key) to $($RegistryValue.Value) of $($RegistryValue.ValueKind) on $Computer have failed. Error: $($_.Exception.Message.Replace([System.Environment]::NewLine, " "))" }
        }
        if ($PSError) {
            if (-not $Suppress) {
                [PSCustomObject] @{PSComputerName = $Computer
                    PSConnection                  = $PSConnection
                    PSError                       = $true
                    PSErrorMessage                = $PSError
                    Path                          = "$($RegistryValue.HiveKey)\$($RegistryValue.SubKeyName)"
                    Key                           = $RegistryValue.Key
                    Value                         = $RegistryValue.Value
                    Type                          = $RegistryValue.ValueKind
                }
            }
        } else {
            try {
                $SubKey = $BaseHive.OpenSubKey($RegistryValue.SubKeyName, $true)
                if (-not $SubKey) {
                    $SubKeysSplit = $RegistryValue.SubKeyName.Split('\')
                    $SubKey = $BaseHive.OpenSubKey($SubKeysSplit[0], $true)
                    if (-not $SubKey) { $SubKey = $BaseHive.CreateSubKey($SubKeysSplit[0]) }
                    $SubKey = $BaseHive.OpenSubKey($SubKeysSplit[0], $true)
                    foreach ($S in $SubKeysSplit | Select-Object -Skip 1) { $SubKey = $SubKey.CreateSubKey($S) }
                }
                if ($RegistryValue.ValueKind -eq [Microsoft.Win32.RegistryValueKind]::MultiString) { $SubKey.SetValue($RegistryValue.Key, [string[]] $RegistryValue.Value, $RegistryValue.ValueKind) } elseif ($RegistryValue.ValueKind -in [Microsoft.Win32.RegistryValueKind]::None, [Microsoft.Win32.RegistryValueKind]::Binary) { $SubKey.SetValue($RegistryValue.Key, [byte[]] $RegistryValue.Value, $RegistryValue.ValueKind) } else { $SubKey.SetValue($RegistryValue.Key, $RegistryValue.Value, $RegistryValue.ValueKind) }
                if (-not $Suppress) {
                    [PSCustomObject] @{PSComputerName = $Computer
                        PSConnection                  = $PSConnection
                        PSError                       = $false
                        PSErrorMessage                = $null
                        Path                          = "$($RegistryValue.HiveKey)\$($RegistryValue.SubKeyName)"
                        Key                           = $RegistryValue.Key
                        Value                         = $RegistryValue.Value
                        Type                          = $RegistryValue.ValueKind
                    }
                }
            } catch {
                if ($PSBoundParameters.ErrorAction -eq 'Stop') { throw } else { Write-Warning "Set-PSRegistry - Setting registry $($RegistryValue.HiveKey)\$($RegistryValue.SubKeyName) on $($RegistryValue.Key) to $($RegistryValue.Value) of $($RegistryValue.ValueKind) on $Computer have failed. Error: $($_.Exception.Message.Replace([System.Environment]::NewLine, " "))" }
                if (-not $Suppress) {
                    [PSCustomObject] @{PSComputerName = $Computer
                        PSConnection                  = $PSConnection
                        PSError                       = $true
                        PSErrorMessage                = $_.Exception.Message
                        Path                          = "$($RegistryValue.HiveKey)\$($RegistryValue.SubKeyName)"
                        Key                           = $RegistryValue.Key
                        Value                         = $RegistryValue.Value
                        Type                          = $RegistryValue.ValueKind
                    }
                }
            }
        }
    }
}
function ConvertTo-HkeyUser {
    [CmdletBinding()]
    param([System.Collections.IDictionary] $HiveDictionary,
        [Array] $SubKeys,
        [string] $DictionaryKey)
    foreach ($Sub in $Subkeys) { if ($HiveDictionary[$DictionaryKey] -eq 'All') { if ($Sub -notlike "*_Classes*" -and $Sub -ne '.DEFAULT') { $R.Replace($DictionaryKey, "Users\$Sub") } } elseif ($HiveDictionary[$DictionaryKey] -eq 'All+Default') { if ($Sub -notlike "*_Classes*") { $R.Replace($DictionaryKey, "Users\$Sub") } } elseif ($HiveDictionary[$DictionaryKey] -eq 'Default') { if ($Sub -eq '.DEFAULT') { $R.Replace($DictionaryKey, "Users\.DEFAULT") } } elseif ($HiveDictionary[$DictionaryKey] -eq 'AllDomain+Default') { if (($Sub.StartsWith("S-1-5-21") -and $Sub -notlike "*_Classes*") -or $Sub -eq '.DEFAULT') { $R.Replace($DictionaryKey, "Users\$Sub") } } elseif ($HiveDictionary[$DictionaryKey] -eq 'AllDomain') { if ($Sub.StartsWith("S-1-5-21") -and $Sub -notlike "*_Classes*") { $R.Replace($DictionaryKey, "Users\$Sub") } } }
}
function Clear-SystemAuditPolicy {
    <#
    .SYNOPSIS
    Clears all audit policies to their default values (Not Configured)
 
    .DESCRIPTION
    Clears all audit policies to their default values (Not Configured)
 
    .PARAMETER ComputerName
    ComputerName for remote system to clear audit policy from. Requires permissions on the destination.
 
    .EXAMPLE
    Clear-SystemAuditPolicy -WhatIf
 
    .NOTES
    General notes
    #>

    [cmdletBinding(SupportsShouldProcess)]
    param([string] $ComputerName)
    $CurrentPolicies = Get-SystemAuditPolicy -ComputerName $ComputerName
    foreach ($Policy in $CurrentPolicies.Keys) {
        $SubPolicies = $CurrentPolicies[$Policy]
        foreach ($Sub in $SubPolicies.Keys) {
            if ($SubPolicies[$Sub] -ne 'NotConfigured') {
                $setSystemAuditPolicySplat = @{"$Policy" = $Sub
                    ComputerName                         = $ComputerName
                    WhatIf                               = $WhatIfPreference
                    Value                                = 'NotConfigured'
                }
                $Success = Set-SystemAuditPolicy @setSystemAuditPolicySplat
                if ($Success.PSError -eq $false -and $Success.PSConnection -eq $true) {} else { Write-Warning -Message " Clear-SystemAuditPolicy - Failed to clear $Policy\$Sub. Error: $($Success.PSErrorMessage)" }
            }
        }
    }
}
function Get-SystemAuditPolicy {
    <#
    .SYNOPSIS
    Small functions that reads Audit Policy (the same way as auditpol.exe) and returns a hashtable with the values.
 
    .DESCRIPTION
    Small functions that reads Audit Policy (the same way as auditpol.exe) and returns a hashtable with the values.
 
    .PARAMETER ComputerName
    ComputerName for remote system to read audit policy from. Requires permissions on the destination.
 
    .EXAMPLE
    $AuditPolicies = Get-SystemAuditPolicy
    $AuditPolicies | Format-Table
    $AuditPolicies.AccountLogon | Format-Table
    $AuditPolicies.AccountManagement | Format-Table
    $AuditPolicies.DetailedTracking | Format-Table
 
    .NOTES
    General notes
    #>

    [CmdletBinding()]
    param([string] $ComputerName)
    Add-Type -TypeDefinition @"
        using System;
 
        namespace AuditPolicies
        {
            public enum Events {
                NotConfigured = 0,
                Success = 1,
                Failure = 2,
                SuccessAndFailure = 3
            }
        }
"@

    $Audit = Get-PSRegistry -RegistryPath "HKEY_LOCAL_MACHINE\SECURITY\Policy\PolAdtEv" -Key "" -ComputerName $ComputerName
    if ($Audit.PSConnection -eq $true -and $Audit.PSError -eq $false) {
        $Data = $Audit.PSValue
        $AuditPolicies = [ordered] @{AccountLogon = [ordered] @{'CredentialValidation' = [AuditPolicies.Events] $Data[122]
                'KerberosServiceTicketOperations'                                      = [AuditPolicies.Events] $Data[124]
                'OtherAccountLogonEvents'                                              = [AuditPolicies.Events] $Data[126]
                'KerberosAuthenticationService'                                        = [AuditPolicies.Events] $Data[128]
            }
            AccountManagement                     = [ordered] @{'UserAccountManagement' = [AuditPolicies.Events] $Data[102]
                'ComputerAccountManagement'                         = [AuditPolicies.Events] $Data[104]
                'SecurityGroupManagement'                           = [AuditPolicies.Events] $Data[106]
                'DistributionGroupManagement'                       = [AuditPolicies.Events] $Data[108]
                'ApplicationGroupManagement'                        = [AuditPolicies.Events] $Data[110]
                'OtherAccountManagementEvents'                      = [AuditPolicies.Events] $Data[112]
            }
            DetailedTracking                      = [ordered] @{'ProcessCreation' = [AuditPolicies.Events] $Data[78]
                'ProcessTermination'                         = [AuditPolicies.Events] $Data[80]
                'DPAPIActivity'                              = [AuditPolicies.Events] $Data[82]
                'RPCEvents'                                  = [AuditPolicies.Events] $Data[84]
                'PNPActivity'                                = [AuditPolicies.Events] $Data[86]
                'TokenRightAdjusted'                         = [AuditPolicies.Events] $Data[88]
            }
            DSAccess                              = [ordered] @{'DirectoryServiceAccess' = [AuditPolicies.Events] $Data[114]
                'DirectoryServiceChanges'                   = [AuditPolicies.Events] $Data[116]
                'DirectoryServiceReplication'               = [AuditPolicies.Events] $Data[118]
                'DetailedDirectoryServiceReplication'       = [AuditPolicies.Events] $Data[120]
            }
            LogonLogoff                           = [ordered] @{'Logon' = [AuditPolicies.Events] $Data[22]
                'Logoff'                      = [AuditPolicies.Events] $Data[24]
                'AccountLockout'              = [AuditPolicies.Events] $Data[26]
                'IPSecMainMode'               = [AuditPolicies.Events] $Data[28]
                'SpecialLogon'                = [AuditPolicies.Events] $Data[30]
                'IPSecQuickMode'              = [AuditPolicies.Events] $Data[32]
                'IPSecExtendedMode'           = [AuditPolicies.Events] $Data[34]
                'OtherLogonLogoffEvents'      = [AuditPolicies.Events] $Data[36]
                'NetworkPolicyServer'         = [AuditPolicies.Events] $Data[38]
                'UserDeviceClaims'            = [AuditPolicies.Events] $Data[40]
                'GroupMembership'             = [AuditPolicies.Events] $Data[42]
            }
            ObjectAccess                          = [ordered] @{'FileSystem' = [AuditPolicies.Events] $Data[44]
                'Registry'                          = [AuditPolicies.Events] $Data[46]
                'KernelObject'                      = [AuditPolicies.Events] $Data[48]
                'SAM'                               = [AuditPolicies.Events] $Data[50]
                'OtherObjectAccessEvents'           = [AuditPolicies.Events] $Data[52]
                'CertificationServices'             = [AuditPolicies.Events] $Data[54]
                'ApplicationGenerated'              = [AuditPolicies.Events] $Data[56]
                'HandleManipulation'                = [AuditPolicies.Events] $Data[58]
                'FileShare'                         = [AuditPolicies.Events] $Data[60]
                'FilteringPlatformPacketDrop'       = [AuditPolicies.Events] $Data[62]
                'FilteringPlatformConnection'       = [AuditPolicies.Events] $Data[64]
                'DetailedFileShare'                 = [AuditPolicies.Events] $Data[66]
                'RemovableStorage'                  = [AuditPolicies.Events] $Data[68]
                'CentralAccessPolicyStaging'        = [AuditPolicies.Events] $Data[70]
            }
            PolicyChange                          = [ordered] @{'AuditPolicyChange' = [AuditPolicies.Events] $Data[90]
                'AuthenticationPolicyChange'               = [AuditPolicies.Events] $Data[92]
                'AuthorizationPolicyChange'                = [AuditPolicies.Events] $Data[94]
                'MPSSVCRuleLevelPolicyChange'              = [AuditPolicies.Events] $Data[96]
                'FilteringPlatformPolicyChange'            = [AuditPolicies.Events] $Data[98]
                'OtherPolicyChangeEvents'                  = [AuditPolicies.Events] $Data[100]
            }
            PrivilegeUse                          = [ordered] @{'SensitivePrivilegeUse' = [AuditPolicies.Events] $Data[72]
                'NonSensitivePrivilegeUse'                     = [AuditPolicies.Events] $Data[74]
                'OtherPrivilegeUseEvents'                      = [AuditPolicies.Events] $Data[76]
            }
            System                                = [ordered] @{'SecurityStateChange' = [AuditPolicies.Events] $Data[12]
                'SecuritySystemExtension'              = [AuditPolicies.Events] $Data[14]
                'SystemIntegrity'                      = [AuditPolicies.Events] $Data[16]
                'IPsecDriver'                          = [AuditPolicies.Events] $Data[18]
                'OtherSystemEvents'                    = [AuditPolicies.Events] $Data[20]
            }
        }
        $AuditPolicies
    } else { Write-Warning -Message "Get-SystemAuditPolicies - Audit policies couldn't be read: $($Audit.PSErrorMessage)" }
}
function Set-SystemAuditPolicy {
    <#
    .SYNOPSIS
    Sets the audit policy similary to what auditpol.exe does.
 
    .DESCRIPTION
    Sets the audit policy similary to what auditpol.exe does.
 
    .PARAMETER ComputerName
    ComputerName for remote system to clear audit policy from. Requires permissions on the destination.
 
    .PARAMETER AccountLogon
    Choose one of the options for the AccountLogon parameter.
 
    .PARAMETER AccountManagement
    Choose one of the options for the AccountManagement parameter.
 
    .PARAMETER DetailedTracking
    Choose one of the options for the DetailedTracking parameter.
 
    .PARAMETER DSAccess
    Choose one of the options for the DSAccess parameter.
 
    .PARAMETER LogonLogoff
    Choose one of the options for the LogonLogoff parameter.
 
    .PARAMETER ObjectAccess
    Choose one of the options for the ObjectAccess parameter.
 
    .PARAMETER PolicyChange
    Choose one of the options for the PolicyChange parameter.
 
    .PARAMETER PrivilegeUse
    Choose one of the options for the PrivilegeUse parameter.
 
    .PARAMETER System
    Choose one of the options for the System parameter.
 
    .PARAMETER Value
    Choose one of the options for the Value parameter.
 
    .EXAMPLE
    $WhatIf = $false
 
    Set-SystemAuditPolicy -AccountLogon KerberosServiceTicketOperations -Value Failure -Verbose -WhatIf:$WhatIf
    Set-SystemAuditPolicy -AccountLogon OtherAccountLogonEvents -Value Failure -Verbose -WhatIf:$WhatIf
    Set-SystemAuditPolicy -AccountLogon KerberosAuthenticationService -Value SuccessAndFailure -Verbose -WhatIf:$WhatIf
    Set-SystemAuditPolicy -AccountLogon CredentialValidation -Value Success -Verbose -WhatIf:$WhatIf
 
    Set-SystemAuditPolicy -AccountManagement ComputerAccountManagement -Value Failure -Verbose -WhatIf:$WhatIf
    Set-SystemAuditPolicy -AccountManagement ApplicationGroupManagement -Value Success -Verbose -WhatIf:$WhatIf
    Set-SystemAuditPolicy -AccountManagement DistributionGroupManagement -Value Failure -Verbose -WhatIf:$WhatIf
    Set-SystemAuditPolicy -AccountManagement OtherAccountManagementEvents -Value Failure -Verbose -WhatIf:$WhatIf
    Set-SystemAuditPolicy -AccountManagement SecurityGroupManagement -Value Failure -Verbose -WhatIf:$WhatIf
    Set-SystemAuditPolicy -AccountManagement UserAccountManagement -Value Failure -Verbose -WhatIf:$WhatIf
 
    .NOTES
    General notes
    #>

    [CmdletBinding(SupportsShouldProcess)]
    param([string] $ComputerName,
        [parameter(Mandatory, ParameterSetName = 'AccountLogon')][ValidateSet('CredentialValidation',
            'KerberosServiceTicketOperations',
            'OtherAccountLogonEvents',
            'KerberosAuthenticationService')][string] $AccountLogon,
        [parameter(Mandatory, ParameterSetName = 'AccountManagement')][ValidateSet('UserAccountManagement',
            'ComputerAccountManagement',
            'SecurityGroupManagement',
            'DistributionGroupManagement',
            'ApplicationGroupManagement',
            'OtherAccountManagementEvents')][string] $AccountManagement,
        [parameter(Mandatory, ParameterSetName = 'DetailedTracking')][ValidateSet('ProcessCreation',
            'ProcessTermination',
            'DPAPIActivity' ,
            'RPCEvents' ,
            'PNPActivity' ,
            'TokenRightAdjusted')][string] $DetailedTracking,
        [parameter(Mandatory, ParameterSetName = 'DSAccess')][ValidateSet('DirectoryServiceAccess',
            'DirectoryServiceChanges',
            'DirectoryServiceReplication',
            'DetailedDirectoryServiceReplication')][string] $DSAccess,
        [parameter(Mandatory, ParameterSetName = 'LogonLogoff')][ValidateSet('Logon',
            'Logoff',
            'AccountLockout',
            'IPSecMainMode',
            'SpecialLogon',
            'IPSecQuickMode',
            'IPSecExtendedMode',
            'OtherLogonLogoffEvents',
            'NetworkPolicyServer',
            'UserDeviceClaims',
            'GroupMembership')][string] $LogonLogoff,
        [parameter(Mandatory, ParameterSetName = 'ObjectAccess')][ValidateSet('FileSystem',
            'Registry',
            'KernelObject',
            'SAM',
            'OtherObjectAccessEvents',
            'CertificationServices',
            'ApplicationGenerated',
            'HandleManipulation',
            'FileShare',
            'FilteringPlatformPacketDrop',
            'FilteringPlatformConnection',
            'DetailedFileShare',
            'RemovableStorage',
            'CentralAccessPolicyStaging')][string] $ObjectAccess,
        [parameter(Mandatory, ParameterSetName = 'PolicyChange')][ValidateSet('FileSystem',
            'AuditPolicyChange',
            'AuthenticationPolicyChange',
            'AuthorizationPolicyChange',
            'MPSSVCRuleLevelPolicyChange',
            'FilteringPlatformPolicyChange',
            'OtherPolicyChangeEvents')][string] $PolicyChange,
        [parameter(Mandatory, ParameterSetName = 'PrivilegeUse')][ValidateSet('SensitivePrivilegeUse',
            'NonSensitivePrivilegeUse',
            'OtherPrivilegeUseEvents')][string] $PrivilegeUse,
        [parameter(Mandatory, ParameterSetName = 'System')][ValidateSet('SecurityStateChange',
            'SecuritySystemExtension',
            'SystemIntegrity',
            'IPsecDriver',
            'OtherSystemEvents')][string] $System,
        [parameter(Mandatory)][validateSet('NotConfigured', 'Success', 'Failure', 'SuccessAndFailure')][string] $Value)
    Add-Type -TypeDefinition @"
        using System;
 
        namespace AuditPolicies
        {
            public enum Events {
                NotConfigured = 0,
                Success = 1,
                Failure = 2,
                SuccessAndFailure = 3
            }
        }
"@

    $AuditValues = @{'NotConfigured' = 0
        'Success'                    = 1
        'Failure'                    = 2
        'SuccessAndFailure'          = 3
    }
    $AuditPoliciesByte = [ordered] @{AccountLogon = [ordered] @{'CredentialValidation' = 122
            'KerberosServiceTicketOperations'                                          = 124
            'OtherAccountLogonEvents'                                                  = 126
            'KerberosAuthenticationService'                                            = 128
        }
        AccountManagement                         = [ordered] @{'UserAccountManagement' = 102
            'ComputerAccountManagement'                         = 104
            'SecurityGroupManagement'                           = 106
            'DistributionGroupManagement'                       = 108
            'ApplicationGroupManagement'                        = 110
            'OtherAccountManagementEvents'                      = 112
        }
        DetailedTracking                          = [ordered] @{'ProcessCreation' = 78
            'ProcessTermination'                         = 80
            'DPAPIActivity'                              = 82
            'RPCEvents'                                  = 84
            'PNPActivity'                                = 86
            'TokenRightAdjusted'                         = 88
        }
        DSAccess                                  = [ordered] @{'DirectoryServiceAccess' = 114
            'DirectoryServiceChanges'                   = 116
            'DirectoryServiceReplication'               = 118
            'DetailedDirectoryServiceReplication'       = 120
        }
        LogonLogoff                               = [ordered] @{'Logon' = 22
            'Logoff'                      = 24
            'AccountLockout'              = 26
            'IPSecMainMode'               = 28
            'SpecialLogon'                = 30
            'IPSecQuickMode'              = 32
            'IPSecExtendedMode'           = 34
            'OtherLogonLogoffEvents'      = 36
            'NetworkPolicyServer'         = 38
            'UserDeviceClaims'            = 40
            'GroupMembership'             = 42
        }
        ObjectAccess                              = [ordered] @{'FileSystem' = 44
            'Registry'                          = 46
            'KernelObject'                      = 48
            'SAM'                               = 50
            'OtherObjectAccessEvents'           = 52
            'CertificationServices'             = 54
            'ApplicationGenerated'              = 56
            'HandleManipulation'                = 58
            'FileShare'                         = 60
            'FilteringPlatformPacketDrop'       = 62
            'FilteringPlatformConnection'       = 64
            'DetailedFileShare'                 = 66
            'RemovableStorage'                  = 68
            'CentralAccessPolicyStaging'        = 70
        }
        PolicyChange                              = [ordered] @{'AuditPolicyChange' = 90
            'AuthenticationPolicyChange'               = 92
            'AuthorizationPolicyChange'                = 94
            'MPSSVCRuleLevelPolicyChange'              = 96
            'FilteringPlatformPolicyChange'            = 98
            'OtherPolicyChangeEvents'                  = 100
        }
        PrivilegeUse                              = [ordered] @{'SensitivePrivilegeUse' = 72
            'NonSensitivePrivilegeUse'                     = 74
            'OtherPrivilegeUseEvents'                      = 76
        }
        System                                    = [ordered] @{'SecurityStateChange' = 12
            'SecuritySystemExtension'              = 14
            'SystemIntegrity'                      = 16
            'IPsecDriver'                          = 18
            'OtherSystemEvents'                    = 20
        }
    }
    $Audit = Get-PSRegistry -RegistryPath "HKEY_LOCAL_MACHINE\SECURITY\Policy\PolAdtEv" -Key "" -ComputerName $ComputerName
    if ($Audit.PSConnection -eq $true -and $Audit.PSError -eq $false) {} else {
        Write-Warning -Message "Set-SystemAuditPolicies - Audit policies couldn't be read: $($Audit.PSErrorMessage)"
        return
    }
    $BoundParameters = $PSBoundParameters
    $CurrentParameterSet = $PsCmdlet.ParameterSetName
    $ChosenParameter = $BoundParameters.$CurrentParameterSet
    if ($CurrentParameterSet) {
        $ByteNumber = $AuditPoliciesByte[$CurrentParameterSet][$ChosenParameter]
        $ExpectedValue = $AuditValues[$Value]
        $CurrentValue = $Audit.PSValue[$ByteNumber]
        $CurrentTranslatedValue = [AuditPolicies.Events] $CurrentValue
        $ExpectedTranslatedValue = [AuditPolicies.Events] $ExpectedValue
        Write-Verbose -Message "Set-SystemAuditPolicies - Current value for $CurrentParameterSet\$ChosenParameter is $CurrentTranslatedValue ($CurrentValue) to be replaced with $ExpectedTranslatedValue ($ExpectedValue)"
        if ($CurrentTranslatedValue -ne $ExpectedTranslatedValue) {
            $ValueToSet = $Audit.PSValue
            $ValueToSet[$ByteNumber] = $ExpectedValue
            $AuditOutput = Set-PSRegistry -RegistryPath "HKEY_LOCAL_MACHINE\SECURITY\Policy\PolAdtEv" -Key "" -ComputerName $ComputerName -Type None -Value $ValueToSet -WhatIf:$WhatIfPreference
            $AuditOutput
        } else { Write-Verbose -Message "Set-SystemAuditPolicies - Current value for $CurrentParameterSet\$ChosenParameter ($ByteNumber) is $CurrentTranslatedValue ($CurrentValue) - nothing to do." }
    }
}
Export-ModuleMember -Function @('Clear-SystemAuditPolicy', 'Get-SystemAuditPolicy', 'Set-SystemAuditPolicy') -Alias @()
# SIG # Begin signature block
# MIIhjgYJKoZIhvcNAQcCoIIhfzCCIXsCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUmBiw5sTZzIxzI3gvQHbwEpQA
# 5k6gghusMIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0B
# AQUFADBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
# VQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVk
# IElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQsw
# CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
# ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg
# Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg
# +XESpa7cJpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lT
# XDGEKvYPmDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5
# a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g
# 0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1
# roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf
# GHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0G
# A1UdDgQWBBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLL
# gjEtUYunpyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3
# cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmr
# EthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+
# fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5Q
# Z7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu
# 838fYxAe+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw
# 8jCCBTAwggQYoAMCAQICEAQJGBtf1btmdVNDtW+VUAgwDQYJKoZIhvcNAQELBQAw
# ZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
# d3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNzdXJlZCBJRCBS
# b290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowcjELMAkGA1UE
# BhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2lj
# ZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENvZGUg
# U2lnbmluZyBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPjTsxx/
# DhGvZ3cH0wsxSRnP0PtFmbE620T1f+Wondsy13Hqdp0FLreP+pJDwKX5idQ3Gde2
# qvCchqXYJawOeSg6funRZ9PG+yknx9N7I5TkkSOWkHeC+aGEI2YSVDNQdLEoJrsk
# acLCUvIUZ4qJRdQtoaPpiCwgla4cSocI3wz14k1gGL6qxLKucDFmM3E+rHCiq85/
# 6XzLkqHlOzEcz+ryCuRXu0q16XTmK/5sy350OTYNkO/ktU6kqepqCquE86xnTrXE
# 94zRICUj6whkPlKWwfIPEvTFjg/BougsUfdzvL2FsWKDc0GCB+Q4i2pzINAPZHM8
# np+mM6n9Gd8lk9ECAwEAAaOCAc0wggHJMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYD
# VR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMDMHkGCCsGAQUFBwEBBG0w
# azAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEMGCCsGAQUF
# BzAChjdodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVk
# SURSb290Q0EuY3J0MIGBBgNVHR8EejB4MDqgOKA2hjRodHRwOi8vY3JsNC5kaWdp
# Y2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3JsMDqgOKA2hjRodHRw
# Oi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3Js
# ME8GA1UdIARIMEYwOAYKYIZIAYb9bAACBDAqMCgGCCsGAQUFBwIBFhxodHRwczov
# L3d3dy5kaWdpY2VydC5jb20vQ1BTMAoGCGCGSAGG/WwDMB0GA1UdDgQWBBRaxLl7
# KgqjpepxA8Bg+S32ZXUOWDAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823I
# DzANBgkqhkiG9w0BAQsFAAOCAQEAPuwNWiSz8yLRFcgsfCUpdqgdXRwtOhrE7zBh
# 134LYP3DPQ/Er4v97yrfIFU3sOH20ZJ1D1G0bqWOWuJeJIFOEKTuP3GOYw4TS63X
# X0R58zYUBor3nEZOXP+QsRsHDpEV+7qvtVHCjSSuJMbHJyqhKSgaOnEoAjwukaPA
# JRHinBRHoXpoaK+bp1wgXNlxsQyPu6j4xRJon89Ay0BEpRPw5mQMJQhCMrI2iiQC
# /i9yfhzXSUWW6Fkd6fp0ZGuy62ZD2rOwjNXpDd32ASDOmTFjPQgaGLOBm0/GkxAG
# /AeB+ova+YJJ92JuoVP6EpQYhS6SkepobEQysmah5xikmmRR7zCCBT0wggQloAMC
# AQICEATV3B9I6snYUgC6zZqbKqcwDQYJKoZIhvcNAQELBQAwcjELMAkGA1UEBhMC
# VVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0
# LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENvZGUgU2ln
# bmluZyBDQTAeFw0yMDA2MjYwMDAwMDBaFw0yMzA3MDcxMjAwMDBaMHoxCzAJBgNV
# BAYTAlBMMRIwEAYDVQQIDAnFmmzEhXNraWUxETAPBgNVBAcTCEthdG93aWNlMSEw
# HwYDVQQKDBhQcnplbXlzxYJhdyBLxYJ5cyBFVk9URUMxITAfBgNVBAMMGFByemVt
# eXPFgmF3IEvFgnlzIEVWT1RFQzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
# ggEBAL+ygd4sga4ZC1G2xXvasYSijwWKgwapZ69wLaWaZZIlY6YvXTGQnIUnk+Tg
# 7EoT7mQiMSaeSPOrn/Im6N74tkvRfQJXxY1cnt3U8//U5grhh/CULdd6M3/Z4h3n
# MCq7LQ1YVaa4MYub9F8WOdXO84DANoNVG/t7YotL4vzqZil3S9pHjaidp3kOXGJc
# vxrCPAkRFBKvUmYo23QPFa0Rd0qA3bFhn97WWczup1p90y2CkOf28OVOOObv1fNE
# EqMpLMx0Yr04/h+LPAAYn6K4YtIu+m3gOhGuNc3B+MybgKePAeFIY4EQzbqvCMy1
# iuHZb6q6ggRyqrJ6xegZga7/gV0CAwEAAaOCAcUwggHBMB8GA1UdIwQYMBaAFFrE
# uXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBQYsTUn6BxQICZOCZA0CxS0TZSU
# ZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwdwYDVR0fBHAw
# bjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItYXNzdXJlZC1j
# cy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zaGEyLWFz
# c3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJYIZIAYb9bAMBMCowKAYIKwYB
# BQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQQBMIGE
# BggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0
# LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0Rp
# Z2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5nQ0EuY3J0MAwGA1UdEwEB/wQC
# MAAwDQYJKoZIhvcNAQELBQADggEBAJq9bM+JbCwEYuMBtXoNAfH1SRaMLXnLe0py
# VK6el0Z1BtPxiNcF4iyHqMNVD4iOrgzLEVzx1Bf/sYycPEnyG8Gr2tnl7u1KGSjY
# enX4LIXCZqNEDQCeTyMstNv931421ERByDa0wrz1Wz5lepMeCqXeyiawqOxA9fB/
# 106liR12vL2tzGC62yXrV6WhD6W+s5PpfEY/chuIwVUYXp1AVFI9wi2lg0gaTgP/
# rMfP1wfVvaKWH2Bm/tU5mwpIVIO0wd4A+qOhEia3vn3J2Zz1QDxEprLcLE9e3Gmd
# G5+8xEypTR23NavhJvZMgY2kEXBEKEEDaXs0LoPbn6hMcepR2A4wggauMIIElqAD
# AgECAhAHNje3JFR82Ees/ShmKl5bMA0GCSqGSIb3DQEBCwUAMGIxCzAJBgNVBAYT
# AlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2Vy
# dC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0yMjAz
# MjMwMDAwMDBaFw0zNzAzMjIyMzU5NTlaMGMxCzAJBgNVBAYTAlVTMRcwFQYDVQQK
# Ew5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1c3RlZCBHNCBS
# U0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0EwggIiMA0GCSqGSIb3DQEBAQUA
# A4ICDwAwggIKAoICAQDGhjUGSbPBPXJJUVXHJQPE8pE3qZdRodbSg9GeTKJtoLDM
# g/la9hGhRBVCX6SI82j6ffOciQt/nR+eDzMfUBMLJnOWbfhXqAJ9/UO0hNoR8XOx
# s+4rgISKIhjf69o9xBd/qxkrPkLcZ47qUT3w1lbU5ygt69OxtXXnHwZljZQp09ns
# ad/ZkIdGAHvbREGJ3HxqV3rwN3mfXazL6IRktFLydkf3YYMZ3V+0VAshaG43IbtA
# rF+y3kp9zvU5EmfvDqVjbOSmxR3NNg1c1eYbqMFkdECnwHLFuk4fsbVYTXn+149z
# k6wsOeKlSNbwsDETqVcplicu9Yemj052FVUmcJgmf6AaRyBD40NjgHt1biclkJg6
# OBGz9vae5jtb7IHeIhTZgirHkr+g3uM+onP65x9abJTyUpURK1h0QCirc0PO30qh
# HGs4xSnzyqqWc0Jon7ZGs506o9UD4L/wojzKQtwYSH8UNM/STKvvmz3+DrhkKvp1
# KCRB7UK/BZxmSVJQ9FHzNklNiyDSLFc1eSuo80VgvCONWPfcYd6T/jnA+bIwpUzX
# 6ZhKWD7TA4j+s4/TXkt2ElGTyYwMO1uKIqjBJgj5FBASA31fI7tk42PgpuE+9sJ0
# sj8eCXbsq11GdeJgo1gJASgADoRU7s7pXcheMBK9Rp6103a50g5rmQzSM7TNsQID
# AQABo4IBXTCCAVkwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUuhbZbU2F
# L3MpdpovdYxqII+eyG8wHwYDVR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08w
# DgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMIMHcGCCsGAQUFBwEB
# BGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsG
# AQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVz
# dGVkUm9vdEc0LmNydDBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdp
# Y2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNybDAgBgNVHSAEGTAXMAgG
# BmeBDAEEAjALBglghkgBhv1sBwEwDQYJKoZIhvcNAQELBQADggIBAH1ZjsCTtm+Y
# qUQiAX5m1tghQuGwGC4QTRPPMFPOvxj7x1Bd4ksp+3CKDaopafxpwc8dB+k+YMjY
# C+VcW9dth/qEICU0MWfNthKWb8RQTGIdDAiCqBa9qVbPFXONASIlzpVpP0d3+3J0
# FNf/q0+KLHqrhc1DX+1gtqpPkWaeLJ7giqzl/Yy8ZCaHbJK9nXzQcAp876i8dU+6
# WvepELJd6f8oVInw1YpxdmXazPByoyP6wCeCRK6ZJxurJB4mwbfeKuv2nrF5mYGj
# VoarCkXJ38SNoOeY+/umnXKvxMfBwWpx2cYTgAnEtp/Nh4cku0+jSbl3ZpHxcpzp
# SwJSpzd+k1OsOx0ISQ+UzTl63f8lY5knLD0/a6fxZsNBzU+2QJshIUDQtxMkzdwd
# eDrknq3lNHGS1yZr5Dhzq6YBT70/O3itTK37xJV77QpfMzmHQXh6OOmc4d0j/R0o
# 08f56PGYX/sr2H7yRp11LB4nLCbbbxV7HhmLNriT1ObyF5lZynDwN7+YAN8gFk8n
# +2BnFqFmut1VwDophrCYoCvtlUG3OtUVmDG0YgkPCr2B2RP+v6TR81fZvAT6gt4y
# 3wSJ8ADNXcL50CN/AAvkdgIm2fBldkKmKYcJRyvmfxqkhQ/8mJb2VVQrH4D6wPIO
# K+XW+6kvRBVK5xMOHds3OBqhK/bt1nz8MIIGxjCCBK6gAwIBAgIQCnpKiJ7JmUKQ
# BmM4TYaXnTANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMO
# RGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNB
# NDA5NiBTSEEyNTYgVGltZVN0YW1waW5nIENBMB4XDTIyMDMyOTAwMDAwMFoXDTMz
# MDMxNDIzNTk1OVowTDELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ
# bmMuMSQwIgYDVQQDExtEaWdpQ2VydCBUaW1lc3RhbXAgMjAyMiAtIDIwggIiMA0G
# CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC5KpYjply8X9ZJ8BWCGPQz7sxcbOPg
# JS7SMeQ8QK77q8TjeF1+XDbq9SWNQ6OB6zhj+TyIad480jBRDTEHukZu6aNLSOiJ
# QX8Nstb5hPGYPgu/CoQScWyhYiYB087DbP2sO37cKhypvTDGFtjavOuy8YPRn80J
# xblBakVCI0Fa+GDTZSw+fl69lqfw/LH09CjPQnkfO8eTB2ho5UQ0Ul8PUN7UWSxE
# dMAyRxlb4pguj9DKP//GZ888k5VOhOl2GJiZERTFKwygM9tNJIXogpThLwPuf4UC
# yYbh1RgUtwRF8+A4vaK9enGY7BXn/S7s0psAiqwdjTuAaP7QWZgmzuDtrn8oLsKe
# 4AtLyAjRMruD+iM82f/SjLv3QyPf58NaBWJ+cCzlK7I9Y+rIroEga0OJyH5fsBrd
# Gb2fdEEKr7mOCdN0oS+wVHbBkE+U7IZh/9sRL5IDMM4wt4sPXUSzQx0jUM2R1y+d
# +/zNscGnxA7E70A+GToC1DGpaaBJ+XXhm+ho5GoMj+vksSF7hmdYfn8f6CvkFLIW
# 1oGhytowkGvub3XAsDYmsgg7/72+f2wTGN/GbaR5Sa2Lf2GHBWj31HDjQpXonrub
# S7LitkE956+nGijJrWGwoEEYGU7tR5thle0+C2Fa6j56mJJRzT/JROeAiylCcvd5
# st2E6ifu/n16awIDAQABo4IBizCCAYcwDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB
# /wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwIAYDVR0gBBkwFzAIBgZngQwB
# BAIwCwYJYIZIAYb9bAcBMB8GA1UdIwQYMBaAFLoW2W1NhS9zKXaaL3WMaiCPnshv
# MB0GA1UdDgQWBBSNZLeJIf5WWESEYafqbxw2j92vDTBaBgNVHR8EUzBRME+gTaBL
# hklodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRSU0E0
# MDk2U0hBMjU2VGltZVN0YW1waW5nQ0EuY3JsMIGQBggrBgEFBQcBAQSBgzCBgDAk
# BggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMFgGCCsGAQUFBzAC
# hkxodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRS
# U0E0MDk2U0hBMjU2VGltZVN0YW1waW5nQ0EuY3J0MA0GCSqGSIb3DQEBCwUAA4IC
# AQANLSN0ptH1+OpLmT8B5PYM5K8WndmzjJeCKZxDbwEtqzi1cBG/hBmLP13lhk++
# kzreKjlaOU7YhFmlvBuYquhs79FIaRk4W8+JOR1wcNlO3yMibNXf9lnLocLqTHbK
# odyhK5a4m1WpGmt90fUCCU+C1qVziMSYgN/uSZW3s8zFp+4O4e8eOIqf7xHJMUpY
# tt84fMv6XPfkU79uCnx+196Y1SlliQ+inMBl9AEiZcfqXnSmWzWSUHz0F6aHZE8+
# RokWYyBry/J70DXjSnBIqbbnHWC9BCIVJXAGcqlEO2lHEdPu6cegPk8QuTA25POq
# aQmoi35komWUEftuMvH1uzitzcCTEdUyeEpLNypM81zctoXAu3AwVXjWmP5UbX9x
# qUgaeN1Gdy4besAzivhKKIwSqHPPLfnTI/KeGeANlCig69saUaCVgo4oa6TOnXbe
# qXOqSGpZQ65f6vgPBkKd3wZolv4qoHRbY2beayy4eKpNcG3wLPEHFX41tOa1DKKZ
# pdcVazUOhdbgLMzgDCS4fFILHpl878jIxYxYaa+rPeHPzH0VrhS/inHfypex2Efq
# HIXgRU4SHBQpWMxv03/LvsEOSm8gnK7ZczJZCOctkqEaEf4ymKZdK5fgi9OczG21
# Da5HYzhHF1tvE9pqEG4fSbdEW7QICodaWQR2EaGndwITHDGCBUwwggVIAgEBMIGG
# MHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsT
# EHd3dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJl
# ZCBJRCBDb2RlIFNpZ25pbmcgQ0ECEATV3B9I6snYUgC6zZqbKqcwCQYFKw4DAhoF
# AKB4MBgGCisGAQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisG
# AQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwIwYJKoZIhvcN
# AQkEMRYEFNy/4h8QU0UzrWooQt6byQWp2JECMA0GCSqGSIb3DQEBAQUABIIBACPQ
# wyyODnzADc8nAL3Yo67tPCFLqrGqHrze0Qf5SE9OLQNGTBIUTba/5c2Rmj3FTzLL
# nFR7O+wlyZUcsXXFEqZ8SD+O+3KTfQi/iERdGah99jSUITQb90596LhNw5KVZtwO
# 8RK6McDv/IfYMVxeKoEsEWu60y28YT0Up590Ln6akHkmR0PByC1MBl9uYepmLuZc
# sbLJ/EMNUou907aiNyqipBNbZiEGtsMPNSiQMsWzZ3qonrKOSvdxdzMUsvacbTIU
# 9x18czSj01gKAMOdmHRbEUYd9A9dyZTkQiWualDhtOEf1oFOGJyqY+BkHgvUHClq
# ciMvqciWUz2ePTcQvTKhggMgMIIDHAYJKoZIhvcNAQkGMYIDDTCCAwkCAQEwdzBj
# MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMT
# MkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYgVGltZVN0YW1waW5n
# IENBAhAKekqInsmZQpAGYzhNhpedMA0GCWCGSAFlAwQCAQUAoGkwGAYJKoZIhvcN
# AQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMjIwNDEyMjE1NDA0WjAv
# BgkqhkiG9w0BCQQxIgQgRhRPjbEMp4+p6tCcmK8A+nOh76uZEAj4jwndzfGLi3Mw
# DQYJKoZIhvcNAQEBBQAEggIAniGsRCGhcvwCjYCEAkMqfZAjaiy6QbJrlRQs4zDF
# A5qjCFRFav/ic35RbjTbtEvpNLcs6qKwfQmHJqA3aliSMCNLZ7YXLkyUJ1WPzAIe
# Ty8pe0SwbMsaQW9rQScbKNOg8VXpTqSQ1UxU+OH6uPXjeswjm00Rro2TBbw01id0
# 4/3KxL8ukKqIg9t1QNGLopVoU84FHguPJ03OglWloB4h20S7CYKjg0X97nMV9I+L
# HTvXZsT8vcscHRH+aNsAJbURKWZyV39NRX8ShzlRZ/wqT41EcnK+7jXF4LJQhgB6
# f00tVkiA712zxVBCrDcoqiOvBRp01QUpEvD08Z4bOMJgPWj01ZrjewBRULQlsvkb
# peJRPmTcB8gt6eXf07etjgrrQoGC71u6jkFRlq/7+cmHHrUrl9duR/WnFy4QGSNB
# B5WSC8lsSfxuG81oRBvsUbtrXwAxPgA4P3j5qPw0DCOMvp12f9T9adUgA4x3WRHu
# uQqCCjBBCY0v1ifdhhCntYuQS3Syoanc993Mz97lyWo1IZ6bB8OtXAx/xZqOUd3y
# Ysr5koJkmTSnfr1py1OTkAsT71wAkYuCeAu+NshDv2evY/9uPVVKoR/fsWQOsGEG
# YcBoY0DkBRsks+Djit2EYcPY5Ul8ZNjcUPjF8itl+Ah50retZezTvEv8gu31jp0H
# t3k=
# SIG # End signature block