SecurityPolicy.psm1

function Convert-Identity {
    <#
    .SYNOPSIS
    Small command that tries to resolve any given object
 
    .DESCRIPTION
    Small command that tries to resolve any given object - be it SID, DN, FSP or Netbiosname
 
    .PARAMETER Identity
    Type to resolve in form of Identity, DN, SID
 
    .PARAMETER SID
    Allows to pass SID directly, rather then going thru verification process
 
    .PARAMETER Name
    Allows to pass Name directly, rather then going thru verification process
 
    .EXAMPLE
    $Identity = @(
        'S-1-5-4'
        'S-1-5-4'
        'S-1-5-11'
        'S-1-5-32-549'
        'S-1-5-32-550'
        'S-1-5-32-548'
        'S-1-5-64-10'
        'S-1-5-64-14'
        'S-1-5-64-21'
        'S-1-5-18'
        'S-1-5-19'
        'S-1-5-32-544'
        'S-1-5-20-20-10-51' # Wrong SID
        'S-1-5-21-853615985-2870445339-3163598659-512'
        'S-1-5-21-3661168273-3802070955-2987026695-512'
        'S-1-5-21-1928204107-2710010574-1926425344-512'
        'CN=Test Test 2,OU=Users,OU=Production,DC=ad,DC=evotec,DC=pl'
        'Test Local Group'
        'przemyslaw.klys@evotec.pl'
        'test2'
        'NT AUTHORITY\NETWORK'
        'NT AUTHORITY\SYSTEM'
        'S-1-5-21-853615985-2870445339-3163598659-519'
        'TEST\some'
        'EVOTECPL\Domain Admins'
        'NT AUTHORITY\INTERACTIVE'
        'INTERACTIVE'
        'EVOTEC\Domain Admins'
        'EVOTECPL\Domain Admins'
        'Test\Domain Admins'
        'CN=S-1-5-21-1928204107-2710010574-1926425344-512,CN=ForeignSecurityPrincipals,DC=ad,DC=evotec,DC=xyz' # Valid
        'CN=S-1-5-21-1928204107-2710010574-512,CN=ForeignSecurityPrincipals,DC=ad,DC=evotec,DC=xyz' # not valid
        'CN=S-1-5-21-1928204107-2710010574-1926425344-512,CN=ForeignSecurityPrincipals,DC=ad,DC=evotec,DC=xyz' # cached
    )
 
    $TestOutput = Convert-Identity -Identity $Identity -Verbose
 
    Output:
 
    Name SID DomainName Type Error
    ---- --- ---------- ---- -----
    NT AUTHORITY\INTERACTIVE S-1-5-4 WellKnownGroup
    NT AUTHORITY\INTERACTIVE S-1-5-4 WellKnownGroup
    NT AUTHORITY\Authenticated Users S-1-5-11 WellKnownGroup
    BUILTIN\Server Operators S-1-5-32-549 WellKnownGroup
    BUILTIN\Print Operators S-1-5-32-550 WellKnownGroup
    BUILTIN\Account Operators S-1-5-32-548 WellKnownGroup
    NT AUTHORITY\NTLM Authentication S-1-5-64-10 WellKnownGroup
    NT AUTHORITY\SChannel Authentication S-1-5-64-14 WellKnownGroup
    NT AUTHORITY\Digest Authentication S-1-5-64-21 WellKnownGroup
    NT AUTHORITY\SYSTEM S-1-5-18 WellKnownAdministrative
    NT AUTHORITY\NETWORK SERVICE S-1-5-19 WellKnownGroup
    BUILTIN\Administrators S-1-5-32-544 WellKnownAdministrative
    S-1-5-20-20-10-51 S-1-5-20-20-10-51 Unknown Exception calling "Translate" with "1" argument(s): "Some or all identity references could not be translated."
    EVOTEC\Domain Admins S-1-5-21-853615985-2870445339-3163598659-512 ad.evotec.xyz Administrative
    EVOTECPL\Domain Admins S-1-5-21-3661168273-3802070955-2987026695-512 ad.evotec.pl Administrative
    TEST\Domain Admins S-1-5-21-1928204107-2710010574-1926425344-512 test.evotec.pl Administrative
    EVOTECPL\TestingAD S-1-5-21-3661168273-3802070955-2987026695-1111 ad.evotec.pl NotAdministrative
    EVOTEC\Test Local Group S-1-5-21-853615985-2870445339-3163598659-3610 ad.evotec.xyz NotAdministrative
    EVOTEC\przemyslaw.klys S-1-5-21-853615985-2870445339-3163598659-1105 ad.evotec.xyz NotAdministrative
    test2 Unknown Exception calling "Translate" with "1" argument(s): "Some or all identity references could not be translated."
    NT AUTHORITY\NETWORK S-1-5-2 WellKnownGroup
    NT AUTHORITY\SYSTEM S-1-5-18 WellKnownAdministrative
    EVOTEC\Enterprise Admins S-1-5-21-853615985-2870445339-3163598659-519 ad.evotec.xyz Administrative
    TEST\some S-1-5-21-1928204107-2710010574-1926425344-1106 test.evotec.pl NotAdministrative
    EVOTECPL\Domain Admins S-1-5-21-3661168273-3802070955-2987026695-512 ad.evotec.pl Administrative
    NT AUTHORITY\INTERACTIVE S-1-5-4 WellKnownGroup
    NT AUTHORITY\INTERACTIVE S-1-5-4 WellKnownGroup
    EVOTEC\Domain Admins S-1-5-21-853615985-2870445339-3163598659-512 ad.evotec.xyz Administrative
    EVOTECPL\Domain Admins S-1-5-21-3661168273-3802070955-2987026695-512 ad.evotec.pl Administrative
    TEST\Domain Admins S-1-5-21-1928204107-2710010574-1926425344-512 test.evotec.pl Administrative
    TEST\Domain Admins S-1-5-21-1928204107-2710010574-1926425344-512 test.evotec.pl Administrative
    S-1-5-21-1928204107-2710010574-512 S-1-5-21-1928204107-2710010574-512 Unknown Exception calling "Translate" with "1" argument(s): "Some or all identity references could not be translated."
    TEST\Domain Admins S-1-5-21-1928204107-2710010574-1926425344-512 test.evotec.pl Administrative
 
    .NOTES
    General notes
    #>

    [cmdletBinding(DefaultParameterSetName = 'Identity')]
    param([parameter(ParameterSetName = 'Identity', Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)][string[]] $Identity,
        [parameter(ParameterSetName = 'SID', Mandatory)][System.Security.Principal.SecurityIdentifier[]] $SID,
        [parameter(ParameterSetName = 'Name', Mandatory)][string[]] $Name)
    Begin { if (-not $Script:GlobalCacheSidConvert) { $Script:GlobalCacheSidConvert = @{} } }
    Process {
        if ($Identity) {
            foreach ($Ident in $Identity) {
                $MatchRegex = [Regex]::Matches($Ident, "S-\d-\d+-(\d+-|){1,14}\d+")
                if ($Script:GlobalCacheSidConvert[$Ident]) {
                    Write-Verbose "Convert-Identity - Processing $Ident (Cache)"
                    $Script:GlobalCacheSidConvert[$Ident]
                } elseif ($MatchRegex.Success) {
                    Write-Verbose "Convert-Identity - Processing $Ident (SID)"
                    if ($MatchRegex.Value -ne $Ident) { $Script:GlobalCacheSidConvert[$Ident] = ConvertFrom-SID -SID $MatchRegex.Value } else { $Script:GlobalCacheSidConvert[$Ident] = ConvertFrom-SID -SID $Ident }
                    $Script:GlobalCacheSidConvert[$Ident]
                } elseif ($Ident -like '*DC=*') {
                    Write-Verbose "Convert-Identity - Processing $Ident (DistinguishedName)"
                    try {
                        $Object = [adsi]"LDAP://$($Ident)"
                        $SIDValue = [System.Security.Principal.SecurityIdentifier]::new($Object.objectSid.Value, 0).Value
                        $Script:GlobalCacheSidConvert[$Ident] = ConvertFrom-SID -SID $SIDValue
                    } catch {
                        $Script:GlobalCacheSidConvert[$Ident] = [PSCustomObject] @{Name = $Ident
                            SID                                                         = $null
                            DomainName                                                  = ''
                            Type                                                        = 'Unknown'
                            Error                                                       = $_.Exception.Message -replace [environment]::NewLine, ' '
                        }
                    }
                    $Script:GlobalCacheSidConvert[$Ident]
                } else {
                    Write-Verbose "Convert-Identity - Processing $Ident (Other)"
                    try {
                        $SIDValue = ([System.Security.Principal.NTAccount] $Ident).Translate([System.Security.Principal.SecurityIdentifier]).Value
                        $Script:GlobalCacheSidConvert[$Ident] = ConvertFrom-SID -SID $SIDValue
                    } catch {
                        $Script:GlobalCacheSidConvert[$Ident] = [PSCustomObject] @{Name = $Ident
                            SID                                                         = $null
                            DomainName                                                  = ''
                            Type                                                        = 'Unknown'
                            Error                                                       = $_.Exception.Message -replace [environment]::NewLine, ' '
                        }
                    }
                    $Script:GlobalCacheSidConvert[$Ident]
                }
            }
        } else {
            if ($SID) {
                foreach ($S in $SID) {
                    if ($Script:GlobalCacheSidConvert[$S]) { $Script:GlobalCacheSidConvert[$S] } else {
                        $Script:GlobalCacheSidConvert[$S] = ConvertFrom-SID -SID $S
                        $Script:GlobalCacheSidConvert[$S]
                    }
                }
            } else {
                foreach ($Ident in $Name) {
                    if ($Script:GlobalCacheSidConvert[$Ident]) { $Script:GlobalCacheSidConvert[$Ident] } else {
                        $Script:GlobalCacheSidConvert[$Ident] = ([System.Security.Principal.NTAccount] $Ident).Translate([System.Security.Principal.SecurityIdentifier]).Value
                        $Script:GlobalCacheSidConvert[$Ident]
                    }
                }
            }
        }
    }
    End {}
}
function ConvertFrom-SID {
    <#
    .SYNOPSIS
    Small command that can resolve SID values
 
    .DESCRIPTION
    Small command that can resolve SID values
 
    .PARAMETER SID
    Value to resolve
 
    .PARAMETER OnlyWellKnown
    Only resolve SID when it's well know SID. Otherwise return $null
 
    .PARAMETER OnlyWellKnownAdministrative
    Only resolve SID when it's administrative well know SID. Otherwise return $null
 
    .PARAMETER DoNotResolve
    Uses only dicrionary values without querying AD
 
    .EXAMPLE
    ConvertFrom-SID -SID 'S-1-5-8', 'S-1-5-9', 'S-1-5-11', 'S-1-5-18', 'S-1-1-0' -DoNotResolve
 
    .NOTES
    General notes
    #>

    [cmdletbinding(DefaultParameterSetName = 'Standard')]
    param([Parameter(ParameterSetName = 'Standard')]
        [Parameter(ParameterSetName = 'OnlyWellKnown')]
        [Parameter(ParameterSetName = 'OnlyWellKnownAdministrative')]
        [string[]] $SID,
        [Parameter(ParameterSetName = 'OnlyWellKnown')][switch] $OnlyWellKnown,
        [Parameter(ParameterSetName = 'OnlyWellKnownAdministrative')][switch] $OnlyWellKnownAdministrative,
        [Parameter(ParameterSetName = 'Standard')][switch] $DoNotResolve)
    $WellKnownAdministrative = @{'S-1-5-18' = [PSCustomObject] @{Name = 'NT AUTHORITY\SYSTEM'
            SID                                                       = 'S-1-5-18'
            DomainName                                                = ''
            Type                                                      = 'WellKnownAdministrative'
            Error                                                     = ''
        }
        'S-1-5-32-544'                      = [PSCustomObject] @{Name = 'BUILTIN\Administrators'
            SID                                  = 'S-1-5-32-544'
            DomainName                           = ''
            Type                                 = 'WellKnownAdministrative'
            Error                                = ''
        }
    }
    $wellKnownSIDs = @{'S-1-0' = [PSCustomObject] @{Name = 'Null AUTHORITY'
            SID                                          = 'S-1-0'
            DomainName                                   = ''
            Type                                         = 'WellKnownGroup'
            Error                                        = ''
        }
        'S-1-0-0'              = [PSCustomObject] @{Name = 'NULL SID'
            SID                             = 'S-1-0-0'
            DomainName                      = ''
            Type                            = 'WellKnownGroup'
            Error                           = ''
        }
        'S-1-1'                = [PSCustomObject] @{Name = 'WORLD AUTHORITY'
            SID                           = 'S-1-1'
            DomainName                    = ''
            Type                          = 'WellKnownGroup'
            Error                         = ''
        }
        'S-1-1-0'              = [PSCustomObject] @{Name = 'Everyone'
            SID                             = 'S-1-1-0'
            DomainName                      = ''
            Type                            = 'WellKnownGroup'
            Error                           = ''
        }
        'S-1-2'                = [PSCustomObject] @{Name = 'LOCAL AUTHORITY'
            SID                           = 'S-1-2'
            DomainName                    = ''
            Type                          = 'WellKnownGroup'
            Error                         = ''
        }
        'S-1-2-0'              = [PSCustomObject] @{Name = 'LOCAL'
            SID                             = 'S-1-2-0'
            DomainName                      = ''
            Type                            = 'WellKnownGroup'
            Error                           = ''
        }
        'S-1-2-1'              = [PSCustomObject] @{Name = 'CONSOLE LOGON'
            SID                             = 'S-1-2-1'
            DomainName                      = ''
            Type                            = 'WellKnownGroup'
            Error                           = ''
        }
        'S-1-3'                = [PSCustomObject] @{Name = 'CREATOR AUTHORITY'
            SID                           = 'S-1-3'
            DomainName                    = ''
            Type                          = 'WellKnownGroup'
            Error                         = ''
        }
        'S-1-3-0'              = [PSCustomObject] @{Name = 'CREATOR OWNER'
            SID                             = 'S-1-3-0'
            DomainName                      = ''
            Type                            = 'WellKnownAdministrative'
            Error                           = ''
        }
        'S-1-3-1'              = [PSCustomObject] @{Name = 'CREATOR GROUP'
            SID                             = 'S-1-3-1'
            DomainName                      = ''
            Type                            = 'WellKnownGroup'
            Error                           = ''
        }
        'S-1-3-2'              = [PSCustomObject] @{Name = 'CREATOR OWNER SERVER'
            SID                             = 'S-1-3-2'
            DomainName                      = ''
            Type                            = 'WellKnownGroup'
            Error                           = ''
        }
        'S-1-3-3'              = [PSCustomObject] @{Name = 'CREATOR GROUP SERVER'
            SID                             = 'S-1-3-3'
            DomainName                      = ''
            Type                            = 'WellKnownGroup'
            Error                           = ''
        }
        'S-1-3-4'              = [PSCustomObject] @{Name = 'OWNER RIGHTS'
            SID                             = 'S-1-3-4'
            DomainName                      = ''
            Type                            = 'WellKnownGroup'
            Error                           = ''
        }
        'S-1-5-80-0'           = [PSCustomObject] @{Name = 'NT SERVICE\ALL SERVICES'
            SID                                = 'S-1-5-80-0'
            DomainName                         = ''
            Type                               = 'WellKnownGroup'
            Error                              = ''
        }
        'S-1-4'                = [PSCustomObject] @{Name = 'Non-unique Authority'
            SID                           = 'S-1-4'
            DomainName                    = ''
            Type                          = 'WellKnownGroup'
            Error                         = ''
        }
        'S-1-5'                = [PSCustomObject] @{Name = 'NT AUTHORITY'
            SID                           = 'S-1-5'
            DomainName                    = ''
            Type                          = 'WellKnownGroup'
            Error                         = ''
        }
        'S-1-5-1'              = [PSCustomObject] @{Name = 'NT AUTHORITY\DIALUP'
            SID                             = 'S-1-5-1'
            DomainName                      = ''
            Type                            = 'WellKnownGroup'
            Error                           = ''
        }
        'S-1-5-2'              = [PSCustomObject] @{Name = 'NT AUTHORITY\NETWORK'
            SID                             = 'S-1-5-2'
            DomainName                      = ''
            Type                            = 'WellKnownGroup'
            Error                           = ''
        }
        'S-1-5-3'              = [PSCustomObject] @{Name = 'NT AUTHORITY\BATCH'
            SID                             = 'S-1-5-3'
            DomainName                      = ''
            Type                            = 'WellKnownGroup'
            Error                           = ''
        }
        'S-1-5-4'              = [PSCustomObject] @{Name = 'NT AUTHORITY\INTERACTIVE'
            SID                             = 'S-1-5-4'
            DomainName                      = ''
            Type                            = 'WellKnownGroup'
            Error                           = ''
        }
        'S-1-5-6'              = [PSCustomObject] @{Name = 'NT AUTHORITY\SERVICE'
            SID                             = 'S-1-5-6'
            DomainName                      = ''
            Type                            = 'WellKnownGroup'
            Error                           = ''
        }
        'S-1-5-7'              = [PSCustomObject] @{Name = 'NT AUTHORITY\ANONYMOUS LOGON'
            SID                             = 'S-1-5-7'
            DomainName                      = ''
            Type                            = 'WellKnownGroup'
            Error                           = ''
        }
        'S-1-5-8'              = [PSCustomObject] @{Name = 'NT AUTHORITY\PROXY'
            SID                             = 'S-1-5-8'
            DomainName                      = ''
            Type                            = 'WellKnownGroup'
            Error                           = ''
        }
        'S-1-5-9'              = [PSCustomObject] @{Name = 'NT AUTHORITY\ENTERPRISE DOMAIN CONTROLLERS'
            SID                             = 'S-1-5-9'
            DomainName                      = ''
            Type                            = 'WellKnownGroup'
            Error                           = ''
        }
        'S-1-5-10'             = [PSCustomObject] @{Name = 'NT AUTHORITY\SELF'
            SID                              = 'S-1-5-10'
            DomainName                       = ''
            Type                             = 'WellKnownGroup'
            Error                            = ''
        }
        'S-1-5-11'             = [PSCustomObject] @{Name = 'NT AUTHORITY\Authenticated Users'
            SID                              = 'S-1-5-11'
            DomainName                       = ''
            Type                             = 'WellKnownGroup'
            Error                            = ''
        }
        'S-1-5-12'             = [PSCustomObject] @{Name = 'NT AUTHORITY\RESTRICTED'
            SID                              = 'S-1-5-12'
            DomainName                       = ''
            Type                             = 'WellKnownGroup'
            Error                            = ''
        }
        'S-1-5-13'             = [PSCustomObject] @{Name = 'NT AUTHORITY\TERMINAL SERVER USER'
            SID                              = 'S-1-5-13'
            DomainName                       = ''
            Type                             = 'WellKnownGroup'
            Error                            = ''
        }
        'S-1-5-14'             = [PSCustomObject] @{Name = 'NT AUTHORITY\REMOTE INTERACTIVE LOGON'
            SID                              = 'S-1-5-14'
            DomainName                       = ''
            Type                             = 'WellKnownGroup'
            Error                            = ''
        }
        'S-1-5-15'             = [PSCustomObject] @{Name = 'NT AUTHORITY\This Organization'
            SID                              = 'S-1-5-15'
            DomainName                       = ''
            Type                             = 'WellKnownGroup'
            Error                            = ''
        }
        'S-1-5-17'             = [PSCustomObject] @{Name = 'NT AUTHORITY\IUSR'
            SID                              = 'S-1-5-17'
            DomainName                       = ''
            Type                             = 'WellKnownGroup'
            Error                            = ''
        }
        'S-1-5-18'             = [PSCustomObject] @{Name = 'NT AUTHORITY\SYSTEM'
            SID                              = 'S-1-5-18'
            DomainName                       = ''
            Type                             = 'WellKnownAdministrative'
            Error                            = ''
        }
        'S-1-5-19'             = [PSCustomObject] @{Name = 'NT AUTHORITY\NETWORK SERVICE'
            SID                              = 'S-1-5-19'
            DomainName                       = ''
            Type                             = 'WellKnownGroup'
            Error                            = ''
        }
        'S-1-5-20'             = [PSCustomObject] @{Name = 'NT AUTHORITY\NETWORK SERVICE'
            SID                              = 'S-1-5-20'
            DomainName                       = ''
            Type                             = 'WellKnownGroup'
            Error                            = ''
        }
        'S-1-5-32-544'         = [PSCustomObject] @{Name = 'BUILTIN\Administrators'
            SID                                  = 'S-1-5-32-544'
            DomainName                           = ''
            Type                                 = 'WellKnownAdministrative'
            Error                                = ''
        }
        'S-1-5-32-545'         = [PSCustomObject] @{Name = 'BUILTIN\Users'
            SID                                  = 'S-1-5-32-545'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
        'S-1-5-32-546'         = [PSCustomObject] @{Name = 'BUILTIN\Guests'
            SID                                  = 'S-1-5-32-546'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
        'S-1-5-32-547'         = [PSCustomObject] @{Name = 'BUILTIN\Power Users'
            SID                                  = 'S-1-5-32-547'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
        'S-1-5-32-548'         = [PSCustomObject] @{Name = 'BUILTIN\Account Operators'
            SID                                  = 'S-1-5-32-548'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
        'S-1-5-32-549'         = [PSCustomObject] @{Name = 'BUILTIN\Server Operators'
            SID                                  = 'S-1-5-32-549'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
        'S-1-5-32-550'         = [PSCustomObject] @{Name = 'BUILTIN\Print Operators'
            SID                                  = 'S-1-5-32-550'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
        'S-1-5-32-551'         = [PSCustomObject] @{Name = 'BUILTIN\Backup Operators'
            SID                                  = 'S-1-5-32-551'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
        'S-1-5-32-552'         = [PSCustomObject] @{Name = 'BUILTIN\Replicators'
            SID                                  = 'S-1-5-32-552'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
        'S-1-5-64-10'          = [PSCustomObject] @{Name = 'NT AUTHORITY\NTLM Authentication'
            SID                                 = 'S-1-5-64-10'
            DomainName                          = ''
            Type                                = 'WellKnownGroup'
            Error                               = ''
        }
        'S-1-5-64-14'          = [PSCustomObject] @{Name = 'NT AUTHORITY\SChannel Authentication'
            SID                                 = 'S-1-5-64-14'
            DomainName                          = ''
            Type                                = 'WellKnownGroup'
            Error                               = ''
        }
        'S-1-5-64-21'          = [PSCustomObject] @{Name = 'NT AUTHORITY\Digest Authentication'
            SID                                 = 'S-1-5-64-21'
            DomainName                          = ''
            Type                                = 'WellKnownGroup'
            Error                               = ''
        }
        'S-1-5-80'             = [PSCustomObject] @{Name = 'NT SERVICE'
            SID                              = 'S-1-5-80'
            DomainName                       = ''
            Type                             = 'WellKnownGroup'
            Error                            = ''
        }
        'S-1-5-83-0'           = [PSCustomObject] @{Name = 'NT VIRTUAL MACHINE\Virtual Machines'
            SID                                = 'S-1-5-83-0'
            DomainName                         = ''
            Type                               = 'WellKnownGroup'
            Error                              = ''
        }
        'S-1-16-0'             = [PSCustomObject] @{Name = 'Untrusted Mandatory Level'
            SID                              = 'S-1-16-0'
            DomainName                       = ''
            Type                             = 'WellKnownGroup'
            Error                            = ''
        }
        'S-1-16-4096'          = [PSCustomObject] @{Name = 'Low Mandatory Level'
            SID                                 = 'S-1-16-4096'
            DomainName                          = ''
            Type                                = 'WellKnownGroup'
            Error                               = ''
        }
        'S-1-16-8192'          = [PSCustomObject] @{Name = 'Medium Mandatory Level'
            SID                                 = 'S-1-16-8192'
            DomainName                          = ''
            Type                                = 'WellKnownGroup'
            Error                               = ''
        }
        'S-1-16-8448'          = [PSCustomObject] @{Name = 'Medium Plus Mandatory Level'
            SID                                 = 'S-1-16-8448'
            DomainName                          = ''
            Type                                = 'WellKnownGroup'
            Error                               = ''
        }
        'S-1-16-12288'         = [PSCustomObject] @{Name = 'High Mandatory Level'
            SID                                  = 'S-1-16-12288'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
        'S-1-16-16384'         = [PSCustomObject] @{Name = 'System Mandatory Level'
            SID                                  = 'S-1-16-16384'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
        'S-1-16-20480'         = [PSCustomObject] @{Name = 'Protected Process Mandatory Level'
            SID                                  = 'S-1-16-20480'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
        'S-1-16-28672'         = [PSCustomObject] @{Name = 'Secure Process Mandatory Level'
            SID                                  = 'S-1-16-28672'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
        'S-1-5-32-554'         = [PSCustomObject] @{Name = 'BUILTIN\Pre-Windows 2000 Compatible Access'
            SID                                  = 'S-1-5-32-554'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
        'S-1-5-32-555'         = [PSCustomObject] @{Name = 'BUILTIN\Remote Desktop Users'
            SID                                  = 'S-1-5-32-555'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
        'S-1-5-32-556'         = [PSCustomObject] @{Name = 'BUILTIN\Network Configuration Operators'
            SID                                  = 'S-1-5-32-556'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
        'S-1-5-32-557'         = [PSCustomObject] @{Name = 'BUILTIN\Incoming Forest Trust Builders'
            SID                                  = 'S-1-5-32-557'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
        'S-1-5-32-558'         = [PSCustomObject] @{Name = 'BUILTIN\Performance Monitor Users'
            SID                                  = 'S-1-5-32-558'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
        'S-1-5-32-559'         = [PSCustomObject] @{Name = 'BUILTIN\Performance Log Users'
            SID                                  = 'S-1-5-32-559'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
        'S-1-5-32-560'         = [PSCustomObject] @{Name = 'BUILTIN\Windows Authorization Access Group'
            SID                                  = 'S-1-5-32-560'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
        'S-1-5-32-561'         = [PSCustomObject] @{Name = 'BUILTIN\Terminal Server License Servers'
            SID                                  = 'S-1-5-32-561'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
        'S-1-5-32-562'         = [PSCustomObject] @{Name = 'BUILTIN\Distributed COM Users'
            SID                                  = 'S-1-5-32-562'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
        'S-1-5-32-569'         = [PSCustomObject] @{Name = 'BUILTIN\Cryptographic Operators'
            SID                                  = 'S-1-5-32-569'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
        'S-1-5-32-573'         = [PSCustomObject] @{Name = 'BUILTIN\Event Log Readers'
            SID                                  = 'S-1-5-32-573'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
        'S-1-5-32-574'         = [PSCustomObject] @{Name = 'BUILTIN\Certificate Service DCOM Access'
            SID                                  = 'S-1-5-32-574'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
        'S-1-5-32-575'         = [PSCustomObject] @{Name = 'BUILTIN\RDS Remote Access Servers'
            SID                                  = 'S-1-5-32-575'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
        'S-1-5-32-576'         = [PSCustomObject] @{Name = 'BUILTIN\RDS Endpoint Servers'
            SID                                  = 'S-1-5-32-576'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
        'S-1-5-32-577'         = [PSCustomObject] @{Name = 'BUILTIN\RDS Management Servers'
            SID                                  = 'S-1-5-32-577'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
        'S-1-5-32-578'         = [PSCustomObject] @{Name = 'BUILTIN\Hyper-V Administrators'
            SID                                  = 'S-1-5-32-578'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
        'S-1-5-32-579'         = [PSCustomObject] @{Name = 'BUILTIN\Access Control Assistance Operators'
            SID                                  = 'S-1-5-32-579'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
        'S-1-5-32-580'         = [PSCustomObject] @{Name = 'BUILTIN\Remote Management Users'
            SID                                  = 'S-1-5-32-580'
            DomainName                           = ''
            Type                                 = 'WellKnownGroup'
            Error                                = ''
        }
    }
    foreach ($S in $SID) {
        if ($OnlyWellKnownAdministrative) { if ($WellKnownAdministrative[$S]) { $WellKnownAdministrative[$S] } } elseif ($OnlyWellKnown) { if ($wellKnownSIDs[$S]) { $wellKnownSIDs[$S] } } else {
            if ($wellKnownSIDs[$S]) { $wellKnownSIDs[$S] } else {
                if ($DoNotResolve) {
                    if ($S -like "S-1-5-21-*-519" -or $S -like "S-1-5-21-*-512") {
                        [PSCustomObject] @{Name = $S
                            SID                 = $S
                            DomainName          = ''
                            Type                = 'Administrative'
                            Error               = ''
                        }
                    } else {
                        [PSCustomObject] @{Name = $S
                            SID                 = $S
                            DomainName          = ''
                            Error               = ''
                            Type                = 'NotAdministrative'
                        }
                    }
                } else {
                    try {
                        if ($S -like "S-1-5-21-*-519" -or $S -like "S-1-5-21-*-512") { $Type = 'Administrative' } else { $Type = 'NotAdministrative' }
                        $Name = (([System.Security.Principal.SecurityIdentifier]::new($S)).Translate([System.Security.Principal.NTAccount])).Value
                        [PSCustomObject] @{Name = $Name
                            SID                 = $S
                            DomainName          = (ConvertFrom-NetbiosName -Identity $Name).DomainName
                            Type                = $Type
                            Error               = ''
                        }
                    } catch {
                        [PSCustomObject] @{Name = $S
                            SID                 = $S
                            DomainName          = ''
                            Error               = $_.Exception.Message -replace [environment]::NewLine, ' '
                            Type                = 'Unknown'
                        }
                    }
                }
            }
        }
    }
}
function ConvertFrom-NetbiosName {
    [cmdletBinding()]
    param([Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName, Position = 0)]
        [string[]] $Identity)
    process {
        foreach ($Ident in $Identity) {
            if ($Ident -like '*\*') {
                $NetbiosWithObject = $Ident -split "\\"
                if ($NetbiosWithObject.Count -eq 2) {
                    $LDAPQuery = ([ADSI]"LDAP://$($NetbiosWithObject[0])")
                    $DomainName = ConvertFrom-DistinguishedName -DistinguishedName $LDAPQuery.distinguishedName -ToDomainCN
                    [PSCustomObject] @{DomainName = $DomainName
                        Name                      = $NetbiosWithObject[1]
                    }
                } else {
                    [PSCustomObject] @{DomainName = ''
                        Name                      = $Ident
                    }
                }
            } else {
                [PSCustomObject] @{DomainName = ''
                    Name                      = $Ident
                }
            }
        }
    }
}
function ConvertFrom-DistinguishedName {
    <#
    .SYNOPSIS
    Converts a Distinguished Name to CN, OU, Multiple OUs or DC
 
    .DESCRIPTION
    Converts a Distinguished Name to CN, OU, Multiple OUs or DC
 
    .PARAMETER DistinguishedName
    Distinguished Name to convert
 
    .PARAMETER ToOrganizationalUnit
    Converts DistinguishedName to Organizational Unit
 
    .PARAMETER ToDC
    Converts DistinguishedName to DC
 
    .PARAMETER ToDomainCN
    Converts DistinguishedName to Domain CN
 
    .EXAMPLE
    $DistinguishedName = 'CN=Przemyslaw Klys,OU=Users,OU=Production,DC=ad,DC=evotec,DC=xyz'
    ConvertFrom-DistinguishedName -DistinguishedName $DistinguishedName -ToOrganizationalUnit
 
    Output:
    OU=Users,OU=Production,DC=ad,DC=evotec,DC=xyz
 
    .EXAMPLE
    $DistinguishedName = 'CN=Przemyslaw Klys,OU=Users,OU=Production,DC=ad,DC=evotec,DC=xyz'
    ConvertFrom-DistinguishedName -DistinguishedName $DistinguishedName
 
    Output:
    Przemyslaw Klys
 
    .EXAMPLE
    ConvertFrom-DistinguishedName -DistinguishedName 'OU=Users,OU=Production,DC=ad,DC=evotec,DC=xyz' -ToMultipleOrganizationalUnit -IncludeParent
 
    Output:
    OU=Users,OU=Production,DC=ad,DC=evotec,DC=xyz
    OU=Production,DC=ad,DC=evotec,DC=xyz
 
    .EXAMPLE
    ConvertFrom-DistinguishedName -DistinguishedName 'OU=Users,OU=Production,DC=ad,DC=evotec,DC=xyz' -ToMultipleOrganizationalUnit
 
    Output:
    OU=Production,DC=ad,DC=evotec,DC=xyz
 
    .EXAMPLE
    $Con = @(
        'CN=Windows Authorization Access Group,CN=Builtin,DC=ad,DC=evotec,DC=xyz'
        'CN=Mmm,DC=elo,CN=nee,DC=RootDNSServers,CN=MicrosoftDNS,CN=System,DC=ad,DC=evotec,DC=xyz'
        'CN=e6d5fd00-385d-4e65-b02d-9da3493ed850,CN=Operations,CN=DomainUpdates,CN=System,DC=ad,DC=evotec,DC=xyz'
        'OU=Domain Controllers,DC=ad,DC=evotec,DC=pl'
        'OU=Microsoft Exchange Security Groups,DC=ad,DC=evotec,DC=xyz'
    )
 
    ConvertFrom-DistinguishedName -DistinguishedName $Con -ToLastName
 
    Output:
    Windows Authorization Access Group
    Mmm
    e6d5fd00-385d-4e65-b02d-9da3493ed850
    Domain Controllers
    Microsoft Exchange Security Groups
 
    .NOTES
    General notes
    #>

    [CmdletBinding(DefaultParameterSetName = 'Default')]
    param([Parameter(ParameterSetName = 'ToOrganizationalUnit')]
        [Parameter(ParameterSetName = 'ToMultipleOrganizationalUnit')]
        [Parameter(ParameterSetName = 'ToDC')]
        [Parameter(ParameterSetName = 'ToDomainCN')]
        [Parameter(ParameterSetName = 'Default')]
        [Parameter(ParameterSetName = 'ToLastName')]
        [alias('Identity', 'DN')][Parameter(ValueFromPipeline, ValueFromPipelineByPropertyName, Position = 0)][string[]] $DistinguishedName,
        [Parameter(ParameterSetName = 'ToOrganizationalUnit')][switch] $ToOrganizationalUnit,
        [Parameter(ParameterSetName = 'ToMultipleOrganizationalUnit')][alias('ToMultipleOU')][switch] $ToMultipleOrganizationalUnit,
        [Parameter(ParameterSetName = 'ToMultipleOrganizationalUnit')][switch] $IncludeParent,
        [Parameter(ParameterSetName = 'ToDC')][switch] $ToDC,
        [Parameter(ParameterSetName = 'ToDomainCN')][switch] $ToDomainCN,
        [Parameter(ParameterSetName = 'ToLastName')][switch] $ToLastName)
    Process {
        foreach ($Distinguished in $DistinguishedName) {
            if ($ToDomainCN) {
                $DN = $Distinguished -replace '.*?((DC=[^=]+,)+DC=[^=]+)$', '$1'
                $CN = $DN -replace ',DC=', '.' -replace "DC="
                if ($CN) { $CN }
            } elseif ($ToOrganizationalUnit) {
                $Value = [Regex]::Match($Distinguished, '(?=OU=)(.*\n?)(?<=.)').Value
                if ($Value) { $Value }
            } elseif ($ToMultipleOrganizationalUnit) {
                if ($IncludeParent) { $Distinguished }
                while ($true) {
                    $Distinguished = $Distinguished -replace '^.+?,(?=..=)'
                    if ($Distinguished -match '^DC=') { break }
                    $Distinguished
                }
            } elseif ($ToDC) {
                $Value = $Distinguished -replace '.*?((DC=[^=]+,)+DC=[^=]+)$', '$1'
                if ($Value) { $Value }
            } elseif ($ToLastName) {
                $NewDN = $Distinguished -split ",DC="
                if ($NewDN[0].Contains(",OU=")) { [Array] $ChangedDN = $NewDN[0] -split ",OU=" } elseif ($NewDN[0].Contains(",CN=")) { [Array] $ChangedDN = $NewDN[0] -split ",CN=" } else { [Array] $ChangedDN = $NewDN[0] }
                if ($ChangedDN[0].StartsWith('CN=')) { $ChangedDN[0] -replace 'CN=', '' } else { $ChangedDN[0] -replace 'OU=', '' }
            } else {
                $Regex = '^CN=(?<cn>.+?)(?<!\\),(?<ou>(?:(?:OU|CN).+?(?<!\\),)+(?<dc>DC.+?))$'
                $Found = $Distinguished -match $Regex
                if ($Found) { $Matches.cn }
            }
        }
    }
}
function Add-UserRightsAssignment {
    <#
    .SYNOPSIS
    Add identity object to the specified user rights Assignment role.
 
    .DESCRIPTION
    Add identity object to the specified user rights Assignment role.
 
    .PARAMETER UserRightsAssignment
    Choose user rights assignment
 
    .PARAMETER Computer
    Choose computer name. If not specified, the current computer will be used.
 
    .PARAMETER Identity
    Choose identity object by providing it's full name
 
    .PARAMETER Suppress
    Suppress the output. By default returns the identity what happend as an object.
 
    .EXAMPLE
    Add-UserRightsAssignment -UserRightsAssignment SeBackupPrivilege -Identity "Evotec\Administrator"
 
    .NOTES
    General notes
    #>

    [cmdletBinding(SupportsShouldProcess)]
    param([parameter(Mandatory)][LocalSecurityEditor.UserRightsAssignment] $UserRightsAssignment,
        [alias('ComputerName')][string] $Computer,
        [parameter(Mandatory)][alias('UserName')][string] $Identity,
        [switch] $Suppress)
    $ConvertedIdentity = Convert-Identity -Identity $Identity
    if ($PSCmdlet.ShouldProcess("Adding $($ConvertedIdentity.Name)/$($ConvertedIdentity.Sid) to $UserRightsAssignment", 'Add-UserRightsAssignment')) {
        try { if ($Computer) { $LsaWrapper = [LocalSecurityEditor.LsaWrapper]::new($Computer) } else { $LsaWrapper = [LocalSecurityEditor.LsaWrapper]::new() } } catch {
            if (-not $Suppress) {
                [PSCustomObject] @{"Action" = 'Add'
                    "Identity"              = $ConvertedIdentity.Name
                    'SID'                   = $ConvertedIdentity.Sid
                    "UserRightsAssignment"  = $UserRightsAssignment
                    "Status"                = 'Failed'
                    "Error"                 = $($_.Exception.Message)
                }
            }
            if ($PSBoundParameters.ErrorAction -eq 'Stop') {
                Write-Error "Could not create LsaWrapper. Error: $($_.Exception.Message)"
                return
            } else {
                Write-Warning -Message "Add-UserRightsAssignment - Could not create LsaWrapper. Error: $($_.Exception.Message)"
                return
            }
        }
        try {
            $null = $LsaWrapper.AddPrivileges($ConvertedIdentity.Name, $UserRightsAssignment)
            if (-not $Suppress) {
                [PSCustomObject] @{"Action" = 'Add'
                    "Identity"              = $ConvertedIdentity.Name
                    'SID'                   = $ConvertedIdentity.Sid
                    "UserRightsAssignment"  = $UserRightsAssignment
                    "Status"                = 'Success'
                    "Error"                 = ''
                }
            }
        } catch {
            if (-not $Suppress) {
                [PSCustomObject] @{"Action" = 'Add'
                    "Identity"              = $ConvertedIdentity.Name
                    'SID'                   = $ConvertedIdentity.Sid
                    "UserRightsAssignment"  = $UserRightsAssignment
                    "Status"                = 'Failure'
                    "Error"                 = $($_.Exception.Message)
                }
            }
            if ($PSBoundParameters.ErrorAction -eq 'Stop') {
                Write-Error "Could not add privileges for $UserRightsAssignment. Error: $($_.Exception.Message)"
                return
            } else { Write-Warning -Message "Add-UserRightsAssignment - Could not add privileges for $UserRightsAssignment. Error: $($_.Exception.Message)" }
        }
        try { $LsaWrapper.Dispose() } catch { if ($PSBoundParameters.ErrorAction -eq 'Stop') { Write-Error "Could not dispose LsaWrapper. Error: $($_.Exception.Message)" } else { Write-Warning -Message "Add-UserRightsAssignment - Could not dispose LsaWrapper. Error: $($_.Exception.Message)" } }
    } else {
        if (-not $Suppress) {
            [PSCustomObject] @{"Action" = 'Add'
                "Identity"              = $ConvertedIdentity.Name
                'SID'                   = $ConvertedIdentity.Sid
                "UserRightsAssignment"  = $UserRightsAssignment
                "Status"                = 'WhatIf'
                "Error"                 = 'WhatIf in use.'
            }
        }
    }
}
Function Get-SecurityPolicy {
    <#
    .SYNOPSIS
    Get security policy settings being read from Local Security Policy using secedit.exe
 
    .DESCRIPTION
    Get security policy settings being read from Local Security Policy using secedit.exe
 
    .PARAMETER ConfigFile
    Optional path to the config file to use. If not specified, the temp config file will be used.
 
    .PARAMETER All
    Get all settings from all sections
 
    .PARAMETER SystemAccess
    Get specific setting from System Access section
 
    .PARAMETER EventAudit
    Get specific setting from Event Audit section
 
    .EXAMPLE
    Get-SecurityPolicy -Verbose -All
 
    .EXAMPLE
    Get-SecurityPolicy -SystemAccess LockoutBadCount
 
    .EXAMPLE
    Get-SecurityPolicy -SystemAccess MinimumPasswordLength
 
    .NOTES
    General notes
    #>

    [CmdletBinding(DefaultParameterSetName = 'SystemAccess')]
    param([string] $ConfigFile = "$env:TEMP\security.cfg",
        [Parameter(ParameterSetName = 'All')][switch] $All,
        [Parameter(Mandatory, ParameterSetName = 'SystemAccess')][ValidateSet('MinimumPasswordAge' ,
            'MaximumPasswordAge' ,
            'MinimumPasswordLength' ,
            'PasswordComplexity' ,
            'PasswordHistorySize' ,
            'LockoutBadCount' ,
            'ResetLockoutCount' ,
            'LockoutDuration' ,
            'RequireLogonToChangePassword',
            'ForceLogoffWhenHourExpire' ,
            'NewAdministratorName' ,
            'NewGuestName' ,
            'ClearTextPassword' ,
            'LSAAnonymousNameLookup' ,
            'EnableAdminAccount' ,
            'EnableGuestAccount')][string] $SystemAccess,
        [Parameter(Mandatory, ParameterSetName = 'EventAudit')][ValidateSet('AuditSystemEvents' ,
            'AuditLogonEvents' ,
            'AuditObjectAccess' ,
            'AuditPrivilegeUse' ,
            'AuditPolicyChange' ,
            'AuditAccountManage' ,
            'AuditProcessTracking' ,
            'AuditDSAccess' ,
            'AuditAccountLogon')][string] $EventAudit)
    if (Test-Path -LiteralPath $ConfigFile -ErrorAction SilentlyContinue) { Remove-Item -LiteralPath $ConfigFile -Force }
    $pinfo = [System.Diagnostics.ProcessStartInfo]::new()
    $pinfo.FileName = "secedit.exe"
    $pinfo.RedirectStandardError = $true
    $pinfo.RedirectStandardOutput = $true
    $pinfo.UseShellExecute = $false
    $pinfo.Arguments = "/export /cfg `"$ConfigFile`""
    $p = [System.Diagnostics.Process]::new()
    $p.StartInfo = $pinfo
    $p.Start() | Out-Null
    $p.WaitForExit()
    $Output = $p.StandardOutput.ReadToEnd().Trim()
    if ($Output -like "*task has completed successfully*") {
        $SecurityPolicy = [ordered] @{}
        $index = 0
        if (Test-Path -LiteralPath $ConfigFile -ErrorAction SilentlyContinue) {
            try {
                $contents = Get-Content -LiteralPath $ConfigFile -Raw -ErrorAction Stop
                [regex]::Matches($contents, "(?<=\[)(.*)(?=\])") | ForEach-Object { $title = $_
                    [regex]::Matches($contents, "(?<=\]).*?((?=\[)|(\Z))", [System.Text.RegularExpressions.RegexOptions]::Singleline)[$index] | ForEach-Object { $section = [ordered] @{}
                        $_.value -split "\r\n" | Where-Object { $_.length -gt 0 } | ForEach-Object { $value = [regex]::Match($_, "(?<=\=).*").value
                            $name = [regex]::Match($_, ".*(?=\=)").value
                            $section[$name.tostring().trim()] = $value.tostring().trim() }
                        $SecurityPolicy[$Title.Value] = $Section }
                    $index += 1 }
            } catch { if ($PSBoundParameters.ErrorAction -eq 'Stop') { throw } else { Write-Warning -Message "Failed to export security policy. Error: $($_.Exception.Message)" } }
        }
        if ($All) { $SecurityPolicy } elseif ($SystemAccess) {
            [PSCustomObject] @{Name = $SystemAccess
                Value               = $SecurityPolicy['System Access'].$SystemAccess
            }
        } elseif ($EventAudit) {
            [PSCustomObject] @{Name = $EventAudit
                Value               = $SecurityPolicy['Event Audit'].$EventAudit
            }
        }
    } else { if ($PSBoundParameters.ErrorAction -eq 'Stop') { throw $Output } else { Write-Warning -Message "Failed to export security policy. Error: $($Output)" } }
}
function Get-UserRightsAssignment {
    <#
    .SYNOPSIS
    Provides a list of users assigned to a specific role.
 
    .DESCRIPTION
    Provides a list of users assigned to a specific role.
 
    .PARAMETER UserRightsAssignment
    Choose the role to list the users assigned to.
 
    .PARAMETER Computer
    Choose computer name. If not specified, the current computer will be used.
 
    .PARAMETER All
    Get all users for all user rights assignment for the specified computer.
 
    .EXAMPLE
    Get-UserRightsAssignment -All
 
    .EXAMPLE
    Get-UserRightsAssignment -UserRightsAssignment SeBackupPrivilege
 
    .NOTES
    General notes
    #>

    [cmdletBinding(DefaultParameterSetName = 'UserRights')]
    param([parameter(Mandatory, ParameterSetName = 'UserRights')][LocalSecurityEditor.UserRightsAssignment] $UserRightsAssignment,
        [alias('ComputerName')][string] $Computer,
        [parameter(ParameterSetName = 'All')][switch] $All)
    try { if ($Computer) { $LsaWrapper = [LocalSecurityEditor.LsaWrapper]::new($Computer) } else { $LsaWrapper = [LocalSecurityEditor.LsaWrapper]::new() } } catch {
        if ($PSBoundParameters.ErrorAction -eq 'Stop') {
            Write-Error "Could not create LsaWrapper. Error: $($_.Exception.Message)"
            return
        } else {
            Write-Warning -Message "Get-UserRightsAssignment - Could not create LsaWrapper. Error: $($_.Exception.Message)"
            return
        }
    }
    if ($All) {
        $Output = [ordered] @{}
        $EnumValues = [Enum]::GetNames([LocalSecurityEditor.UserRightsAssignment])
        foreach ($Value in $EnumValues | Sort-Object) {
            try { $PriviligeOutput = $LsaWrapper.GetPrivileges($Value) } catch {
                $PriviligeOutput = $null
                if ($PSBoundParameters.ErrorAction -eq 'Stop') {
                    Write-Error "Could not get privileges for $Value. Error: $($_.Exception.Message)"
                    return
                } else { Write-Warning -Message "Get-UserRightsAssignment - Could not get privileges for $Value. Error: $($_.Exception.Message)" }
            }
            $Output[$Value] = foreach ($P in $PriviligeOutput) { Convert-Identity -Identity $P }
        }
        $Output
    } else {
        try { $PriviligeOutput = $LsaWrapper.GetPrivileges($UserRightsAssignment) } catch {
            if ($PSBoundParameters.ErrorAction -eq 'Stop') {
                Write-Error "Could not get privileges for $UserRightsAssignment. Error: $($_.Exception.Message)"
                return
            } else { Write-Warning -Message "Get-UserRightsAssignment - Could not get privileges for $UserRightsAssignment. Error: $($_.Exception.Message)" }
        }
        foreach ($P in $PriviligeOutput) { Convert-Identity -Identity $P }
    }
    try { $LsaWrapper.Dispose() } catch {
        if ($PSBoundParameters.ErrorAction -eq 'Stop') {
            Write-Error "Could not dispose LsaWrapper. Error: $($_.Exception.Message)"
            return
        } else {
            Write-Warning -Message "Get-UserRightsAssignment - Could not dispose LsaWrapper. Error: $($_.Exception.Message)"
            return
        }
    }
}
function Remove-UserRightsAssignment {
    <#
    .SYNOPSIS
    Remove identity object from User Rights Assignment role
 
    .DESCRIPTION
    Remove identity object from User Rights Assignment role
 
    .PARAMETER UserRightsAssignment
    Choose user rights assignment
 
    .PARAMETER Computer
    Choose computer name. If not specified, the current computer will be used.
 
    .PARAMETER Identity
    Provide the user name to remove the user rights assignment for
 
    .PARAMETER Suppress
    Suppress the output. By default returns the identity what happend as an object.
 
    .EXAMPLE
    Remove-UserRightsAssignment -UserRightsAssignment SeBackupPrivilege -Identity "Evotec\Administrator"
 
    .NOTES
    General notes
    #>

    [cmdletBinding(SupportsShouldProcess)]
    param([parameter(Mandatory)][LocalSecurityEditor.UserRightsAssignment] $UserRightsAssignment,
        [alias('ComputerName')][string] $Computer,
        [parameter(Mandatory)][alias('UserName')][string] $Identity,
        [switch] $Suppress)
    $ConvertedIdentity = Convert-Identity -Identity $Identity
    try { if ($Computer) { $LsaWrapper = [LocalSecurityEditor.LsaWrapper]::new($Computer) } else { $LsaWrapper = [LocalSecurityEditor.LsaWrapper]::new() } } catch {
        if (-not $Suppress) {
            [PSCustomObject] @{"Action" = 'Remove'
                "Identity"              = $ConvertedIdentity.Name
                'SID'                   = $ConvertedIdentity.Sid
                "UserRightsAssignment"  = $UserRightsAssignment
                "Status"                = 'Failure'
                "Error"                 = $($_.Exception.Message)
            }
        }
        if ($PSBoundParameters.ErrorAction -eq 'Stop') {
            Write-Error "Could not create LsaWrapper. Error: $($_.Exception.Message)"
            return
        } else {
            Write-Warning -Message "Remove-UserRightsAssignment - Could not create LsaWrapper. Error: $($_.Exception.Message)"
            return
        }
    }
    if ($PSCmdlet.ShouldProcess("Removing $($ConvertedIdentity.Name)/$($ConvertedIdentity.Sid) from $UserRightsAssignment", 'Add-UserRightsAssignment')) {
        try {
            $LsaWrapper.RemovePrivileges($ConvertedIdentity.Name, $UserRightsAssignment)
            if (-not $Suppress) {
                [PSCustomObject] @{"Action" = 'Remove'
                    "Identity"              = $ConvertedIdentity.Name
                    'SID'                   = $ConvertedIdentity.Sid
                    "UserRightsAssignment"  = $UserRightsAssignment
                    "Status"                = 'Success'
                    "Error"                 = ''
                }
            }
        } catch {
            if (-not $Suppress) {
                [PSCustomObject] @{"Action" = 'Remove'
                    "Identity"              = $ConvertedIdentity.Name
                    'SID'                   = $ConvertedIdentity.Sid
                    "UserRightsAssignment"  = $UserRightsAssignment
                    "Status"                = 'Failure'
                    "Error"                 = $($_.Exception.Message)
                }
            }
            if ($PSBoundParameters.ErrorAction -eq 'Stop') {
                Write-Error "Could not remove privileges for $UserRightsAssignment. Error: $($_.Exception.Message)"
                return
            } else {
                Write-Warning -Message "Remove-UserRightsAssignment - Could not remove privileges for $UserRightsAssignment. Error: $($_.Exception.Message)"
                return
            }
        }
        try { $LsaWrapper.Dispose() } catch {
            if ($PSBoundParameters.ErrorAction -eq 'Stop') {
                Write-Error "Could not dispose LsaWrapper. Error: $($_.Exception.Message)"
                return
            } else {
                Write-Warning -Message "Remove-UserRightsAssignment - Could not dispose LsaWrapper. Error: $($_.Exception.Message)"
                return
            }
        }
    } else {
        if (-not $Suppress) {
            [PSCustomObject] @{"Action" = 'Remove'
                "Identity"              = $ConvertedIdentity.Name
                'SID'                   = $ConvertedIdentity.Sid
                "UserRightsAssignment"  = $UserRightsAssignment
                "Status"                = 'WhatIf'
                "Error"                 = 'WhatIf in use.'
            }
        }
    }
}
function Set-SecurityPolicy {
    <#
    .SYNOPSIS
    Set security policy ssetting in the Local Security Policy using secedit.exe
 
    .DESCRIPTION
    Set security policy ssetting in the Local Security Policy using secedit.exe
 
    .PARAMETER SystemAccess
    Choose specific system access policy.
 
    .PARAMETER Value
    Set specific value for the policy.
 
    .PARAMETER ConfigFile
    Optional path to the config file to use. If not specified, the temp config file will be used.
 
    .PARAMETER Suppress
    Suppress the output. By default output is provided
 
    .EXAMPLE
    Set-SecurityPolicy -SystemAccess MinimumPasswordAge -Value 1 -Whatif
 
    .NOTES
    General notes
    #>

    [cmdletBinding(SupportsShouldProcess)]
    param([Parameter(Mandatory)][ValidateSet('MinimumPasswordAge' ,
            'MaximumPasswordAge' ,
            'MinimumPasswordLength' ,
            'PasswordComplexity' ,
            'PasswordHistorySize' ,
            'LockoutBadCount' ,
            'ResetLockoutCount' ,
            'LockoutDuration' ,
            'RequireLogonToChangePassword',
            'ForceLogoffWhenHourExpire' ,
            'NewAdministratorName' ,
            'NewGuestName' ,
            'ClearTextPassword' ,
            'LSAAnonymousNameLookup' ,
            'EnableAdminAccount' ,
            'EnableGuestAccount')][string] $SystemAccess,
        [Parameter(Mandatory)][object] $Value,
        [string] $ConfigFile = "$env:TEMP\security.cfg",
        [switch] $Suppress)
    if ($PSCmdlet.ShouldProcess("$SystemAccess to $Value", "Set-SecurityPolicy")) {
        try { $Object = Get-SecurityPolicy -ConfigFile $ConfigFile -ErrorAction Stop } catch {
            if (-not $Suppress) {
                [PSCustomObject] @{"Name" = $SystemAccess
                    "Value"               = $Value
                    "Status"              = $false
                    "Error"               = $($_.Exception.Message)
                }
            }
            if ($PSBoundParameters.ErrorAction -eq 'Stop') { throw } else {
                Write-Warning -Message "Failed to read security policy. Error: $($_.Exception.Message)"
                return
            }
        }
        if ($SystemAccess) { $Object.'System Access'.$SystemAccess = $Value }
        try {
            $Object.GetEnumerator() | ForEach-Object { "[$($_.Name)]"
                $_.Value | ForEach-Object { $_.GetEnumerator() | ForEach-Object { "$($_.Name)=$($_.Value)" } } } | Out-File -LiteralPath $ConfigFile -ErrorAction Stop
        } catch {
            if (-not $Suppress) {
                [PSCustomObject] @{"Name" = $SystemAccess
                    "Value"               = $Value
                    "Status"              = $false
                    "Error"               = $($_.Exception.Message)
                }
            }
            if ($PSBoundParameters.ErrorAction -eq 'Stop') { throw } else {
                Write-Warning -Message "Failed to save security policy. Error: $($_.Exception.Message)"
                return
            }
        }
        $pinfo = [System.Diagnostics.ProcessStartInfo]::new()
        $pinfo.FileName = "secedit.exe"
        $pinfo.RedirectStandardError = $true
        $pinfo.RedirectStandardOutput = $true
        $pinfo.UseShellExecute = $false
        $pinfo.Arguments = " /configure /db c:\windows\security\local.sdb /cfg `"$ConfigFile`" /areas SECURITYPOLICY"
        $p = [System.Diagnostics.Process]::new()
        $p.StartInfo = $pinfo
        $p.Start() | Out-Null
        $p.WaitForExit()
        $Output = $p.StandardOutput.ReadToEnd()
        $Errors = $p.StandardError.ReadToEnd()
        if ($Output -like "*task has completed successfully*") {
            if (-not $Suppress) {
                [PSCustomObject] @{"Name" = $SystemAccess
                    "Value"               = $Value
                    "Status"              = $true
                    "Error"               = ""
                }
            }
        } else {
            if (-not $Suppress) {
                [PSCustomObject] @{"Name" = $SystemAccess
                    "Value"               = $Value
                    "Status"              = $false
                    "Error"               = $Errors
                }
            }
            if ($PSBoundParameters.ErrorAction -eq 'Stop') { throw $Errors } else { Write-Warning -Message "Failed to save security policy. Error: $Errors" }
        }
    } else {}
}
function Set-UserRightsAssignment {
    <#
    .SYNOPSIS
    Overwrites current user rights assignment with the specified identities.
 
    .DESCRIPTION
    Overwrites current user rights assignment with the specified identities.
    It does so by adding only missing rights, and removing the ones that require removal.
    Identies that don't require changing are left as is.
 
    .PARAMETER UserRightsAssignment
    Choose user rights assignment
 
    .PARAMETER Computer
    Choose computer name. If not specified, the current computer will be used.
 
    .PARAMETER Identity
    Provide the identities to set the user rights assignment for
 
    .PARAMETER Suppress
    Suppress the output. By default returns the identity what happend as an object.
 
    .EXAMPLE
    $Identity = @(
        'BUILTIN\Backup Operators'
        'BUILTIN\Administrators'
        'Guest'
        'BUILTIN\Users'
        'przemyslaw.klys'
    )
 
    Set-UserRightsAssignment-UserRightsAssignment SeBackupPrivilege -Identity $Identity -WhatIf
 
    .NOTES
    General notes
    #>

    [CmdletBinding(SupportsShouldProcess)]
    param([parameter(Mandatory, ParameterSetName = 'UserRights')][LocalSecurityEditor.UserRightsAssignment] $UserRightsAssignment,
        [alias('ComputerName')][string] $Computer,
        [alias('UserName')][string[]] $Identity,
        [switch] $Suppress)
    $ToDo = [ordered] @{}
    $WhatHappend = [ordered] @{}
    $ConvertedIdentities = foreach ($I in $Identity) { Convert-Identity -Identity $I }
    $CurrentSettings = Get-UserRightsAssignment -UserRightsAssignment $UserRightsAssignment -Computer $Computer
    foreach ($I in $ConvertedIdentities.Name) { if ($I -in $CurrentSettings.Name) { $ToDo[$I] = 'DoNothing' } else { $ToDo[$I] = 'Add' } }
    foreach ($I in $CurrentSettings.Name) { if ($I -notin $ConvertedIdentities.Name) { $ToDo[$I] = 'Remove' } }
    foreach ($Action in $ToDo.Keys) {
        if ($ToDo[$Action] -eq 'Add') {
            $DidItWork = Add-UserRightsAssignment -UserRightsAssignment $UserRightsAssignment -Computer $Computer -Identity $Action
            $WhatHappend[$Action] = $DidItWork
        } elseif ($ToDo[$Action] -eq 'Remove') {
            $DidItWork = Remove-UserRightsAssignment -UserRightsAssignment $UserRightsAssignment -Computer $Computer -Identity $Action
            $WhatHappend[$Action] = $DidItWork
        } elseif ($ToDo[$Action] -eq 'DoNothing') {
            $DoNothingIdentity = Convert-Identity -Identity $I
            $WhatHappend[$Action] = [PSCustomObject] @{"Action" = 'DoNothing'
                "Identity"                                      = $Action
                'SID'                                           = $DoNothingIdentity.Sid
                "UserRightsAssignment"                          = $UserRightsAssignment
                "Status"                                        = 'NoAction'
                "Error"                                         = ''
            }
        }
    }
    if (-not $Suppress) { $WhatHappend }
}
Export-ModuleMember -Function @('Add-UserRightsAssignment', 'Get-SecurityPolicy', 'Get-UserRightsAssignment', 'Remove-UserRightsAssignment', 'Set-SecurityPolicy', 'Set-UserRightsAssignment') -Alias @()
# SIG # Begin signature block
# MIInQwYJKoZIhvcNAQcCoIInNDCCJzACAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUooB5Qv+gsdEsu6uQI7DH1lsj
# UWOggiFhMIIDtzCCAp+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+8xEypTR23NavhJvZMgY2kEXBEKEEDaXs0LoPbn6hMcepR2A4wggWxMIIEmaAD
# AgECAhABJAr7HjgLihbxS3Gd9NPAMA0GCSqGSIb3DQEBDAUAMGUxCzAJBgNVBAYT
# AlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2Vy
# dC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0y
# MjA2MDkwMDAwMDBaFw0zMTExMDkyMzU5NTlaMGIxCzAJBgNVBAYTAlVTMRUwEwYD
# VQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAf
# BgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEB
# BQADggIPADCCAgoCggIBAL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4Smn
# PVirdprNrnsbhA3EMB/zG6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6f
# qVcWWVVyr2iTcMKyunWZanMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O
# 7F5OyJP4IWGbNOsFxl7sWxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZ
# Vu7Ke13jrclPXuU15zHL2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4F
# fYj1gj4QkXCrVYJBMtfbBHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLm
# qaBn3aQnvKFPObURWBf3JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMre
# Sx7nDmOu5tTvkpI6nj3cAORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/ch
# srIRt7t/8tWMcCxBYKqxYxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+U
# DCEdslQpJYls5Q5SUUd0viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xM
# dT9j7CFfxCBRa2+xq4aLT8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUb
# AgMBAAGjggFeMIIBWjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTs1+OC0nFd
# ZEzfLmc/57qYrhwPTzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzAO
# BgNVHQ8BAf8EBAMCAYYwEwYDVR0lBAwwCgYIKwYBBQUHAwgweQYIKwYBBQUHAQEE
# bTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQwYIKwYB
# BQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3Vy
# ZWRJRFJvb3RDQS5jcnQwRQYDVR0fBD4wPDA6oDigNoY0aHR0cDovL2NybDMuZGln
# aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDAgBgNVHSAEGTAX
# MAgGBmeBDAEEAjALBglghkgBhv1sBwEwDQYJKoZIhvcNAQEMBQADggEBAJoWAqUB
# 74H7DbRYsnitqCMZ2XM32mCeUdfL+C9AuaMffEBOMz6QPOeJAXWF6GJ7HVbgcbre
# XsY3vHlcYgBN+El6UU0GMvPF0gAqJyDqiS4VOeAsPvh1fCyCQWE1DyPQ7TWV0oiV
# KUPL4KZYEHxTjp9FySA3FMDtGbp+dznSVJbHphHfNDP2dVJCSxydjZbVlWxHEhQk
# XyZB+hpGvd6w5ZFHA6wYCMvL22aJfyucZb++N06+LfOdSsPMzEdeyJWVrdHLuyoG
# IPk/cuo260VyknopexQDPPtN1khxehARigh0zWwbBFzSipUDdlFQU9Yu90pGw64Q
# LHFMsIe2JzdEYEQwggauMIIElqADAgECAhAHNje3JFR82Ees/ShmKl5bMA0GCSqG
# SIb3DQEBCwUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMx
# GTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRy
# dXN0ZWQgUm9vdCBHNDAeFw0yMjAzMjMwMDAwMDBaFw0zNzAzMjIyMzU5NTlaMGMx
# CzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMy
# RGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcg
# Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDGhjUGSbPBPXJJUVXH
# JQPE8pE3qZdRodbSg9GeTKJtoLDMg/la9hGhRBVCX6SI82j6ffOciQt/nR+eDzMf
# UBMLJnOWbfhXqAJ9/UO0hNoR8XOxs+4rgISKIhjf69o9xBd/qxkrPkLcZ47qUT3w
# 1lbU5ygt69OxtXXnHwZljZQp09nsad/ZkIdGAHvbREGJ3HxqV3rwN3mfXazL6IRk
# tFLydkf3YYMZ3V+0VAshaG43IbtArF+y3kp9zvU5EmfvDqVjbOSmxR3NNg1c1eYb
# qMFkdECnwHLFuk4fsbVYTXn+149zk6wsOeKlSNbwsDETqVcplicu9Yemj052FVUm
# cJgmf6AaRyBD40NjgHt1biclkJg6OBGz9vae5jtb7IHeIhTZgirHkr+g3uM+onP6
# 5x9abJTyUpURK1h0QCirc0PO30qhHGs4xSnzyqqWc0Jon7ZGs506o9UD4L/wojzK
# QtwYSH8UNM/STKvvmz3+DrhkKvp1KCRB7UK/BZxmSVJQ9FHzNklNiyDSLFc1eSuo
# 80VgvCONWPfcYd6T/jnA+bIwpUzX6ZhKWD7TA4j+s4/TXkt2ElGTyYwMO1uKIqjB
# Jgj5FBASA31fI7tk42PgpuE+9sJ0sj8eCXbsq11GdeJgo1gJASgADoRU7s7pXche
# MBK9Rp6103a50g5rmQzSM7TNsQIDAQABo4IBXTCCAVkwEgYDVR0TAQH/BAgwBgEB
# /wIBADAdBgNVHQ4EFgQUuhbZbU2FL3MpdpovdYxqII+eyG8wHwYDVR0jBBgwFoAU
# 7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoG
# CCsGAQUFBwMIMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29j
# c3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdp
# Y2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNVHR8EPDA6MDig
# NqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9v
# dEc0LmNybDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwDQYJKoZI
# hvcNAQELBQADggIBAH1ZjsCTtm+YqUQiAX5m1tghQuGwGC4QTRPPMFPOvxj7x1Bd
# 4ksp+3CKDaopafxpwc8dB+k+YMjYC+VcW9dth/qEICU0MWfNthKWb8RQTGIdDAiC
# qBa9qVbPFXONASIlzpVpP0d3+3J0FNf/q0+KLHqrhc1DX+1gtqpPkWaeLJ7giqzl
# /Yy8ZCaHbJK9nXzQcAp876i8dU+6WvepELJd6f8oVInw1YpxdmXazPByoyP6wCeC
# RK6ZJxurJB4mwbfeKuv2nrF5mYGjVoarCkXJ38SNoOeY+/umnXKvxMfBwWpx2cYT
# gAnEtp/Nh4cku0+jSbl3ZpHxcpzpSwJSpzd+k1OsOx0ISQ+UzTl63f8lY5knLD0/
# a6fxZsNBzU+2QJshIUDQtxMkzdwdeDrknq3lNHGS1yZr5Dhzq6YBT70/O3itTK37
# xJV77QpfMzmHQXh6OOmc4d0j/R0o08f56PGYX/sr2H7yRp11LB4nLCbbbxV7HhmL
# NriT1ObyF5lZynDwN7+YAN8gFk8n+2BnFqFmut1VwDophrCYoCvtlUG3OtUVmDG0
# YgkPCr2B2RP+v6TR81fZvAT6gt4y3wSJ8ADNXcL50CN/AAvkdgIm2fBldkKmKYcJ
# RyvmfxqkhQ/8mJb2VVQrH4D6wPIOK+XW+6kvRBVK5xMOHds3OBqhK/bt1nz8MIIG
# xjCCBK6gAwIBAgIQCnpKiJ7JmUKQBmM4TYaXnTANBgkqhkiG9w0BAQsFADBjMQsw
# CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRp
# Z2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYgVGltZVN0YW1waW5nIENB
# MB4XDTIyMDMyOTAwMDAwMFoXDTMzMDMxNDIzNTk1OVowTDELMAkGA1UEBhMCVVMx
# FzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMSQwIgYDVQQDExtEaWdpQ2VydCBUaW1l
# c3RhbXAgMjAyMiAtIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC5
# KpYjply8X9ZJ8BWCGPQz7sxcbOPgJS7SMeQ8QK77q8TjeF1+XDbq9SWNQ6OB6zhj
# +TyIad480jBRDTEHukZu6aNLSOiJQX8Nstb5hPGYPgu/CoQScWyhYiYB087DbP2s
# O37cKhypvTDGFtjavOuy8YPRn80JxblBakVCI0Fa+GDTZSw+fl69lqfw/LH09CjP
# QnkfO8eTB2ho5UQ0Ul8PUN7UWSxEdMAyRxlb4pguj9DKP//GZ888k5VOhOl2GJiZ
# ERTFKwygM9tNJIXogpThLwPuf4UCyYbh1RgUtwRF8+A4vaK9enGY7BXn/S7s0psA
# iqwdjTuAaP7QWZgmzuDtrn8oLsKe4AtLyAjRMruD+iM82f/SjLv3QyPf58NaBWJ+
# cCzlK7I9Y+rIroEga0OJyH5fsBrdGb2fdEEKr7mOCdN0oS+wVHbBkE+U7IZh/9sR
# L5IDMM4wt4sPXUSzQx0jUM2R1y+d+/zNscGnxA7E70A+GToC1DGpaaBJ+XXhm+ho
# 5GoMj+vksSF7hmdYfn8f6CvkFLIW1oGhytowkGvub3XAsDYmsgg7/72+f2wTGN/G
# baR5Sa2Lf2GHBWj31HDjQpXonrubS7LitkE956+nGijJrWGwoEEYGU7tR5thle0+
# C2Fa6j56mJJRzT/JROeAiylCcvd5st2E6ifu/n16awIDAQABo4IBizCCAYcwDgYD
# VR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUH
# AwgwIAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJYIZIAYb9bAcBMB8GA1UdIwQYMBaA
# FLoW2W1NhS9zKXaaL3WMaiCPnshvMB0GA1UdDgQWBBSNZLeJIf5WWESEYafqbxw2
# j92vDTBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsMy5kaWdpY2VydC5jb20v
# RGlnaUNlcnRUcnVzdGVkRzRSU0E0MDk2U0hBMjU2VGltZVN0YW1waW5nQ0EuY3Js
# MIGQBggrBgEFBQcBAQSBgzCBgDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGln
# aWNlcnQuY29tMFgGCCsGAQUFBzAChkxodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5j
# b20vRGlnaUNlcnRUcnVzdGVkRzRSU0E0MDk2U0hBMjU2VGltZVN0YW1waW5nQ0Eu
# Y3J0MA0GCSqGSIb3DQEBCwUAA4ICAQANLSN0ptH1+OpLmT8B5PYM5K8WndmzjJeC
# KZxDbwEtqzi1cBG/hBmLP13lhk++kzreKjlaOU7YhFmlvBuYquhs79FIaRk4W8+J
# OR1wcNlO3yMibNXf9lnLocLqTHbKodyhK5a4m1WpGmt90fUCCU+C1qVziMSYgN/u
# SZW3s8zFp+4O4e8eOIqf7xHJMUpYtt84fMv6XPfkU79uCnx+196Y1SlliQ+inMBl
# 9AEiZcfqXnSmWzWSUHz0F6aHZE8+RokWYyBry/J70DXjSnBIqbbnHWC9BCIVJXAG
# cqlEO2lHEdPu6cegPk8QuTA25POqaQmoi35komWUEftuMvH1uzitzcCTEdUyeEpL
# NypM81zctoXAu3AwVXjWmP5UbX9xqUgaeN1Gdy4besAzivhKKIwSqHPPLfnTI/Ke
# GeANlCig69saUaCVgo4oa6TOnXbeqXOqSGpZQ65f6vgPBkKd3wZolv4qoHRbY2be
# ayy4eKpNcG3wLPEHFX41tOa1DKKZpdcVazUOhdbgLMzgDCS4fFILHpl878jIxYxY
# aa+rPeHPzH0VrhS/inHfypex2EfqHIXgRU4SHBQpWMxv03/LvsEOSm8gnK7ZczJZ
# COctkqEaEf4ymKZdK5fgi9OczG21Da5HYzhHF1tvE9pqEG4fSbdEW7QICodaWQR2
# EaGndwITHDGCBUwwggVIAgEBMIGGMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxE
# aWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNVBAMT
# KERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJRCBDb2RlIFNpZ25pbmcgQ0ECEATV3B9I
# 6snYUgC6zZqbKqcwCQYFKw4DAhoFAKB4MBgGCisGAQQBgjcCAQwxCjAIoAKAAKEC
# gAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwG
# CisGAQQBgjcCARUwIwYJKoZIhvcNAQkEMRYEFMGXQQFYeXiZJahN4zB89rwouXrZ
# MA0GCSqGSIb3DQEBAQUABIIBAB1OAyNzINZi6SQ0Ld98BcACF31fWq/AE5Y2s2P9
# psctforR3bE74opUGzHonjEr7HkbYz6BfE+J+CxmbTlingzJCObrRxHmYqvdleL8
# Wx2C9QfmPd/QFto3zbqW7msZcd19NJRpdOYyjULcEYRJ5/kdPpYWxYocCwbSJRzu
# PUNGqhl3W6bXoszNoo5eKibC0y31RwacEX90nYRT/j2iK+CnlyHDfPASWljlVUGv
# hZapGOHz1Trn7Wj9MOQ/df7uceRxfbj7w+kJmg8mOLRNtrIguNywY+n3jia8dgta
# RLByMNlOXilvhyLZbF2thEGZf5hKG9rcWX9N22Z8l5nuodChggMgMIIDHAYJKoZI
# hvcNAQkGMYIDDTCCAwkCAQEwdzBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGln
# aUNlcnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5
# NiBTSEEyNTYgVGltZVN0YW1waW5nIENBAhAKekqInsmZQpAGYzhNhpedMA0GCWCG
# SAFlAwQCAQUAoGkwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0B
# CQUxDxcNMjIwNjE1MDYxNTA0WjAvBgkqhkiG9w0BCQQxIgQgbKUVVQvDqF97xJJK
# KMC7x0MCfJdhR3FrwDBSPyPtLRAwDQYJKoZIhvcNAQEBBQAEggIAe9mZuMYdYKVw
# HtKxVCzpuMdWLshsnbUYtgx9GQyNO4CVjRdEya4n/BE3AGQdv/aMDw5FTS2i3JeL
# 2MocN9IGw5tkokke55zW1MxdmV9+68v4HHIYwX6zuReGwZUl8IiAyrNFysvoVpo1
# GEgi15Wmt+11pnKPKBrqniZFxpxqfmHGXcmkzhVBufn6ygTSAsrDiYdC2C4YVXUk
# GHaRogViBCIQVCiqRKvs//T+f3DB9LMMejvvyikGr1RjZvfnKSPuV1+ADNfpiJKF
# cn+5fVDQ0fsDkwDR/7LSrlmEyPDy+m6zThsHpbJe54/3ocyXN+QnK7fn+BSTRgKW
# vbdIfmP54jdgaB7FTCYlN4qjGeGz0Zhhr84GqMllM2klyhWgGPKQZnV6Bq0jM4FB
# OIMlpXGTHoiENcrduGbAxg6m+oAHpDY2S7wgKb8wMI9NcA06UmyNqRP46NIfkzEG
# 5iVxRXvqVvvV2PhHFtcKI4RiazZZQYEVVteSv6/P30Mso8QDpjei4/RxzI8Kz5JW
# +8Fz46iVfATaJTqNyhu9KbSQgvvcha/RpoVcvCtr6jWmrJgJ/yEkfcfGLWONLoMJ
# ui/SaO3ZoMedUl7zpZXN4V5D75Q47m9wDXe1zH0KZMnfrw9RiNaAIfP4SwoS59X6
# m/J+eT1exEnJUmvjpa/Ze5vAP++jPs8=
# SIG # End signature block