Full Code of darkoperator/Posh-Sysmon for AI

master f89a27fd1897 cached
65 files
822.3 KB
210.7k tokens
1 requests
Download .txt
Showing preview only (854K chars total). Download the full file or copy to clipboard to get everything.
Repository: darkoperator/Posh-Sysmon
Branch: master
Commit: f89a27fd1897
Files: 65
Total size: 822.3 KB

Directory structure:
gitextract_jqcvzr7i/

├── .gitattributes
├── Config.ps1
├── Filters.ps1
├── Format/
│   ├── Sysmon.ConfigOption.ps1xml
│   ├── Sysmon.Rule.Filter.ps1xml
│   └── Sysmon.Rule.ps1xml
├── Functions/
│   ├── ConvertFrom-SysmonBinaryConfiguration.ps1
│   ├── ConvertTo-SysmonXMLConfiguration.ps1
│   ├── Get-SysmonConfiguration.ps1
│   ├── Get-SysmonEventData.ps1
│   ├── Get-SysmonHashingAlgorithm.ps1
│   ├── Get-SysmonRule.ps1
│   ├── Get-SysmonRuleFilter.ps1
│   ├── New-SysmonConfiguration.ps1
│   ├── New-SysmonCreateRemoteThreadFilter.ps1
│   ├── New-SysmonDriverLoadFilter.ps1
│   ├── New-SysmonFileCreateFilter.ps1
│   ├── New-SysmonFileCreateStreamHashFilter.ps1
│   ├── New-SysmonImageLoadFilter.ps1
│   ├── New-SysmonNetworkConnectFilter.ps1
│   ├── New-SysmonPipeFilter.ps1
│   ├── New-SysmonProcessAccessFilter.ps1
│   ├── New-SysmonProcessCreateFilter.ps1
│   ├── New-SysmonProcessTerminateFilter.ps1
│   ├── New-SysmonRawAccessReadFilter.ps1
│   ├── New-SysmonRegistryFilter.ps1
│   ├── New-SysmonWmiFilter.ps1
│   ├── Remove-SysmonRule.ps1
│   ├── Remove-SysmonRuleFilter.ps1
│   ├── Schemas/
│   │   ├── SysmonConfigurationSchema_3_40.xsd
│   │   └── SysmonConfigurationSchema_4_00.xsd
│   ├── Set-SysmonHashingAlgorithm.ps1
│   └── Set-SysmonRule.ps1
├── LICENSE
├── Posh-SysMon.psm1
├── Posh-Sysmon.psd1
├── README.md
├── build.ps1
├── docs/
│   ├── Get-SysmonEventData.md
│   ├── Get-SysmonHashingAlgorithm.md
│   ├── Get-SysmonRule.md
│   ├── Get-SysmonRuleFilter.md
│   ├── New-SysmonConfiguration.md
│   ├── New-SysmonDriverLoadFilter.md
│   ├── New-SysmonFileCreateFilter.md
│   ├── New-SysmonFileCreateStreamHash.md
│   ├── New-SysmonFileCreateStreamHashFilter.md
│   ├── New-SysmonImageLoadFilter.md
│   ├── New-SysmonNetworkConnectFilter.md
│   ├── New-SysmonPipeEvent.md
│   ├── New-SysmonPipeFilter.md
│   ├── New-SysmonProcessAccessFilter.md
│   ├── New-SysmonProcessCreateFilter.md
│   ├── New-SysmonProcessTerminateFilter.md
│   ├── New-SysmonRegistryEvent.md
│   ├── New-SysmonRegistryFilter.md
│   ├── Remove-SysmonRule.md
│   ├── Remove-SysmonRuleFilter.md
│   ├── Set-SysmonHashingAlgorithm.md
│   └── Set-SysmonRule.md
├── en-US/
│   ├── Posh-SysMon-help.xml
│   └── Posh-SysMon.psm1-Help.xml
└── lib/
    ├── sysmon3_1.dtd
    ├── sysmon3_2.dtd
    └── sysmon3_3.dtd

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitattributes
================================================
# Auto detect text files and perform LF normalization
* text=auto

# Custom for Visual Studio
*.cs     diff=csharp
*.sln    merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union

# Standard to msysgit
*.doc	 diff=astextplain
*.DOC	 diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot  diff=astextplain
*.DOT  diff=astextplain
*.pdf  diff=astextplain
*.PDF	 diff=astextplain
*.rtf	 diff=astextplain
*.RTF	 diff=astextplain

# Custom for PowerShell*.psm1 text
*.psd1 text
*.psm1 text
*.ps1xml text

================================================
FILE: Config.ps1
================================================

#  .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonConfiguration
{
    [CmdletBinding(HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonConfiguration.md')]
    Param
    (
        # Path to write XML config file.
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=0)]
        [String]
        $Path,

        # Specify one or more hash algorithms used for image identification
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=1)]
        [ValidateSet('ALL', 'MD5', 'SHA1', 'SHA256', 'IMPHASH')]
        [string[]]
        $HashingAlgorithm,



        # Log Network Connections
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=2)]
        [Switch]
        $NetworkConnect,

        # Log process loading of modules.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=3)]
        [Switch]
        $DriverLoad,

        # Log process loading of modules.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=4)]
        [Switch]
        $ImageLoad,

        # Log create remote thread actions.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=5)]
        [Switch]
        $CreateRemoteThread,

        # Log file creation time modifications.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=6)]
        [Switch]
        $FileCreateTime,

        # Log process creation.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=7)]
        [Switch]
        $ProcessCreate,

        # Log process termination.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=8)]
        [Switch]
        $ProcessTerminate,

        # Log when a running process opens another process.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=9)]
        [Switch]
        $ProcessAccess,

        # Log raw access reads of files.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=10)]
        [Switch]
        $RawAccessRead,

        # Check for signature certificate revocation.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=11 )]
        [Switch]
        $CheckRevocation,

        # Log Registry events.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=12 )]
        [Switch]
        $RegistryEvent,

        # Log File Creation events.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=13 )]
        [Switch]
        $FileCreate,

        # Log File Stream creations events.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=14 )]
        [Switch]
        $FileCreateStreamHash,

        # Log NamedPipes connection and creations events.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=15 )]
        [Switch]
        $PipeEvent,

        # WMI Permanent Event component events.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=16 )]
        [Switch]
        $WmiEvent,

        # Comment for purpose of the configuration file.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true)]
        [String]
        $Comment,

        # Schema Vesion for the configuration file, default is 3.3.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true)]
                   [ValidateSet('2.0','3.0', '3.1', '3.2','3.3', '3.4')]
        [String]
        $SchemaVersion = '3.4'
    )

    Begin{}
    Process
    {
        if ($HashingAlgorithm -contains 'ALL')
        {
            $Hash = '*'
        }
        else
        {
            $Hash = $HashingAlgorithm -join ','
        }

        $Config = ($ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Path))

        # get an XMLTextWriter to create the XML

        $XmlWriter = New-Object System.XMl.XmlTextWriter($Config,$Null)

        # choose a pretty formatting:
        $xmlWriter.Formatting = 'Indented'
        $xmlWriter.Indentation = 1

        # write the header
        if ($Comment)
        {
            $xmlWriter.WriteComment($Comment)
        }
        $xmlWriter.WriteStartElement('Sysmon')

        $XmlWriter.WriteAttributeString('schemaversion', $SchemaVersion)

        Write-Verbose -Message "Enabling hashing algorithms : $($Hash)"
        $xmlWriter.WriteElementString('HashAlgorithms',$Hash)

        # Enable checking revocation.
        if ($CheckRevocation)
        {
            if ($SchemaVersion -in @('3.1','3.2','3.3','3.4'))
            {
                Write-Verbose -message 'Enabling CheckRevocation.'
                $xmlWriter.WriteElementString('CheckRevocation','')
            }
            else
            {
                Write-Warning -Message 'CheckRevocation was not enabled because it is not supported in this SchemaVersion.'
            }
        }

        # Create empty EventFiltering section.
        $xmlWriter.WriteStartElement('EventFiltering')

        if ($NetworkConnect)
        {
            Write-Verbose -Message 'Enabling network connection logging for all connections by setting no filter and onmatch to exclude.'
            $xmlWriter.WriteStartElement('NetworkConnect')
            $XmlWriter.WriteAttributeString('onmatch', 'exclude')
            $xmlWriter.WriteFullEndElement()
        }

        if ($DriverLoad)
        {
            Write-Verbose -Message 'Enabling logging all driver loading by setting no filter and onmatch to exclude.'
            $xmlWriter.WriteStartElement('DriverLoad ')
            $XmlWriter.WriteAttributeString('onmatch', 'exclude')
            $xmlWriter.WriteFullEndElement()
        }

        if ($ImageLoad)
        {
            Write-Verbose -Message 'Enabling logging all image loading by setting no filter and onmatch to exclude.'
            $xmlWriter.WriteStartElement('ImageLoad ')
            $XmlWriter.WriteAttributeString('onmatch', 'exclude')
            $xmlWriter.WriteFullEndElement()
        }

        if ($CreateRemoteThread)
        {
            Write-Verbose -Message 'Enabling logging all  CreateRemoteThread API actions by setting no filter and onmatch to exclude.'
            $xmlWriter.WriteStartElement('CreateRemoteThread ')
            $XmlWriter.WriteAttributeString('onmatch', 'exclude')
            $xmlWriter.WriteFullEndElement()
        }

        if ($ProcessCreate)
        {
            Write-Verbose -Message 'Enabling logging all  process creation by setting no filter and onmatch to exclude.'
            $xmlWriter.WriteStartElement('ProcessCreate ')
            $XmlWriter.WriteAttributeString('onmatch', 'exclude')
            $xmlWriter.WriteFullEndElement()
        }

        if ($ProcessTerminate)
        {
            Write-Verbose -Message 'Enabling logging all  process termination by setting no filter and onmatch to exclude.'
            $xmlWriter.WriteStartElement('ProcessTerminate ')
            $XmlWriter.WriteAttributeString('onmatch', 'exclude')
            $xmlWriter.WriteFullEndElement()
        }

        if ($FileCreateTime)
        {
            Write-Verbose -Message 'Enabling logging all  process creation by setting no filter and onmatch to exclude.'
            $xmlWriter.WriteStartElement('FileCreateTime ')
            $XmlWriter.WriteAttributeString('onmatch', 'exclude')
            $xmlWriter.WriteFullEndElement()
        }

        if ($ProcessAccess)
        {
            Write-Verbose -Message 'Enabling logging all  process access by setting no filter and onmatch to exclude.'
            $xmlWriter.WriteStartElement('ProcessAccess ')
            $XmlWriter.WriteAttributeString('onmatch', 'exclude')
            $xmlWriter.WriteFullEndElement()
        }

        if ($RawAccessRead)
        {
            Write-Verbose -Message 'Enabling logging all  process access by setting no filter and onmatch to exclude.'
            $xmlWriter.WriteStartElement('RawAccessRead ')
            $XmlWriter.WriteAttributeString('onmatch', 'exclude')
            $xmlWriter.WriteFullEndElement()
        }

        # Log registry events.
        if ($RegistryEvent)
        {
            if ($SchemaVersion -gt 3.2)
            {
                Write-Verbose -message 'Enabling RegistryEvent.'
                $xmlWriter.WriteStartElement('RegistryEvent ')
                $XmlWriter.WriteAttributeString('onmatch', 'exclude')
                $xmlWriter.WriteFullEndElement()
            }
            else
            {
                Write-Warning -Message 'RegistryEvent was not enabled because it is not supported in this SchemaVersion.'
            }
        }

        # Log file create events.
        if ($FileCreate)
        {
            if ($SchemaVersion -gt 3.2)
            {
                Write-Verbose -message 'Enabling FileCreate.'
                $xmlWriter.WriteStartElement('FileCreate ')
                $XmlWriter.WriteAttributeString('onmatch', 'exclude')
                $xmlWriter.WriteFullEndElement()
            }
            else
            {
                Write-Warning -Message 'FileCreate was not enabled because it is not supported in this SchemaVersion.'
            }
        }

        # Log file create events.
        if ($FileCreateStreamHash)
        {
            if ($SchemaVersion -gt 3.2)
            {
                Write-Verbose -message 'Enabling FileCreateStreamHash.'
                $xmlWriter.WriteStartElement('FileCreateStreamHash ')
                $XmlWriter.WriteAttributeString('onmatch', 'exclude')
                $xmlWriter.WriteFullEndElement()
            }
            else
            {
                Write-Warning -Message 'FileCreateStreamHash was not enabled because it is not supported in this SchemaVersion.'
            }
        }

        # NamedPipes create and connect events.
        if ($PipeEvent)
        {
            if ($SchemaVersion -gt 3.2)
            {
                Write-Verbose -message 'Enabling PipeEvent.'
                $xmlWriter.WriteStartElement('PipeEvent ')
                $XmlWriter.WriteAttributeString('onmatch', 'exclude')
                $xmlWriter.WriteFullEndElement()
            }
            else
            {
                Write-Warning -Message 'PipeEvent was not enabled because it is not supported in this SchemaVersion.'
            }
        }

        # NamedPipes create and connect events.
        if ($WmiEvent)
        {
            if ($SchemaVersion -gt 3.4)
            {
                Write-Verbose -message 'Enabling WmiEvent.'
                $xmlWriter.WriteStartElement('WmiEvent ')
                $XmlWriter.WriteAttributeString('onmatch', 'exclude')
                $xmlWriter.WriteFullEndElement()
            }
            els
            {
                Write-Warning -Message 'WmiEvent was not enabled because it is not supported in this SchemaVersion.'
            }
        }

        # End Element of EventFiltering
        $xmlWriter.WriteFullEndElement()

        # Sysmon
        $xmlWriter.WriteEndElement()

        # finalize the document:
        #$xmlWriter.WriteEndDocument()
        $xmlWriter.Flush()
        $xmlWriter.Close()
        Write-Verbose -Message "Config file created as $($Config)"
        write-verbose -Message "Configuration is for Sysmon $($sysmonVerMap[$SchemaVersion])"
    }
    End
    {
    }
}

#  .ExternalHelp Posh-SysMon.psm1-Help.xml
function Get-SysmonHashingAlgorithm
{
    [CmdletBinding(DefaultParameterSetName = 'Path',
                   HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/Get-SysmonHashingAlgorithm.md')]
    Param
    (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   ParameterSetName='Path',
                   Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [string]$Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   ParameterSetName='LiteralPath',
                   Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        [string]$LiteralPath
    )

    Begin{}
    Process
    {
        # Check if the file is a valid XML file and if not raise and error.
        try
        {
            switch($psCmdlet.ParameterSetName)
            {
                'Path'        {[xml]$Config = Get-Content -Path $Path}
                'LiteralPath' {[xml]$Config = Get-Content -LiteralPath $LiteralPath}
            }
        }
        catch [System.Management.Automation.PSInvalidCastException]
        {
            Write-Error -Message 'Specified file does not appear to be a XML file.'
            return
        }

        # Validate the XML file is a valid Sysmon file.
        if ($Config.SelectSingleNode('//Sysmon') -eq $null)
        {
            Write-Error -Message 'XML file is not a valid Sysmon config file.'
            return
        }

        if ($Config.Sysmon.schemaversion -notin $SysMonSupportedVersions)
        {
            Write-Error -Message 'This version of Sysmon Rule file is not supported.'
            return
        }

        $ObjOptions = @{}

        if ($Config.Sysmon.SelectSingleNode('//HashAlgorithms'))
        {
            $ObjOptions['Hashing'] = $config.Sysmon.HashAlgorithms
        }
        else
        {
            $ObjOptions['Hashing'] = ''
        }

        #$ObjOptions['Comment'] = $Config.'#comment'
        $ConfigObj = [pscustomobject]$ObjOptions
        $ConfigObj.pstypenames.insert(0,'Sysmon.HashingAlgorithm')
        $ConfigObj

    }
    End{}
}


#  .ExternalHelp Posh-SysMon.psm1-Help.xml
function Get-SysmonRule
{
    [CmdletBinding(DefaultParameterSetName = 'Path',
                   HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/Get-SysmonRule.md')]
    Param
    (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   ParameterSetName='Path',
                   Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [string]$Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   ParameterSetName='LiteralPath',
                   Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        [string]$LiteralPath,

        # Event type to parse rules for.
        [Parameter(Mandatory=$false,
                   ValueFromPipelineByPropertyName=$true,
                   Position=1)]
        [ValidateSet('ALL', 'NetworkConnect', 'ProcessCreate', 'FileCreateTime',
                     'ProcessTerminate', 'ImageLoad', 'DriverLoad', 'ProcessAccess',
                     'RawAccessRead','ProcessAccess', 'FileCreateStreamHash',
                     'RegistryEvent', 'FileCreate', 'PipeEvent', 'WmiEvent')]
        [string[]]
        $EventType = @('ALL')
    )

    Begin{}
    Process
    {
        # Check if the file is a valid XML file and if not raise and error.
        try
        {
            switch($psCmdlet.ParameterSetName)
            {
                'Path'        {[xml]$Config = Get-Content -Path $Path}
                'LiteralPath' {[xml]$Config = Get-Content -LiteralPath $LiteralPath}
            }
        }
        catch [System.Management.Automation.PSInvalidCastException]
        {
            Write-Error -Message 'Specified file does not appear to be a XML file.'
            return
        }

        # Validate the XML file is a valid Sysmon file.
        if ($Config.SelectSingleNode('//Sysmon') -eq $null)
        {
            Write-Error -Message 'XML file is not a valid Sysmon config file.'
            return
        }

         if ($Config.Sysmon.schemaversion -notin $SysMonSupportedVersions)
        {
            Write-Error -Message 'This version of Sysmon Rule file is not supported.'
            return
        }

        # Collect all individual rules if they exist.
        $Rules = $Config.Sysmon.EventFiltering

        if ($EventType -contains 'ALL')
        {
            $TypesToParse = @('NetworkConnect', 'ProcessCreate', 'FileCreateTime',
                              'ProcessTerminate', 'ImageLoad', 'DriverLoad','CreateRemoteThread',
                              'ProcessAccess', 'RawAccessRead', 'FileCreateStreamHash',
                              'RegistryEvent', 'FileCreate', 'PipeEvent', 'WmiEvent')
        }
        else
        {
            $TypesToParse = $EventType
        }

        foreach($Type in $TypesToParse)
        {
            $EvtType = $MyInvocation.MyCommand.Module.PrivateData[$Type]
            $RuleData = $Rules.SelectNodes("//EventFiltering/$($EvtType)")
            if($RuleData -ne $null)
            {
                Write-Verbose -Message "$($EvtType) Rule Found."
                Get-RuleWithFilter($RuleData)
            }

        }
    }
    End{}
}


#  .ExternalHelp Posh-SysMon.psm1-Help.xml
function Set-SysmonHashingAlgorithm
{
    [CmdletBinding(DefaultParameterSetName = 'Path',
                   HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/Set-SysmonHashingAlgorithm.md')]
    Param
    (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   ParameterSetName='Path',
                   Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   ParameterSetName='LiteralPath',
                   Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Specify one or more hash algorithms used for image identification
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=1)]
        [ValidateSet('ALL', 'MD5', 'SHA1', 'SHA256', 'IMPHASH')]
        [string[]]
        $HashingAlgorithm
    )

    Begin{}
    Process
    {
        # Check if the file is a valid XML file and if not raise and error.
        try
        {
            switch($psCmdlet.ParameterSetName)
            {
                'Path'
                {
                    [xml]$Config = Get-Content -Path $Path
                    $FileLocation = (Resolve-Path -Path $Path).Path
                }

                'LiteralPath'
                {
                    [xml]$Config = Get-Content -LiteralPath $LiteralPath
                    $FileLocation = (Resolve-Path -LiteralPath $LiteralPath).Path
                }
            }
        }
        catch [System.Management.Automation.PSInvalidCastException]
        {
            Write-Error -Message 'Specified file does not appear to be a XML file.'
            return
        }

        # Validate the XML file is a valid Sysmon file.
        if ($Config.SelectSingleNode('//Sysmon') -eq $null)
        {
            Write-Error -Message 'XML file is not a valid Sysmon config file.'
            return
        }

         if ($Config.Sysmon.schemaversion -notin $SysMonSupportedVersions)
        {
            Write-Error -Message 'This version of Sysmon Rule file is not supported.'
            return
        }

        Write-Verbose -Message 'Updating Hashing option.'
        if ($HashingAlgorithm -contains 'ALL')
        {
            $Hash = '*'
        }
        else
        {
            $Hash = $HashingAlgorithm -join ','
        }

        # Check if Hashing Alorithm node exists.
        if($Config.SelectSingleNode('//Sysmon/HashAlgorithms') -ne $null)
        {
            $Config.Sysmon.HashAlgorithms = $Hash
        }
        else
        {
            $HashElement = $Config.CreateElement('HashAlgorithms')
            [void]$Config.Sysmon.Configuration.AppendChild($HashElement)
            $Config.Sysmon.Configuration.Hashing = $Hash
        }
        Write-Verbose -Message 'Hashing option has been updated.'


        Write-Verbose -Message "Option have been set on $($FileLocation)"
        $Config.Save($FileLocation)
    }
    End{}
}


#  .ExternalHelp Posh-SysMon.psm1-Help.xml
function Set-SysmonRule
{
    [CmdletBinding(DefaultParameterSetName = 'Path',
                   HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/Set-SysmonRule.md')]
    Param
    (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   ParameterSetName='Path',
                   Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   ParameterSetName='LiteralPath',
                   Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type to update.
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=1)]
        [ValidateSet('NetworkConnect', 'ProcessCreate', 'FileCreateTime',
                     'ProcessTerminate', 'ImageLoad', 'DriverLoad', 'CreateRemoteThread',
                     'ProcessAccess', 'RawAccessRead', 'FileCreateStreamHash',
                     'RegistryEvent', 'FileCreate', 'PipeEvent', 'WmiEvent')]
        [string[]]
        $EventType,

        # Action for event type rule and filters.
        [Parameter(Mandatory=$false,
                   ValueFromPipelineByPropertyName=$true,
                   Position=2)]
        [ValidateSet('Include', 'Exclude')]
        [String]
        $OnMatch = 'Exclude',

        # Action to take for Schema 3.0 files.
        [Parameter(Mandatory=$false,
                   ValueFromPipelineByPropertyName=$true)]
        [ValidateSet('Modify', 'Add')]
        [String]
        $Action = 'Modify'
    )

    Begin{}
    Process
    {
        # if no elemrnt create one either if it is schema 2.0 or 3.0.
        # If one is present we modify that one if Schema 2.0 and if Schema 3.0 and action modify.
        # If Schema 3.0 and action add we check if only is present and that it is not the same OnMatch
        # as being specified if it is we do nothing if not we add.


        # Check if the file is a valid XML file and if not raise and error.
        try
        {
            switch($psCmdlet.ParameterSetName)
            {
                'Path'
                {
                    [xml]$Config = Get-Content -Path $Path
                    $FileLocation = (Resolve-Path -Path $Path).Path
                }

                'LiteralPath'
                {
                    [xml]$Config = Get-Content -LiteralPath $LiteralPath
                    $FileLocation = (Resolve-Path -LiteralPath $LiteralPath).Path
                }
            }
        }
        catch [Management.Automation.PSInvalidCastException]
        {
            Write-Error -Message 'Specified file does not appear to be a XML file.'
            return
        }

        # Validate the XML file is a valid Sysmon file.
        if ($Config.SelectSingleNode('//Sysmon') -eq $null)
        {
            Write-Error -Message 'XML file is not a valid Sysmon config file.'
            return
        }

         if ($Config.Sysmon.schemaversion -notin $SysMonSupportedVersions)
        {
            Write-Error -Message 'This version of Sysmon Rule file is not supported.'
            return
        }

        $Rules = $config.SelectSingleNode('//Sysmon/EventFiltering')

        foreach($Type in $EventType)
        {
            $EvtType = $MyInvocation.MyCommand.Module.PrivateData[$Type]
            $RuleData = $Rules.SelectSingleNode("//EventFiltering/$($EvtType)")
            $elements = $Rules."$($EvtType)" | Select-Object -property onmatch -Unique

            if($RuleData -ne $null)
            {
                if ($Rules."$($EvtType)".count -eq $null)
                {
                    if (($Config.Sysmon.schemaversion -eq '2.0') -or ($Config.Sysmon.schemaversion -in @('3.0', '3.1', '3.2','3.3', '3.4') -and $Action -eq 'Modify'))
                    {
                        Write-Verbose -Message "Setting as default action for $($EvtType) the rule on match of $($OnMatch)."
                        $RuleData.SetAttribute('onmatch',($OnMatch.ToLower()))
                        Write-Verbose -Message 'Action has been set.'
                    }
                    elseif ($Config.Sysmon.schemaversion -in @('3.0', '3.1', '3.2','3.3', '3.4') -and $Action -eq 'Add')
                    {
                        if ($RuleData.onmatch -ne $OnMatch)
                        {
                            Write-Verbose -Message "Creating rule for event type with action of $($OnMatch)"
                            $TypeElement = $config.CreateElement($EvtType)
                            $TypeElement.SetAttribute('onmatch',($OnMatch.ToLower()))
                             $RuleData = $Rules.AppendChild($TypeElement)
                            Write-Verbose -Message 'Action has been set.'
                        }
                        else
                        {
                            Write-Verbose -Message 'A rule with the specified onmatch action already exists.'
                        }
                    }
                }
                elseif ($Config.Sysmon.schemaversion -in ('3.0', '3.1', '3.2','3.3', '3.4') -and $elements.count -eq 2)
                {
                    Write-Verbose -Message 'A rule with the specified onmatch action already exists.'
                }
                else
                {
                    Write-Error -Message 'This XML file does not conform to the schema.'
                    return
                }
            }
            else
            {
                Write-Verbose -Message "No rule for $($EvtType) was found."
                Write-Verbose -Message "Creating rule for event type with action of $($OnMatch)"
                $TypeElement = $config.CreateElement($EvtType)
                $TypeElement.SetAttribute('onmatch',($OnMatch.ToLower()))
                $RuleData = $Rules.AppendChild($TypeElement)
                Write-Verbose -Message 'Action has been set.'
            }

            Get-RuleWithFilter($RuleData)
        }
        $config.Save($FileLocation)
    }
    End{}
}


#  .ExternalHelp Posh-SysMon.psm1-Help.xml
function Remove-SysmonRule
{
    [CmdletBinding(DefaultParameterSetName = 'Path',
                   HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/Remove-SysmonRule.md')]
    Param
    (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   ParameterSetName='Path',
                   Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   ParameterSetName='LiteralPath',
                   Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type to remove. It is case sensitive.
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=1)]
        [ValidateSet('NetworkConnect', 'ProcessCreate', 'FileCreateTime',
                     'ProcessTerminate', 'ImageLoad', 'DriverLoad', 'CreateRemoteThread',
                     'ProcessAccess', 'RawAccessRead', 'FileCreateStreamHash',
                     'RegistryEvent', 'FileCreate', 'PipeEvent', 'WmiEvent')]
        [string[]]
        $EventType,

        # Action for event type rule and filters.
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=2)]
        [ValidateSet('Include', 'Exclude')]
        [String]
        $OnMatch = 'Exclude'
    )

    Begin{}
    Process
    {
        # Check if the file is a valid XML file and if not raise and error.
        try
        {
            switch($psCmdlet.ParameterSetName)
            {
                'Path'
                {
                    [xml]$Config = Get-Content -Path $Path
                    $FileLocation = (Resolve-Path -Path $Path).Path
                }

                'LiteralPath'
                {
                    [xml]$Config = Get-Content -LiteralPath $LiteralPath
                    $FileLocation = (Resolve-Path -LiteralPath $LiteralPath).Path
                }
            }
        }
        catch [Management.Automation.PSInvalidCastException]
        {
            Write-Error -Message 'Specified file does not appear to be a XML file.'
            return
        }

        # Validate the XML file is a valid Sysmon file.
        if ($Config.SelectSingleNode('//Sysmon') -eq $null)
        {
            Write-Error -Message 'XML file is not a valid Sysmon config file.'
            return
        }

         if ($Config.Sysmon.schemaversion -notin $SysMonSupportedVersions)
        {
            Write-Error -Message 'This version of Sysmon Rule file is not supported.'
            return
        }

        $Rules = $config.SelectSingleNode('//Sysmon/EventFiltering')
        foreach ($rule in $rules.ChildNodes)
        {
            if ($rule.name -in $EventType -and $rule.onmatch -eq $OnMatch)
            {
                [void]$rule.ParentNode.RemoveChild($rule)
                Write-Verbose -Message "Removed rule for $($EventType)."
            }
        }

        $config.Save($FileLocation)
    }
    End{}
}



================================================
FILE: Filters.ps1
================================================
#  .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonImageLoadFilter {
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonImageLoadFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch,

        # Condition for filtering against and event field.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
            'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
        [string]
        $Condition,

        # Event field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=3)]
        [ValidateSet('UtcTime', 'ProcessGuid', 'ProcessId', 'Image',
            'ImageLoaded', 'Hashes', 'Signed',
            'Signature')]
        [string]
        $EventField,

        # Value of Event Field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=4)]
        [string[]]
        $Value
    )

    Begin {}
    Process
    {
        $FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
        $cmdoptions = @{
            'EventType' =  'ImageLoad'
            'Condition' = $Condition
            'EventField' = $FieldString
            'Value' = $Value
            'OnMatch' = $OnMatch

        }
        switch($psCmdlet.ParameterSetName)
        {
            'Path'
            {
                $cmdOptions.Add('Path',$Path)
                New-RuleFilter @cmdOptions
            }

            'LiteralPath'
            {
                $cmdOptions.Add('LiteralPath',$LiteralPath)
                New-RuleFilter @cmdOptions
            }
        }

    }
    End { }
}


#  .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonDriverLoadFilter {
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonDriverLoadFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch,

        # Condition for filtering against and event field.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
            'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
        [string]
        $Condition,

        # Event field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=3)]
        [ValidateSet('UtcTime', 'ImageLoaded',
            'Hashes', 'Signed', 'Signature')]
        [string]
        $EventField,

        # Value of Event Field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=4)]
        [string[]]
        $Value
    )

    Begin {}
    Process {
        $FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
        $cmdoptions = @{
            'EventType' =  'DriverLoad'
            'Condition' = $Condition
            'EventField' = $FieldString
            'Value' = $Value
            'OnMatch' = $OnMatch

        }

        switch($psCmdlet.ParameterSetName) {
            'Path' {
                $cmdOptions.Add('Path',$Path)
                New-RuleFilter @cmdOptions
            }

            'LiteralPath' {
                $cmdOptions.Add('LiteralPath',$LiteralPath)

                New-RuleFilter @cmdOptions
            }
        }
    }
    End {}
}


#  .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonNetworkConnectFilter
{
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonNetworkConnectFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch,

        # Condition for filtering against and event field.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
            'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
        [string]
        $Condition,

        # Event field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=3)]
        [ValidateSet('UtcTime', 'ProcessGuid', 'ProcessId', 'Image',
            'User', 'Protocol', 'Initiated', 'SourceIsIpv6',
            'SourceIp', 'SourceHostname', 'SourcePort',
            'SourcePortName', 'DestinationIsIpv6',
            'DestinationIp', 'DestinationHostname',
            'DestinationPort', 'DestinationPortName')]
        [string]
        $EventField,

        # Value of Event Field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=4)]
        [string[]]
        $Value
    )

    Begin {}
    Process {
        $FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
        $cmdoptions = @{
            'EventType' =  'NetworkConnect'
            'Condition' = $Condition
            'EventField' = $FieldString
            'Value' = $Value
            'OnMatch' = $OnMatch

        }

        switch($psCmdlet.ParameterSetName) {
            'Path' {
                $cmdOptions.Add('Path',$Path)
                New-RuleFilter @cmdOptions
            }

            'LiteralPath' {
                $cmdOptions.Add('LiteralPath',$LiteralPath)
                New-RuleFilter @cmdOptions
            }
        }
    }
    End {}
}


#  .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonFileCreateFilter {
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonFileCreateFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch,

        # Condition for filtering against and event field.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
        'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
        [string]
        $Condition,

        # Event field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=3)]
        [ValidateSet('UtcTime', 'ProcessGuid', 'ProcessId', 'Image',
            'TargetFilename', 'CreationUtcTime',
            'PreviousCreationUtcTime')]
        [string]
        $EventField,

        # Value of Event Field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=4)]
        [string[]]
        $Value
    )

    Begin {}
    Process {
        $FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]

        switch($psCmdlet.ParameterSetName) {
            'Path' {
                New-RuleFilter -Path $Path -EventType FileCreateTime -Condition $Condition -EventField $FieldString -Value $Value -OnMatch $OnMatch
            }

            'LiteralPath' {
                New-RuleFilter -LiteralPath $LiteralPath -EventType FileCreateTime -Condition $Condition -EventField $FieldString -Value $Value -OnMatch $OnMatch
            }
        }

    }
    End {}
}


#  .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonProcessCreateFilter
{
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonProcessCreateFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch,

        # Condition for filtering against and event field.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
            'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
        [string]
        $Condition,

        # Event field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=3)]
        [ValidateSet('UtcTime', 'ProcessGuid', 'ProcessId', 'Image',
            'CommandLine', 'User', 'LogonGuid', 'LogonId',
            'TerminalSessionId', 'IntegrityLevel',
            'Hashes', 'ParentProcessGuid', 'ParentProcessId',
            'ParentImage', 'ParentCommandLine')]
        [string]
        $EventField,

        # Value of Event Field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=4)]
        [string[]]
        $Value
    )

    Begin {}
    Process {
        $FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
        $cmdoptions = @{
            'EventType' =  'ProcessCreate'
            'Condition' = $Condition
            'EventField' = $FieldString
            'Value' = $Value
            'OnMatch' = $OnMatch

        }
        switch($psCmdlet.ParameterSetName) {
            'Path' {
                $cmdOptions.Add('Path',$Path)
                New-RuleFilter @cmdOptions
            }

            'LiteralPath' {
                $cmdOptions.Add('LiteralPath',$LiteralPath)
                New-RuleFilter @cmdOptions
            }
        }
    }
    End { }
}


#  .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonProcessTerminateFilter
{
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonProcessTerminateFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch,

        # Condition for filtering against and event field.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
            'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
        [string]
        $Condition,

        # Event field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=3)]
        [ValidateSet('UtcTime', 'ProcessGuid', 'ProcessId')]
        [string]
        $EventField,

        # Value of Event Field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=4)]
        [string[]]
        $Value
    )

    Begin {}
    Process
    {
        $FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
        $cmdoptions = @{
            'EventType' =  'ProcessTerminate'
            'Condition' = $Condition
            'EventField' = $FieldString
            'Value' = $Value
            'OnMatch' = $OnMatch

        }
        switch($psCmdlet.ParameterSetName)
        {
            'Path'
            {
                $cmdOptions.Add('Path',$Path)
                New-RuleFilter @cmdOptions
            }

            'LiteralPath'
            {
                $cmdOptions.Add('LiteralPath',$LiteralPath)
                New-RuleFilter @cmdOptions
            }
        }
    }
    End {}
}

#  .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonCreateRemoteThreadFilter
{
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonCreateRemoteThreadFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch,

        # Condition for filtering against and event field.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
            'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
        [string]
        $Condition,

        # Event field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=3)]
        [ValidateSet('SourceImage', 'TargetImage')]
        [string]
        $EventField,

        # Value of Event Field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=4)]
        [string[]]
        $Value
    )

    Begin { }
    Process {
        $FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
        $cmdoptions = @{
            'EventType' =  'CreateRemoteThread'
            'Condition' = $Condition
            'EventField' = $FieldString
            'Value' = $Value
            'OnMatch' = $OnMatch

        }
        switch($psCmdlet.ParameterSetName) {
            'Path' {
                $cmdOptions.Add('Path',$Path)
                New-RuleFilter @cmdOptions
            }

            'LiteralPath' {
                $cmdOptions.Add('LiteralPath',$LiteralPath)
                New-RuleFilter @cmdOptions
            }
        }
    }
    End {}
}

<#
.SYNOPSIS
Create a new filter for the logging of when a running process opens another.
.DESCRIPTION
Create a new filter for the logging of when a running process opens another.
.EXAMPLE
C:\PS> New-SysmonProcessAccessFilter -Path .\testver31.xml -OnMatch include -Condition Contains -EventField TargetImage lsass.exe
Log any process trying to open lsass.exe.
#>
function New-SysmonProcessAccessFilter {
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonProcessAccessFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch,

        # Condition for filtering against and event field.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
            'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
            [string]
        $Condition,

        # Event field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=3)]
        [ValidateSet('UtcTime', 'SourceProcessGUID',
            'SourceProcessId', 'SourceThreadId', 'SourceImage',
            'TargetProcessGUID', 'TargetProcessId', 'TargetImage',
            'GrantedAccess','CallTrace')]
        [string]
        $EventField,

        # Value of Event Field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=4)]
        [string[]]
        $Value
    )

    Begin {}
    Process {
        $FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
        $cmdoptions = @{
            'EventType' =  'ProcessAccess'
            'Condition' = $Condition
            'EventField' = $FieldString
            'Value' = $Value
            'OnMatch' = $OnMatch

        }
        switch ($PSCmdlet.ParameterSetName) {
            'Path' {
                $cmdOptions.Add('Path',$Path)
                New-RuleFilter @cmdOptions
            }

            'LiteralPath' {
                $cmdOptions.Add('LiteralPath',$LiteralPath)
                New-RuleFilter @cmdOptions
            }
        }
    }
    End {}
}

<#
.SYNOPSIS
Create a new filter for the logging of file raw access read actions.
.DESCRIPTION
Create a new filter for the logging of file raw access read actions.
.EXAMPLE
C:\PS> New-SysmonRawAccessReadFilter -Path .\testver31.xml -OnMatch include -Condition Contains -EventField Image NTDS.dit
Log any raw access read of the file NTDS.dit.
#>
function New-SysmonRawAccessReadFilter {
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonRawAccessReadFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch,

        # Condition for filtering against and event field.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
            'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
        [string]
        $Condition,

        # Event field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=3)]
        [ValidateSet('UtcTime', 'ProcessGuid', 'ProcessId',
            'Image', 'Device')]
        [string]
        $EventField,

        # Value of Event Field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=4)]
        [string[]]
        $Value
    )

    Begin {}
    Process {
        $FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
        $cmdoptions = @{
            'EventType' =  'RawAccessRead'
            'Condition' = $Condition
            'EventField' = $FieldString
            'Value' = $Value
            'OnMatch' = $OnMatch

        }

        switch ($PSCmdlet.ParameterSetName) {
            'Path' {
                $cmdOptions.Add('Path',$Path)
                New-RuleFilter @cmdOptions
            }

            'LiteralPath' {
                $cmdOptions.Add('LiteralPath',$LiteralPath)
                New-RuleFilter @cmdOptions
            }
        }
    }
    End {}
}


<#
.SYNOPSIS
Create a new filter for the logging file creation.
.DESCRIPTION
Create a new filter for the logging file creation.
.EXAMPLE
#>
function New-SysmonFileCreateFilter {
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonFileCreateFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch,

        # Condition for filtering against and event field.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
            'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
        [string]
        $Condition,

        # Event field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=3)]
        [ValidateSet('TargetFilename', 'ProcessGuid', 'ProcessId',
            'Image')]
        [string]
        $EventField,

        # Value of Event Field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=4)]
        [string[]]
        $Value
    )

    Begin {}
    Process {
        $FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
        $cmdoptions = @{
            'EventType' =  'FileCreate'
            'Condition' = $Condition
            'EventField' = $FieldString
            'Value' = $Value
            'OnMatch' = $OnMatch
        }

        switch ($PSCmdlet.ParameterSetName) {
            'Path' {
                $cmdOptions.Add('Path',$Path)
                New-RuleFilter @cmdOptions
            }

            'LiteralPath' {
                $cmdOptions.Add('LiteralPath',$LiteralPath)
                New-RuleFilter @cmdOptions
            }
        }
    }
    End {}
}


<#
.SYNOPSIS
Create a new filter for the logging of the saving of data on a file stream.
.DESCRIPTION
Create a new filter for the logging of the saving of data on a file stream.
#>
function New-SysmonFileCreateStreamHashFilter {
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonFileCreateStreamHashFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch,

        # Condition for filtering against and event field.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
            'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
        [string]
        $Condition,

        # Event field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=3)]
        [ValidateSet('TargetFilename', 'ProcessGuid', 'ProcessId',
            'Image')]
        [string]
        $EventField,

        # Value of Event Field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=4)]
        [string[]]
        $Value
    )

    Begin {}
    Process {
        $FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
        $cmdoptions = @{
            'EventType' =  'FileCreateStreamHash'
            'Condition' = $Condition
            'EventField' = $FieldString
            'Value' = $Value
            'OnMatch' = $OnMatch
        }

        switch ($PSCmdlet.ParameterSetName) {
            'Path' {
                $cmdOptions.Add('Path',$Path)
                New-RuleFilter @cmdOptions
            }

            'LiteralPath' {
                $cmdOptions.Add('LiteralPath',$LiteralPath)
                New-RuleFilter @cmdOptions
            }
        }
    }
    End {}
}


<#
.SYNOPSIS
Create a new filter for the actions against the registry.
.DESCRIPTION
Create a new filter for actions against the registry. Supports filtering
by aby of the following event types:
* CreateKey
* DeleteKey
* RenameKey
* CreateValue
* DeleteValue
* RenameValue
* SetValue

Hives on Schema 3.2 in TargetObject are referenced as:
* \REGISTRY\MACHINE\HARDWARE
* \REGISTRY\USER\Security ID number
* \REGISTRY\MACHINE\SECURITY
* \REGISTRY\USER\.DEFAULT
* \REGISTRY\MACHINE\SYSTEM
* \REGISTRY\MACHINE\SOFTWARE
* \REGISTRY\MACHINE\SAM

Hives on Schema 3.3 and above in TargetObject are referenced as:
* HKLM
* HKCR
* HKEY_USER

.EXAMPLE
C:\PS> New-SysmonRegistryFilter -Path .\32config.xml -OnMatch include -Condition Contains -EventField TargetObject 'RunOnce'
Capture persistance attemp by creating a registry entry in the RunOnce keys.
#>
function New-SysmonRegistryFilter {
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonRegistryFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({ Test-Path -Path $_ })]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch,

        # Condition for filtering against and event field.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
            'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
        [string]
        $Condition,

        # Event field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=3)]
        [ValidateSet('TargetObject', 'ProcessGuid', 'ProcessId',
            'Image', 'EventType')]
        [string]
        $EventField,

        # Value of Event Field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=4)]
        [string[]]
        $Value
    )

    Begin {
        # Event types used to validate right type and string case
        $EventTypeMap = @{
            CreateKey = 'CreateKey'
            DeleteKey = 'DeleteKey'
            RenameKey = 'RenameKey'
            CreateValue = 'CreateValue'
            DeleteValue = 'DeleteValue'
            RenameValue = 'RenameValue'
            SetValue = 'SetValue'
        }

        $Etypes = $EventTypeMap.Keys
    }
    Process {
        $FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]

        if ($EventField -in 'EventType') {
            if ($Value -in $Etypes) {
                $Value = $EventTypeMap[$Value]
            } else {
                Write-Error -Message "Not a supported EventType. Supported Event types $($Etypes -join ', ')"
                return
            }
        }
        $cmdoptions = @{
            'EventType' =  'RegistryEvent'
            'Condition' = $Condition
            'EventField' = $FieldString
            'Value' = $Value
            'OnMatch' = $OnMatch

        }

        switch ($PSCmdlet.ParameterSetName) {
            'Path' {
                $cmdOptions.Add('Path',$Path)
                New-RuleFilter @cmdOptions
            }

            'LiteralPath' {
                $cmdOptions.Add('LiteralPath',$LiteralPath)
                New-RuleFilter @cmdOptions
            }
        }
    }
    End {}
}

<#
.SYNOPSIS
Create a new filter for when a Named Pipe is created or connected.
.DESCRIPTION
Create a new filter for when a Named Pipe is created or connected.
Useful for watching malware inter process communication.
#>
function New-SysmonPipeFilter {
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonPipeFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch,

        # Condition for filtering against and event field.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
            'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
        [string]
        $Condition,

        # Event field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=3)]
        [ValidateSet('Pipe', 'ProcessGuid', 'ProcessId',
            'Image')]
        [string]
        $EventField,

        # Value of Event Field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=4)]
        [string[]]
        $Value
    )

    Begin {}
    Process {
        $FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
        $cmdoptions = @{
            'EventType' =  'PipeEvent'
            'Condition' = $Condition
            'EventField' = $FieldString
            'Value' = $Value
            'OnMatch' = $OnMatch

        }
        switch ($PSCmdlet.ParameterSetName) {
            'Path' {
                $cmdOptions.Add('Path',$Path)
                New-RuleFilter @cmdOptions
            }

            'LiteralPath' {
                $cmdOptions.Add('LiteralPath',$LiteralPath)
                New-RuleFilter @cmdOptions
            }
        }
    }
    End {}
}

<#
.SYNOPSIS
Create a new filter for WMI Permamanent Event Classes.
.DESCRIPTION
Create a new filter for WMI permamanent event classes are created or connected.
Useful for monitoring for persistence actions.
#>
function New-SysmonWmiFilter {
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonWmiFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch,

        # Condition for filtering against and event field.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
            'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
        [string]
        $Condition,

        # Event field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=3)]
        [ValidateSet('Name', 'EventNamespace', 'Destination',
            'Type', 'Query', 'Operation', 'Consumer', 'Filter')]
        [string]
        $EventField,

        # Value of Event Field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=4)]
        [string[]]
        $Value
    )

    Begin {}
    Process {
        $FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
        $cmdoptions = @{
            'EventType' =  'WmiEvent'
            'Condition' = $Condition
            'EventField' = $FieldString
            'Value' = $Value
            'OnMatch' = $OnMatch

        }
        switch ($PSCmdlet.ParameterSetName) {
            'Path' {
                $cmdOptions.Add('Path',$Path)
                New-RuleFilter @cmdOptions
            }

            'LiteralPath' {
                $cmdOptions.Add('LiteralPath',$LiteralPath)
                New-RuleFilter @cmdOptions
            }
        }
    }
    End {}
}


#  .ExternalHelp Posh-SysMon.psm1-Help.xml
function Remove-SysmonRuleFilter {
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/Remove-SysmonRuleFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type to update.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [ValidateSet('NetworkConnect', 'ProcessCreate', 'FileCreateTime',
            'ProcessTerminate', 'ImageLoad', 'DriverLoad',
            'CreateRemoteThread', 'RawAccessRead', 'ProcessAccess',
            'FileCreateStreamHash', 'RegistryEvent', 'FileCreate',
            'PipeEvent', 'WmiEvent')]
        [string]
        $EventType,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch,

        # Condition for filtering against and event field.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=3)]
        [ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
            'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
        [string]
        $Condition,

        # Event field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=4)]
        [string]
        $EventField,

        # Value of Event Field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=5)]
        [string[]]
        $Value
    )

    Begin{}
    Process {
        $EvtType = $null
        # Check if the file is a valid XML file and if not raise and error.
        try {
            switch($psCmdlet.ParameterSetName) {
                'Path' {
                    [xml]$Config = Get-Content -Path $Path
                    $FileLocation = (Resolve-Path -Path $Path).Path
                }

                'LiteralPath' {
                    [xml]$Config = Get-Content -LiteralPath $LiteralPath
                    $FileLocation = (Resolve-Path -LiteralPath $LiteralPath).Path
                }
            }
        }
        catch [Management.Automation.PSInvalidCastException] {
            Write-Error -Message 'Specified file does not appear to be a XML file.'
            return
        }

        # Validate the XML file is a valid Sysmon file.
        if ($Config.SelectSingleNode('//Sysmon') -eq $null) {
            Write-Error -Message 'XML file is not a valid Sysmon config file.'
            return
        }

        $Rules = $Config.SelectSingleNode('//Sysmon/EventFiltering')

        # Select the proper condition string.
        switch ($Condition) {
            'Is' {$ConditionString = 'is'}
            'IsNot' {$ConditionString = 'is not'}
            'Contains' {$ConditionString = 'contains'}
            'Excludes' {$ConditionString = 'excludes'}
            'Image' {$ConditionString = 'image'}
            'BeginWith' {$ConditionString = 'begin with'}
            'EndWith' {$ConditionString = 'end with'}
            'LessThan' {$ConditionString = 'less than'}
            'MoreThan' {$ConditionString = 'more than'}
            Default {$ConditionString = 'is'}
        }

        # Check if the event type exists if not create it.
        if ($Rules -eq '') {
            Write-Error -Message 'Rule element does not exist. This appears to not be a valid config file'
            return
        } else {
            $EvtType = $MyInvocation.MyCommand.Module.PrivateData[$EventType]

            $EventRule = $Rules.SelectNodes("//EventFiltering/$($EvtType)")
        }

        if($EventRule -eq $null) {
            Write-Warning -Message "No rule for $($EvtType) was found."
            return
        }

        if($EventRule -eq $null) {
            Write-Error -Message "No rule for $($EvtType) was found."
            return
        } else {
            if ($EventRule.count -eq $null -or $EventRule.Count -eq 1) {
                if ($EventRule.onmatch -eq $OnMatch) {
                    $Filters = $EventRule.SelectNodes('*')
                    if ($Filters.count -gt 0) {
                        foreach($val in $Value) {
                            foreach($Filter in $Filters) {
                                if ($Filter.Name -eq $EventField) {
                                    if (($Filter.condition -eq $null) -and ($Condition -eq 'is') -and ($Filter.'#text' -eq $val)) {
                                        [void]$Filter.ParentNode.RemoveChild($Filter)
                                        Write-Verbose -Message "Filter for field $($EventField) with condition $($Condition) and value of $($val) removed."
                                    } elseif (($Filter.condition -eq $Condition) -and ($Filter.'#text' -eq $val)) {
                                        [void]$Filter.ParentNode.RemoveChild($Filter)
                                        Write-Verbose -Message "Filter for field $($EventField) with condition $($Condition) and value of $($val) removed."
                                    }
                                }
                            }
                        }
                        Get-RuleWithFilter($EventRule)
                    }
                }
            } else {
                Write-Verbose -Message 'Mutiple nodes.'
                foreach ($rule in $EventRule) {
                    if ($rule.onmatch -eq $OnMatch) {
                        $Filters = $rule.SelectNodes('*')
                        if ($Filters.count -gt 0) {
                            foreach($val in $Value) {
                                foreach($Filter in $Filters) {
                                    if ($Filter.Name -eq $EventField) {
                                        if (($Filter.condition -eq $null) -and ($Condition -eq 'is') -and ($Filter.'#text' -eq $val)) {
                                            [void]$Filter.ParentNode.RemoveChild($Filter)
                                            Write-Verbose -Message "Filter for field $($EventField) with condition $($Condition) and value of $($val) removed."
                                        } elseif (($Filter.condition -eq $Condition) -and ($Filter.'#text' -eq $val)) {
                                            [void]$Filter.ParentNode.RemoveChild($Filter)
                                            Write-Verbose -Message "Filter for field $($EventField) with condition $($Condition) and value of $($val) removed."
                                        }
                                    }
                                }
                            }
                            Get-RuleWithFilter($rule)
                        }
                    }
                }
            }
        }
        $config.Save($FileLocation)
    }
    End{}
}

<#
.SYNOPSIS
Get the configured filters for a specified Event Type Rule in a Sysmon configuration file.
.DESCRIPTION
Get the configured filters for a specified Event Type Rule in a Sysmon configuration file.
.EXAMPLE
C:\PS>  Get-SysmonRuleFilter -Path C:\sysmon.xml -EventType ProcessCreate
Get the filter under the ProcessCreate Rule.
#>
function Get-SysmonRuleFilter {
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/Get-SysmonRuleFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type rule to get filter for.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=1)]
        [ValidateSet('NetworkConnect', 'ProcessCreate', 'FileCreateTime',
            'ProcessTerminate', 'ImageLoad', 'DriverLoad',
            'CreateRemoteThread','RawAccessRead', 'ProcessAccess',
            'FileCreateStreamHash', 'RegistryEvent', 'FileCreate',
            'PipeEvent', 'WmiEvent')]
        [string]
        $EventType,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch
    )

    Begin{}
    Process {
        $EvtType = $null
        # Check if the file is a valid XML file and if not raise and error.
        try {
            switch($psCmdlet.ParameterSetName){
                'Path'{
                    [xml]$Config = Get-Content -Path $Path
                    $FileLocation = (Resolve-Path -Path $Path).Path
                }
                'LiteralPath' {
                    [xml]$Config = Get-Content -LiteralPath $LiteralPath
                    $FileLocation = (Resolve-Path -LiteralPath $LiteralPath).Path
                }
            }
        }
        catch [System.Management.Automation.PSInvalidCastException] {
            Write-Error -Message 'Specified file does not appear to be a XML file.'
            return
        }

        # Validate the XML file is a valid Sysmon file.
        if ($Config.SelectSingleNode('//Sysmon') -eq $null){
            Write-Error -Message 'XML file is not a valid Sysmon config file.'
            return
        }

        $Rules = $Config.SelectSingleNode('//Sysmon/EventFiltering')

        if ($Rules -eq '') {
            Write-Error -Message 'Rule element does not exist. This appears to not be a valid config file'
            return
        } else {
            $EvtType = $MyInvocation.MyCommand.Module.PrivateData[$EventType]

            $EventRule = $Rules.SelectNodes("//EventFiltering/$($EvtType)")
        }

        if($EventRule -eq $null) {
            Write-Error -Message "No rule for $($EvtType) was found."
            return
        } else {
            if ($EventRule.count -eq $null -or $EventRule.Count -eq 1) {
                Write-Verbose -Message 'Single Node'
                if ($EventRule.onmatch -eq $OnMatch) {
                    $Filters = $EventRule.SelectNodes('*')
                    if ($Filters.ChildNodes.Count -gt 0) {
                        foreach($Filter in $Filters) {
                            $FilterObjProps = @{}
                            $FilterObjProps['EventField'] = $Filter.Name
                            $FilterObjProps['Condition'] = &{if($Filter.condition -eq $null){'is'}else{$Filter.condition}}
                            $FilterObjProps['Value'] =  $Filter.'#text'
                            $FilterObjProps['EventType'] =  $EvtType
                            $FilterObjProps['OnMatch'] =  $OnMatch
                            $FilterObj = [pscustomobject]$FilterObjProps
                            $FilterObj.pstypenames.insert(0,'Sysmon.Rule.Filter')
                            $FilterObj
                        }

                    }
                }
            }
            else
            {
                Write-Verbose -Message 'Mutiple nodes.'
                foreach ($rule in $EventRule)
                {
                    if ($rule.onmatch -eq $OnMatch)
                    {
                        $Filters = $rule.SelectNodes('*')
                        if ($Filters.ChildNodes.Count -gt 0)
                        {
                            foreach($Filter in $Filters)
                            {
                                $FilterObjProps = @{}
                                $FilterObjProps['EventField'] = $Filter.Name
                                $FilterObjProps['Condition'] = &{if($Filter.condition -eq $null){'is'}else{$Filter.condition}}
                                $FilterObjProps['Value'] =  $Filter.'#text'
                                $FilterObjProps['EventType'] =  $EvtType
                                $FilterObjProps['OnMatch'] =  $OnMatch
                                $FilterObj = [pscustomobject]$FilterObjProps
                                $FilterObj.pstypenames.insert(0,'Sysmon.Rule.Filter')
                                $FilterObj
                            }

                        }
                    }
                }
            }
        }
    }
    End{}
}

<#
.Synopsis
Searches for specified SysMon Events and retunrs the Event Data as a custom object.
.DESCRIPTION
Searches for specified SysMon Events and retunrs the Event Data as a custom object.
.EXAMPLE
Get-SysMonEventData -EventId 1 -MaxEvents 10 -EndTime (Get-Date) -StartTime (Get-Date).AddDays(-1)

All process creation events in the last 24hr
.EXAMPLE
Get-SysMonEventData -EventId 3 -MaxEvents 20 -Path .\export.evtx

last 20 network connection events from a exported SysMon log.
#>
function Get-SysmonEventData {
    [CmdletBinding(DefaultParameterSetName='ID',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/Get-SysmonEventData.md')]
    Param (
        # Sysmon Event ID of records to show
        [Parameter(Mandatory=$true,
            ParameterSetName='ID',
            ValueFromPipelineByPropertyName=$true,
            Position=0)]
        [ValidateSet(1,2,3,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,255)]
        [Int32[]]
        $EventId,

        # EventType that a Rule can be written against.
        [Parameter(Mandatory=$false,
            ParameterSetName='Type',
            ValueFromPipelineByPropertyName=$true,
            Position=0)]
        [string[]]
        [ValidateSet('NetworkConnect', 'ProcessCreate', 'FileCreateTime',
            'ProcessTerminate', 'ImageLoad', 'DriverLoad',
            'CreateRemoteThread', 'RawAccessRead', 'ProcessAccess', 'Error',
            'FileCreateStreamHash', 'RegistryValueSet', 'RegistryRename',
            'RegistryAddOrDelete', 'FileCreate','ConfigChange','PipeCreated',
            'PipeConnected', 'WmiFilter', 'WmiConsumer', 'WmiBinding')]
        $EventType,

        # Specifies the maximum number of events that Get-WinEvent returns. Enter an integer. The default is to return all the events in the logs or files.
        [Parameter(Mandatory=$false,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [int]
        $MaxEvents,

        # Specifies a path to one or more exported SysMon events in evtx format.
        [Parameter(Mandatory=$false,
            ValueFromPipeline=$true,
            ValueFromPipelineByPropertyName=$true,
            HelpMessage='Path to one or more locations.')]
        [Alias('PSPath')]
        [ValidateNotNullOrEmpty()]
        [string[]]
        $Path,

        # Start Date to get all event going forward.
        [Parameter(Mandatory=$false)]
        [datetime]
        $StartTime,

        # End data for searching events.
        [Parameter(Mandatory=$false)]
        [datetime]
        $EndTime
    )

    Begin
    {
        $EventTypeMap = @{
            ProcessCreate = 1
            FileCreateTime = 2
            NetworkConnect = 3
            ProcessTerminate = 5
            DriverLoad = 6
            ImageLoad = 7
            CreateRemoteThread = 8
            RawAccessRead = 9
            ProcessAccess = 10
            FileCreate = 11
            RegistryAddOrDelete = 12
            RegistryValueSet = 13
            RegistryRename = 14
            FileCreateStreamHash = 15
            ConfigChange = 16
            PipeCreated = 17
            PipeConnected = 18
            WmiFilter = 19
            WmiConsumer = 20
            WmiBinding = 21
            Error = 255
        }

        $EventIdtoType = @{
            '1' = 'ProcessCreate'
            '2' = 'FileCreateTime'
            '3' = 'NetworkConnect'
            '5' = 'ProcessTerminate'
            '6' = 'DriverLoad'
            '7' = 'ImageLoad'
            '8' = 'CreateRemoteThread'
            '9' = 'RawAccessRead'
            '10' = 'ProcessAccess'
            '11' = 'FileCreate'
            '12' = 'RegistryAddOrDelete'
            '13' = 'RegistryValueSet'
            '14' = 'RegistryRename'
            '15' = 'FileCreateStreamHash'
            '16' = 'ConfigChange'
            '17' = 'PipeCreated'
            '18' = 'PipeConnected'
            '19' = 'WmiFilter'
            '20' = 'WmiConsumer'
            '21' = 'WmiBinding'
            '255' = 'Error'

        }
    }
    Process
    {
        # Hash for filtering
        $HashFilter = @{LogName='Microsoft-Windows-Sysmon/Operational'}

        # Hash for command paramteters
        $ParamHash = @{}

        if ($MaxEvents -gt 0)
        {
            $ParamHash.Add('MaxEvents', $MaxEvents)
        }

        if ($Path -gt 0)
        {
            $ParamHash.Add('Path', $Path)
        }

        switch ($PSCmdlet.ParameterSetName) {
            'ID' { $HashFilter.Add('Id', $EventId) }
            'Type' {
                $EventIds = @()
                foreach ($etype in $EventType)
                {
                    $EventIds += $EventTypeMap[$etype]
                }
                $HashFilter.Add('Id', $EventIds)
            }
        }

        if ($StartTime)
        {
            $HashFilter.Add('StartTime', $StartTime)
        }

        if ($EndTime)
        {
            $HashFilter.Add('EndTime', $EndTime)
        }

        $ParamHash.Add('FilterHashTable',$HashFilter)
        Get-WinEvent @ParamHash | ForEach-Object {
            [xml]$evtxml = $_.toxml()
            $ProcInfo = [ordered]@{}
            $ProcInfo['EventId'] = $evtxml.Event.System.EventID
            $ProcInfo['EventType'] = $EventIdtoType[$evtxml.Event.System.EventID]
            $ProcInfo['Computer'] = $evtxml.Event.System.Computer
            $evtxml.Event.EventData.Data | ForEach-Object {
                $ProcInfo[$_.name] = $_.'#text'
            }
            New-Object psobject -Property $ProcInfo
        }
    }
    End {}
}


================================================
FILE: Format/Sysmon.ConfigOption.ps1xml
================================================
<?xml version="1.0" encoding="utf-16"?>
<Configuration>
<ViewDefinitions>
<View>
    <Name>Sysmon.ConfigOption</Name>
    <ViewSelectedBy>
        <TypeName>Sysmon.ConfigOption</TypeName>
    </ViewSelectedBy>
    <ListControl>
        <ListEntries>
            <ListEntry>
                <ListItems>
                    <ListItem> 
                        <Label>Hashing</Label>
                        <PropertyName>Hashing</PropertyName>
                    </ListItem>
                    <ListItem>
                        <Label>Network</Label>
                        <PropertyName>Network</PropertyName>
                    </ListItem>
                    <ListItem>
                        <Label>ImageLoading</Label>
                        <PropertyName>ImageLoading</PropertyName>
                    </ListItem>
                    <ListItem>
                        <Label>Comment</Label>
                        <PropertyName>Comment</PropertyName>
                    </ListItem>
                    </ListItems>
            </ListEntry>
        </ListEntries>
    </ListControl>
</View>
</ViewDefinitions>
</Configuration>

================================================
FILE: Format/Sysmon.Rule.Filter.ps1xml
================================================
<?xml version="1.0" encoding="utf-16"?>
<Configuration>
<ViewDefinitions>
<View>
    <Name>Sysmon.Rule.Filter</Name>
    <ViewSelectedBy>
        <TypeName>Sysmon.Rule.Filter</TypeName>
    </ViewSelectedBy>
    <TableControl>
        <TableHeaders>
          <TableColumnHeader>
            <Width>12</Width>
          </TableColumnHeader>
          <TableColumnHeader>
            <Width>12</Width>
          </TableColumnHeader>
          <TableColumnHeader>
            <Width>50</Width>
          </TableColumnHeader>
        </TableHeaders>
        <TableRowEntries>
          <TableRowEntry>
            <TableColumnItems>
              <TableColumnItem>
               <PropertyName>EventField</PropertyName>
              </TableColumnItem>
              <TableColumnItem>
               <PropertyName>Condition</PropertyName>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>Value</PropertyName>
              </TableColumnItem>
            </TableColumnItems>
          </TableRowEntry>
        </TableRowEntries>
      </TableControl>
</View>
</ViewDefinitions>
</Configuration>

================================================
FILE: Format/Sysmon.Rule.ps1xml
================================================
<?xml version="1.0" encoding="utf-16"?>
<Configuration>
<ViewDefinitions>
<View>
    <Name>Sysmon.Rule</Name>
    <ViewSelectedBy>
        <TypeName>Sysmon.Rule</TypeName>
    </ViewSelectedBy>
    <ListControl>
        <ListEntries>
            <ListEntry>
                <ListItems>
                    <ListItem> 
                        <Label>EventType</Label>
                        <PropertyName>EventType</PropertyName>
                    </ListItem>
                    <ListItem>
                        <Label>Scope</Label>
                        <PropertyName>Scope</PropertyName>
                    </ListItem>
                    <ListItem>
                        <Label>DefaultAction</Label>
                        <PropertyName>DefaultAction</PropertyName>
                    </ListItem>
                    <ListItem>
                        <Label>Filters</Label>
                        <PropertyName>Filters</PropertyName>
                    </ListItem>
                    </ListItems>
            </ListEntry>
        </ListEntries>
    </ListControl>
</View>
</ViewDefinitions>
</Configuration>

================================================
FILE: Functions/ConvertFrom-SysmonBinaryConfiguration.ps1
================================================
<#
.SYNOPSIS

Parses a binary Sysmon configuration.

.DESCRIPTION

ConvertFrom-SysmonBinaryConfiguration parses a binary Sysmon configuration. The configuration is typically stored in the registry at the following path: HKLM\SYSTEM\CurrentControlSet\Services\SysmonDrv\Parameters\Rules

ConvertFrom-SysmonBinaryConfiguration currently only supports the following schema versions: 3.30, 3.40 and 4.0

Author: Matthew Graeber (@mattifestation)
License: BSD 3-Clause

.PARAMETER RuleBytes

Specifies the raw bytes of a Sysmon configuration from the registry.

.EXAMPLE

[Byte[]] $RuleBytes = Get-ItemPropertyValue -Path HKLM:\SYSTEM\CurrentControlSet\Services\SysmonDrv\Parameters -Name Rules
ConvertFrom-SysmonBinaryConfiguration -RuleBytes $RuleBytes

.OUTPUTS

Sysmon.EventCollection

Output a fully-parsed rule object including the hash of the rules blob.

.NOTES

ConvertFrom-SysmonBinaryConfiguration is designed to serve as a helper function for Get-SysmonConfiguration.
#>

function ConvertFrom-SysmonBinaryConfiguration {
    [OutputType('Sysmon.EventCollection')]
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $True)]
        [Byte[]]
        [ValidateNotNullOrEmpty()]
        $RuleBytes
    )

    #region Define byte to string mappings. This may change across verions.
    $SupportedSchemaVersions = @(
        [Version] '3.30.0.0',
        [Version] '3.40.0.0',
        [Version] '4.00.0.0'
    )

    $EventConditionMapping = @{
        0 = 'Is'
        1 = 'IsNot'
        2 = 'Contains'
        3 = 'Excludes'
        4 = 'BeginWith'
        5 = 'EndWith'
        6 = 'LessThan'
        7 = 'MoreThan'
        8 = 'Image'
    }

    # The following value to string mappings were all pulled from
    # IDA and will require manual validation with with each new
    # Sysmon and schema version. Here's hoping they don't change often!
    $ProcessCreateMapping = @{
        0 = 'UtcTime'
        1 = 'ProcessGuid'
        2 = 'ProcessId'
        3 = 'Image'
        4 = 'CommandLine'
        5 = 'CurrentDirectory'
        6 = 'User'
        7 = 'LogonGuid'
        8 = 'LogonId'
        9 = 'TerminalSessionId'
        10 = 'IntegrityLevel'
        11 = 'Hashes'
        12 = 'ParentProcessGuid'
        13 = 'ParentProcessId'
        14 = 'ParentImage'
        15 = 'ParentCommandLine'
    }

    $ProcessCreateMapping_4_00 = @{
        0 = 'UtcTime'
        1 = 'ProcessGuid'
        2 = 'ProcessId'
        3 = 'Image'
        4 = 'FileVersion'
        5 = 'Description'
        6 = 'Product'
        7 = 'Company'
        8 = 'CommandLine'
        9 = 'CurrentDirectory'
        10 = 'User'
        11 = 'LogonGuid'
        12 = 'LogonId'
        13 = 'TerminalSessionId'
        14 = 'IntegrityLevel'
        15 = 'Hashes'
        16 = 'ParentProcessGuid'
        17 = 'ParentProcessId'
        18 = 'ParentImage'
        19 = 'ParentCommandLine'
    }

    $FileCreateTimeMapping = @{
        0 = 'UtcTime'
        1 = 'ProcessGuid'
        2 = 'ProcessId'
        3 = 'Image'
        4 = 'TargetFilename'
        5 = 'CreationUtcTime'
        6 = 'PreviousCreationUtcTime'
    }

    $NetworkConnectMapping = @{
        0 = 'UtcTime'
        1 = 'ProcessGuid'
        2 = 'ProcessId'
        3 = 'Image'
        4 = 'User'
        5 = 'Protocol'
        6 = 'Initiated'
        7 = 'SourceIsIpv6'
        8 = 'SourceIp'
        9 = 'SourceHostname'
        10 = 'SourcePort'
        11 = 'SourcePortName'
        12 = 'DestinationIsIpv6'
        13 = 'DestinationIp'
        14 = 'DestinationHostname'
        15 = 'DestinationPort'
        16 = 'DestinationPortName'
    }

    $SysmonServiceStateChangeMapping = @{
        0 = 'UtcTime'
        1 = 'State'
        2 = 'Version'
        3 = 'SchemaVersion'
    }

    $ProcessTerminateMapping = @{
        0 = 'UtcTime'
        1 = 'ProcessGuid'
        2 = 'ProcessId'
        3 = 'Image'
    }

    $DriverLoadMapping = @{
        0 = 'UtcTime'
        1 = 'ImageLoaded'
        2 = 'Hashes'
        3 = 'Signed'
        4 = 'Signature'
        5 = 'SignatureStatus'
    }

    $ImageLoadMapping = @{
        0 = 'UtcTime'
        1 = 'ProcessGuid'
        2 = 'ProcessId'
        3 = 'Image'
        4 = 'ImageLoaded'
        5 = 'Hashes'
        6 = 'Signed'
        7 = 'Signature'
        8 = 'SignatureStatus'
    }

    $ImageLoadMapping_4_00 = @{
        0 = 'UtcTime'
        1 = 'ProcessGuid'
        2 = 'ProcessId'
        3 = 'Image'
        4 = 'ImageLoaded'
        5 = 'FileVersion'
        6 = 'Description'
        7 = 'Product'
        8 = 'Company'
        9 = 'Hashes'
        10 = 'Signed'
        11 = 'Signature'
        12 = 'SignatureStatus'
    }

    $CreateRemoteThreadMapping = @{
        0 = 'UtcTime'
        1 = 'SourceProcessGuid'
        2 = 'SourceProcessId'
        3 = 'SourceImage'
        4 = 'TargetProcessGuid'
        5 = 'TargetProcessId'
        6 = 'TargetImage'
        7 = 'NewThreadId'
        8 = 'StartAddress'
        9 = 'StartModule'
        10 = 'StartFunction'
    }

    $RawAccessReadMapping = @{
        0 = 'UtcTime'
        1 = 'ProcessGuid'
        2 = 'ProcessId'
        3 = 'Image'
        4 = 'Device'
    }

    $ProcessAccessMapping = @{
        0 = 'UtcTime'
        1 = 'SourceProcessGUID'
        2 = 'SourceProcessId'
        3 = 'SourceThreadId'
        4 = 'SourceImage'
        5 = 'TargetProcessGUID'
        6 = 'TargetProcessId'
        7 = 'TargetImage'
        8 = 'GrantedAccess'
        9 = 'CallTrace'
    }

    $FileCreateMapping = @{
        0 = 'UtcTime'
        1 = 'ProcessGuid'
        2 = 'ProcessId'
        3 = 'Image'
        4 = 'TargetFilename'
        5 = 'CreationUtcTime'
    }

    $RegistryEventCreateKeyMapping = @{
        0 = 'EventType'
        1 = 'UtcTime'
        2 = 'ProcessGuid'
        3 = 'ProcessId'
        4 = 'Image'
        5 = 'TargetObject'
    }

    $RegistryEventSetValueMapping = @{
        0 = 'EventType'
        1 = 'UtcTime'
        2 = 'ProcessGuid'
        3 = 'ProcessId'
        4 = 'Image'
        5 = 'TargetObject'
        6 = 'Details'
    }

    $RegistryEventDeleteKeyMapping = @{
        0 = 'EventType'
        1 = 'UtcTime'
        2 = 'ProcessGuid'
        3 = 'ProcessId'
        4 = 'Image'
        5 = 'TargetObject'
        6 = 'NewName'
    }

    $FileCreateStreamHashMapping = @{
        0 = 'UtcTime'
        1 = 'ProcessGuid'
        2 = 'ProcessId'
        3 = 'Image'
        4 = 'TargetFilename'
        5 = 'CreationUtcTime'
        6 = 'Hash'
    }

    $SysmonConfigurationChangeMapping = @{
        0 = 'UtcTime'
        1 = 'Configuration'
        2 = 'ConfigurationFileHash'
    }

    $PipeEventCreatedMapping = @{
        0 = 'UtcTime'
        1 = 'ProcessGuid'
        2 = 'ProcessId'
        3 = 'PipeName'
        4 = 'Image'
    }

    $PipeEventConnectedMapping = @{
        0 = 'UtcTime'
        1 = 'ProcessGuid'
        2 = 'ProcessId'
        3 = 'PipeName'
        4 = 'Image'
    }

    $WmiEventFilterMapping = @{
        0 = 'EventType'
        1 = 'UtcTime'
        2 = 'Operation'
        3 = 'User'
        4 = 'EventNamespace'
        5 = 'Name'
        6 = 'Query'
    }

    $WmiEventConsumerMapping = @{
        0 = 'EventType'
        1 = 'UtcTime'
        2 = 'Operation'
        3 = 'User'
        4 = 'Name'
        5 = 'Type'
        6 = 'Destination'
    }

    $WmiEventConsumerToFilterMapping = @{
        0 = 'EventType'
        1 = 'UtcTime'
        2 = 'Operation'
        3 = 'User'
        4 = 'Consumer'
        5 = 'Filter'
    }

    $EventTypeMapping = @{
        1  = @('ProcessCreate', $ProcessCreateMapping)
        2  = @('FileCreateTime', $FileCreateTimeMapping)
        3  = @('NetworkConnect', $NetworkConnectMapping)
        # SysmonServiceStateChange is not actually present in the schema. It is here for the sake of completeness.
        4  = @('SysmonServiceStateChange', $SysmonServiceStateChangeMapping)
        5  = @('ProcessTerminate', $ProcessTerminateMapping)
        6  = @('DriverLoad', $DriverLoadMapping)
        7  = @('ImageLoad', $ImageLoadMapping)
        8  = @('CreateRemoteThread', $CreateRemoteThreadMapping)
        9  = @('RawAccessRead', $RawAccessReadMapping)
        10 = @('ProcessAccess', $ProcessAccessMapping)
        11 = @('FileCreate', $FileCreateMapping)
        12 = @('RegistryEventCreateKey', $RegistryEventCreateKeyMapping)
        13 = @('RegistryEventSetValue', $RegistryEventSetValueMapping)
        14 = @('RegistryEventDeleteKey', $RegistryEventDeleteKeyMapping)
        15 = @('FileCreateStreamHash', $FileCreateStreamHashMapping)
        # SysmonConfigurationChange is not actually present in the schema. It is here for the sake of completeness.
        16 = @('SysmonConfigurationChange', $SysmonConfigurationChangeMapping)
        17 = @('PipeEventCreated', $PipeEventCreatedMapping)
        18 = @('PipeEventConnected', $PipeEventConnectedMapping)
        19 = @('WmiEventFilter', $WmiEventFilterMapping)
        20 = @('WmiEventConsumer', $WmiEventConsumerMapping)
        21 = @('WmiEventConsumerToFilter', $WmiEventConsumerToFilterMapping)
    }
    #endregion

    $RuleMemoryStream = New-Object -TypeName System.IO.MemoryStream -ArgumentList @(,$RuleBytes)

    $RuleReader = New-Object -TypeName System.IO.BinaryReader -ArgumentList $RuleMemoryStream

    # I'm noting here for the record that parsing could be slightly more robust to account for malformed
    # rule blobs. I'm writing this in my spare time so I likely won't put too much work into increased
    # parsing robustness.

    if ($RuleBytes.Count -lt 16) {
        $RuleReader.Dispose()
        $RuleMemoryStream.Dispose()
        throw 'Insufficient length to contain a Sysmon rule header.'
    }

    # This value should be either 0 or 1. 1 should be expected for a current Sysmon config.
    # A value of 1 indicates that offset 8 will contain the file offset to the first rule grouping.
    # A value of 0 should indicate that offset 8 will be the start of the first rule grouping.
    # Currently, I am just going to check that the value is 1 and throw an exception if it's not.
    $HeaderValue0 = $RuleReader.ReadUInt16()

    if ($HeaderValue0 -ne 1) {
        $RuleReader.Dispose()
        $RuleMemoryStream.Dispose()
        throw "Incorrect header value at offset 0x00. Expected: 1. Actual: $HeaderValue0"
    }

    # This value is expected to be 1. Any other value will indicate the presence of a "registry rule version"
    # that is incompatible with the current Sysmon schema version. A value other than 1 likely indicates the
    # presence of an old version of Sysmon. Any value besides 1 will not be supported in this script.
    $HeaderValue1 = $RuleReader.ReadUInt16()

    if ($HeaderValue1 -ne 1) {
        $RuleReader.Dispose()
        $RuleMemoryStream.Dispose()
        throw "Incorrect header value at offset 0x02. Expected: 1. Actual: $HeaderValue1"
    }

    $RuleGroupCount = $RuleReader.ReadUInt32()
    $RuleGroupBeginOffset = $RuleReader.ReadUInt32()

    $SchemaVersionMinor = $RuleReader.ReadUInt16()
    $SchemaVersionMajor = $RuleReader.ReadUInt16()

    $SchemaVersion = New-Object -TypeName System.Version -ArgumentList $SchemaVersionMajor, $SchemaVersionMinor, 0, 0

    Write-Verbose "Obtained the following schema version: $($SchemaVersion.ToString(2))"

    if (-not ($SupportedSchemaVersions -contains $SchemaVersion)) {
        $RuleReader.Dispose()
        $RuleMemoryStream.Dispose()
        throw "Unsupported schema version: $($SchemaVersion.ToString(2)). Schema version must be at least $($MinimumSupportedSchemaVersion.ToString(2))"
    }

    #region Perform offset updates depending upon the schema version here
    # This logic should be the first candidate for refactoring should the schema change drastically in the future.
    switch ($SchemaVersion.ToString(2)) {
        '4.0' {
            Write-Verbose 'Using schema version 4.00 updated offsets.'
            # ProcessCreate and ImageLoad values changed
            $EventTypeMapping[1][1] = $ProcessCreateMapping_4_00
            $EventTypeMapping[7][1] = $ImageLoadMapping_4_00
        }
    }
    #endregion

    $null = $RuleReader.BaseStream.Seek($RuleGroupBeginOffset, 'Begin')

    $EventCollection = for ($i = 0; $i -lt $RuleGroupCount; $i++) {
        $EventTypeValue = $RuleReader.ReadInt32()
        $EventType = $EventTypeMapping[$EventTypeValue][0]
        $EventTypeRuleTypes = $EventTypeMapping[$EventTypeValue][1]
        $OnMatchValue = $RuleReader.ReadInt32()

        $OnMatch = $null

        switch ($OnMatchValue) {
            0 { $OnMatch = 'Exclude' }
            1 { $OnMatch = 'Include' }
            default { $OnMatch = '?' }
        }

        $NextEventTypeOffset = $RuleReader.ReadInt32()
        $RuleCount = $RuleReader.ReadInt32()
        [PSObject[]] $Rules = New-Object -TypeName PSObject[]($RuleCount)

        # Parse individual rules here
        for ($j = 0; $j -lt $RuleCount; $j++) {
            $RuleType = $EventTypeRuleTypes[$RuleReader.ReadInt32()]
            $Filter = $EventConditionMapping[$RuleReader.ReadInt32()]
            $NextRuleOffset = $RuleReader.ReadInt32()
            $RuleTextLength = $RuleReader.ReadInt32()
            $RuleTextBytes = $RuleReader.ReadBytes($RuleTextLength)
            $RuleText = [Text.Encoding]::Unicode.GetString($RuleTextBytes).TrimEnd("`0")

            $Rules[$j] = [PSCustomObject] @{
                PSTypeName = 'Sysmon.Rule'
                RuleType = $RuleType
                Filter = $Filter
                RuleText = $RuleText
            }

            $null = $RuleReader.BaseStream.Seek($NextRuleOffset, 'Begin')
        }

        [PSCustomObject] @{
            PSTypeName = 'Sysmon.EventGroup'
            EventType = $EventType
            OnMatch = $OnMatch
            Rules = $Rules
        }

        $null = $RuleReader.BaseStream.Seek($NextEventTypeOffset, 'Begin')
    }

    $RuleReader.Dispose()
    $RuleMemoryStream.Dispose()

    # Calculate the hash of the binary rule blob
    $SHA256Hasher = New-Object -TypeName System.Security.Cryptography.SHA256CryptoServiceProvider
    $ConfigBlobSHA256Hash = ($SHA256Hasher.ComputeHash($RuleBytes) | ForEach-Object { $_.ToString('X2') }) -join ''

    [PSCustomObject] @{
        PSTypeName = 'Sysmon.EventCollection'
        SchemaVersion = $SchemaVersion
        ConfigBlobSHA256Hash = $ConfigBlobSHA256Hash
        Events = $EventCollection
    }
}


================================================
FILE: Functions/ConvertTo-SysmonXMLConfiguration.ps1
================================================
<#
.SYNOPSIS

Recovers a Sysmon XML configuration from a binary configuration.

.DESCRIPTION

ConvertTo-SysmonXMLConfiguration takes the parsed output from Get-SysmonConfiguration and converts it to an XML configuration. This function is useful for recovering lost Sysmon configurations or for performing reconnaisance.

Author: Matthew Graeber (@mattifestation)
License: BSD 3-Clause

Required Dependencies: Get-SysmonConfiguration
                       GeneratedCode.ps1

.PARAMETER Configuration

Specifies the parsed Sysmon configuration output from Get-SysmonConfiguration.

.EXAMPLE

Get-SysmonConfiguration | ConvertTo-SysmonXMLConfiguration

.EXAMPLE

$Configuration = Get-SysmonConfiguration
ConvertTo-SysmonXMLConfiguration -Configuration $Configuration

.INPUTS

Sysmon.Configuration

ConvertTo-SysmonXMLConfiguration accepts a single result from Get-SysmonConfiguration over the pipeline. Note: it will not accept input from Get-SysmonConfiguration when "-MatchExeOutput" is specified.

.OUTPUTS

System.String

Outputs a Sysmon XML configuration document.
#>
function ConvertTo-SysmonXMLConfiguration {
    [OutputType([String])]
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $True, ValueFromPipeline = $True)]
        [PSTypeName('Sysmon.Configuration')]
        $Configuration
    )

    $SchemaVersion = $Configuration.SchemaVersion

    # Get the parsing code for the respective schema.
    # Code injection note: an attacker would be able to influence the schema version used. That would only influence what
    #  non-injectible source code was supplied to Add-Type, however. $ConfigurationSchemaSource variables should always be
    #  constant variables with script (i.e. module) scope.
    $SchemaSource = Get-Variable -Name "SysmonConfigSchemaSource_$($SchemaVersion.Replace('.', '_'))" -Scope Script -ValueOnly
    
    # Compile the parsing code
    Add-Type -TypeDefinition $SchemaSource -ReferencedAssemblies 'System.Xml' -ErrorAction Stop

    $NamespaceName = "Sysmon_$($SchemaVersion.Replace('.', '_'))"

    # Create a base "Sysmon" object. This serves as the root node that will eventually be serialized to XML.
    $Sysmon = New-Object -TypeName "$NamespaceName.Sysmon"

    $Sysmon.schemaversion = $Configuration.SchemaVersion

    if ($Configuration.CRLCheckingEnabled) { $Sysmon.CheckRevocation = New-Object -TypeName "$NamespaceName.SysmonCheckRevocation" }

    # The hashing algorithms need to be lower case in the XML config.
    $Sysmon.HashAlgorithms = ($Configuration.HashingAlgorithms | ForEach-Object { $_.ToLower() }) -join ','

    $ProcessAccessString = ($Configuration.ProcessAccess | ForEach-Object { "$($_.ProcessName):0x$($_.AccessMask.ToString('x'))" }) -join ','
    if ($ProcessAccessString) { $Sysmon.ProcessAccessConfig = $ProcessAccessString }

    # Do not consider redundant event types. A well-formed binary Sysmon rule blob will have
    # identical RegistryEvent, PipeEvent, and WmiEvent rule entries as of config schema version 3.4[0]
    $EventTypesToExclude = @(
        'RegistryEventSetValue',
        'RegistryEventDeleteKey',
        'PipeEventConnected',
        'WmiEventConsumer',
        'WmiEventConsumerToFilter'
    )

    # Group rules by their respective event types - a requirement for
    # setting properties properly in the SysmonEventFiltering instance.
    $EventGrouping = $Configuration.Rules |
        Where-Object { -not ($EventTypesToExclude -contains $_.EventType) } |
            Group-Object -Property EventType

    # A configuration can technically not have any EventFiltering rules.
    if ($EventGrouping) {
        $Sysmon.EventFiltering = New-Object -TypeName "$NamespaceName.SysmonEventFiltering"

        foreach ($Event in $EventGrouping) {
            # The name of the event - e.g. ProcessCreate, FileCreate, etc.
            $EventName = $Event.Name

            # Normalize these event names.
            # Have a mentioned that I hate that these aren't unique names in Sysmon?
            switch ($EventName) {
                'RegistryEventCreateKey' { $EventName = 'RegistryEvent' }
                'PipeEventCreated' { $EventName = 'PipeEvent' }
                'WmiEventFilter' { $EventName = 'WmiEvent' }
            }

            if ($Event.Count -gt 2) {
                Write-Error "There is more than two $EventName entries. This should not be possible."
                return
            }

            if (($Event.Count -eq 2) -and ($Event.Group[0].OnMatch -eq $Event.Group[1].OnMatch)) {
                Write-Error "The `"onmatch`" attribute values for the $EventName rules are not `"include`" and `"exclude`". This should not be possible."
                return
            }

            $Events = foreach ($RuleSet in $Event.Group) {
                # The dynamic typing that follows relies upon naming consistency in the schema serialization source code.
                $EventInstance = New-Object -TypeName "$NamespaceName.SysmonEventFiltering$EventName" -Property @{
                    onmatch = $RuleSet.OnMatch.ToLower()
                }

                $RuleDefs = @{}

                foreach ($Rule in $RuleSet.Rules) {
                    $PropertyName = $Rule.RuleType
                    # Since each property can be of a unique type, resolve it accordingly.
                    $PropertyTypeName = ("$NamespaceName.SysmonEventFiltering$EventName" -as [Type]).GetProperty($PropertyName).PropertyType.FullName.TrimEnd('[]')

                    if (-not $RuleDefs.ContainsKey($PropertyName)) {
                        $RuleDefs[$PropertyName] = New-Object -TypeName "Collections.ObjectModel.Collection``1[$PropertyTypeName]"
                    }

                    $RuleInstance = New-Object -TypeName $PropertyTypeName
                    # This needs to be lower case in the XML config.
                    $RuleInstance.condition = $Rule.Filter.ToLower()
                    # An exception is thrown here if the value has a space and it is being cast to an enum type.
                    # Currently, "Protected Process" is the only instance. I'll need to refactor this if more instances arise.
                    if ($Rule.RuleText -eq 'Protected Process') { $RuleInstance.Value = 'ProtectedProcess' } else { $RuleInstance.Value = $Rule.RuleText }

                    $RuleDefs[$PropertyName].Add($RuleInstance)
                }

                # Set the collected rule properties accordingly.
                foreach ($PropertyName in $RuleDefs.Keys) {
                    $EventInstance."$PropertyName" = $RuleDefs[$PropertyName]
                }

                $EventInstance
            }

            $EventPropertyName = $Events[0].GetType().Name.Substring('SysmonEventFiltering'.Length)
            $Sysmon.EventFiltering."$EventPropertyName" = $Events
        }
    }

    $XmlWriter = $null

    try {
        $XmlWriterSetting = New-Object -TypeName Xml.XmlWriterSettings
        # A Sysmon XML config is not expected to have an XML declaration line.
        $XmlWriterSetting.OmitXmlDeclaration = $True
        $XmlWriterSetting.Indent = $True
        # Use two spaces in place of a tab character.
        $XmlWriterSetting.IndentChars = '  '
        # Normalize newlines to CRLF.
        $XmlWriterSetting.NewLineHandling = [Xml.NewLineHandling]::Replace

        $XMlStringBuilder = New-Object -TypeName Text.StringBuilder

        $XmlWriter = [Xml.XmlWriter]::Create($XMlStringBuilder, $XmlWriterSetting)

        $XmlSerializer = New-Object -TypeName Xml.Serialization.XmlSerializer -ArgumentList ("$NamespaceName.Sysmon" -as [Type]), ''
        # This will strip any additional "xmlns" attributes from the root Sysmon element.
        $EmptyNamespaces = New-Object -TypeName Xml.Serialization.XmlSerializerNamespaces
        $EmptyNamespaces.Add('', '')

        $XmlSerializer.Serialize($XmlWriter, $Sysmon, $EmptyNamespaces)
    } catch {
        Write-Error $_
    } finally {
        if ($XmlWriter) { $XmlWriter.Close() }
    }

    $XMlStringBuilder.ToString()
}


================================================
FILE: Functions/Get-SysmonConfiguration.ps1
================================================
<#
.SYNOPSIS

Parses a Sysmon driver configuration from the registry. Output is nearly identical to that of "sysmon.exe -c" but without the requirement to run sysmon.exe.

.DESCRIPTION

Get-SysmonConfiguration parses a Sysmon configuration from the registry without the need to run "sysmon.exe -c". This function is designed to enable Sysmon configuration auditing at scale as well as reconnaissance for red teamers. 

Get-SysmonConfiguration has been tested with the following Sysmon versions: 6.20

Due to the admin-only ACL set on the Sysmon driver registry key, Get-SysmonConfiguration will typically need to run in an elevated context. Because the user-mode service and driver names can be changed, Get-SysmonConfiguration will locate the service and driver regardless of their names.

Author: Matthew Graeber (@mattifestation)
License: BSD 3-Clause

Required Dependencies: ConvertFrom-SysmonBinaryConfiguration

.PARAMETER MatchExeOutput

Mirrors the text output of "sysmon.exe -c". This parameter was implemented primarily to enable testing scenarios - i.e. to ensure that the output matches that of the version of Sysmon (or schema) being tested against.

.EXAMPLE

Get-SysmonConfiguration

.EXAMPLE

Get-SysmonConfiguration -MatchExeOutput

.OUTPUTS

Sysmon.Configuration

Outputs a fully parsed Sysmon configuration including the hash of the registry rule blob for auditing purposes.

System.String

Outputs mirrored output from "sysmon.exe -c".

.NOTES

Get-SysmonConfiguration will have to be manually validated for each new Sysmon and configuration schema version. Please report all bugs and indiscrepencies with new versions by supplying the following information:

1) The Sysmon config XML that's generating the error (only schema versions 3.30 and later).
2) The version of Sysmon being used (only 6.20 and later).
#>
function Get-SysmonConfiguration {


    [OutputType('Sysmon.Configuration', ParameterSetName = 'PSOutput')]
    [OutputType([String], ParameterSetName = 'ExeOutput')]
    [CmdletBinding(DefaultParameterSetName = 'PSOutput')]
    param (
        [Parameter(ParameterSetName = 'ExeOutput')]
        [Switch]
        $MatchExeOutput
    )

    # Find the Sysmon driver based solely off the presence of the "Rules" value.
    # This is being done because the user can optionally specify a driver name other than the default: SysmonDrv
    $ServiceParameters = Get-ChildItem -Path HKLM:\SYSTEM\CurrentControlSet\Services -Recurse -Include 'Parameters' -ErrorAction SilentlyContinue
    $DriverParameters = $ServiceParameters | Where-Object { $_.Property -contains 'Rules' }

    if (-not $DriverParameters) {
        Write-Error 'Unable to locate a Sysmon driver. Either it is not installed or you do not have permissions to read the driver configuration in the registry.'
        return
    }

    $FoundSysmonMatch = $False
    $SysmonDriverName = $null
    $SysmonServiceName = $null
    $SysmonDriverParams = $null

    # Just in case there is more than one instance where there is a "Rules" value, correlate it with the user-mode service to confirm.
    $DriverParameters | ForEach-Object {
        $CandidateDriverName = $_.PSParentPath.Split('\')[-1]
        $CandidateDriverParams = $_

        $CandidateUserModeServices = $ServiceParameters | Where-Object { $_.Property -contains 'DriverName' }

        if (-not $CandidateUserModeServices) {
            Write-Error 'Unable to locate a user-mode Sysmon service.'
            return
        }

        $CandidateUserModeServices | ForEach-Object {
            $CandidateServiceName = $_.PSParentPath.Split('\')[-1]
            $DriverName = ($_ | Get-ItemProperty).DriverName

            # We have a matching user-mode Sysmon service and Sysmon driver.
            if ($DriverName -eq $CandidateDriverName) {
                $FoundSysmonMatch = $True
                $SysmonDriverName = $CandidateDriverName
                $SysmonServiceName = $CandidateServiceName
                $SysmonDriverParams = $CandidateDriverParams | Get-ItemProperty
            }
        }
    }

    if ($FoundSysmonMatch) {
        # HKLM\SYSTEM\CurrentControlSet\Services\<SYSMON_DRIVER_NAME>\Parameters
        $RuleBytes = $SysmonDriverParams.Rules                        # REG_BINARY
        $Options = $SysmonDriverParams.Options                        # REG_DWORD
        $HashingAlgorithmValue = $SysmonDriverParams.HashingAlgorithm # REG_DWORD
        $ProcessAccessMasks = $SysmonDriverParams.ProcessAccessMasks  # REG_BINARY - No larger than size: 0x28 (0x28 / 4 == 10: unique masks to interpret alongside ProcessAccessNames)
        $ProcessAccessNames = $SysmonDriverParams.ProcessAccessNames  # REG_MULTI_SZ - Can have no more than 10 entries
        $CheckRevocation = $SysmonDriverParams.CheckRevocation        # REG_BINARY of size: 1 byte

        # The high-order bit of HashingAlgorithm must be set to 1 (i.e. 0x80000000)
        $HashingAlgorithms = if ($HashingAlgorithmValue) {
            if ($HashingAlgorithmValue -band 1) { 'SHA1' }
            if ($HashingAlgorithmValue -band 2) { 'MD5' }
            if ($HashingAlgorithmValue -band 4) { 'SHA256' }
            if ($HashingAlgorithmValue -band 8) { 'IMPHASH' }
        }

        $NetworkConnection = $False
        if ($Options -band 1) { $NetworkConnection = $True }

        $ImageLoading = $False
        if ($Options -band 2) { $ImageLoading = $True }

        $CRLChecking = $False
        if (($CheckRevocation.Count -gt 0) -and ($CheckRevocation[0] -eq 1)) { $CRLChecking = $True }

        # Parse the binary rules blob.
        $Rules = ConvertFrom-SysmonBinaryConfiguration -RuleBytes $RuleBytes

        $ProcessAccess = $False
        if ($Rules.Events.EventType -contains 'ProcessAccess') { $ProcessAccess = $True }

        # Process ProcessAccessNames and ProcessAccessMasks.
        # The code path to actually use these appears to be a dead one now.
        # I'm only parsing this to mirror Sysmon 6.20 supporting parsing.
        $ProcessAccessList = New-Object -TypeName PSObject[]($ProcessAccessNames.Count)
        for ($i = 0; $i -lt $ProcessAccessNames.Count; $i++) {
            $ProcessAccessList[$i] = [PSCustomObject] @{
                ProcessName = $ProcessAccessNames[$i]
                AccessMask = [BitConverter]::ToInt32($ProcessAccessMasks, $i * 4)
            }
        }

        $Properties = [Ordered] @{
            PSTypeName = 'Sysmon.Configuration'
            ServiceName = $SysmonServiceName
            DriverName = $SysmonDriverName
            HashingAlgorithms = $HashingAlgorithms
            NetworkConnectionEnabled = $NetworkConnection
            ImageLoadingEnabled = $ImageLoading
            CRLCheckingEnabled = $CRLChecking
            ProcessAccessEnabled = $ProcessAccess
            ProcessAccess = $ProcessAccessList
            SchemaVersion = $Rules.SchemaVersion.ToString(2)
            ConfigBlobSHA256Hash = $Rules.ConfigBlobSHA256Hash
            Rules = $Rules.Events
        }

        # Don't print the ProcessAccess property if it's not populated. With Sysmon 6.20, this
        # should never be present anyway unless there's a stale artifact from an older version.
        if ($ProcessAccessList.Count -eq 0) { $Properties.Remove('ProcessAccess') }

        if ($MatchExeOutput) {

            $NetworkConnectionString = if ($NetworkConnection) { 'enabled' } else { 'disabled' }
            $ImageLoadingString = if ($ImageLoading) { 'enabled' } else { 'disabled' }
            $CRLCheckingString = if ($CRLChecking) { 'enabled' } else { 'disabled' }
            $ProcessAccessString = if ($ProcessAccess) { 'enabled' } else { 'disabled' }
            if ($ProcessAccessList) {
                $ProcessAccessString = ($ProcessAccessList | ForEach-Object { "`"$($_.ProcessName)`":0x$($_.AccessMask.ToString('x'))" }) -join ','
            }

            $AllRuleText = $Rules.Events | ForEach-Object {
                # Dumb hacks to format output to the original "sysmon.exe -c" output
                $EventType = $_.EventType
                if ($EventType.StartsWith('RegistryEvent')) { $EventType = 'RegistryEvent' }
                if ($EventType.StartsWith('WmiEvent')) { $EventType = 'WmiEvent' }
                if ($EventType.StartsWith('PipeEvent')) { $EventType = 'PipeEvent' }

                $RuleText = $_.Rules | ForEach-Object {
                    $FilterText = switch ($_.Filter) {
                        'Is' { 'is' }
                        'IsNot' { 'is not' }
                        'Contains' { 'contains' }
                        'Excludes' { 'excludes' }
                        'BeginWith' { 'begin with' }
                        'EndWith' { 'end with' }
                        'LessThan' { 'less than' }
                        'MoreThan' { 'more than' }
                        'Image' { 'image' }
                    }

                    "`t{0,-30} filter: {1,-12} value: '{2}'" -f $_.RuleType, $FilterText, $_.RuleText
                }

                $RuleSet =  @"
 - {0,-34} onmatch: {1}
{2}
"@ -f $EventType,
      $_.OnMatch.ToLower(),
      ($RuleText | Out-String).TrimEnd("`r`n")

                $RuleSet.TrimEnd("`r`n")
            }


            $ConfigOutput = @"
Current configuration:
{0,-34}{1}
{2,-34}{3}
{4,-34}{5}
{6,-34}{7}
{8,-34}{9}
{10,-34}{11}
{12,-34}{13}

Rule configuration (version {14}):
{15}
"@ -f ' - Service name:',
      $SysmonServiceName,
      ' - Driver name:',
      $SysmonDriverName,
      ' - HashingAlgorithms:',
      ($HashingAlgorithms -join ','),
      ' - Network connection:',
      $NetworkConnectionString,
      ' - Image loading:',
      $ImageLoadingString,
      ' - CRL checking:',
      $CRLCheckingString,
      ' - Process Access:',
      $ProcessAccessString,
      "$($Rules.SchemaVersion.Major).$($Rules.SchemaVersion.Minor.ToString().PadRight(2, '0'))",
      ($AllRuleText | Out-String).TrimEnd("`r`n")

            $ConfigOutput
        } else {
            [PSCustomObject] $Properties
        }
    } else {
        Write-Error 'Unable to locate a Sysmon driver and user-mode service.'
    }
}


================================================
FILE: Functions/Get-SysmonEventData.ps1
================================================
<#
.Synopsis
Searches for specified SysMon Events and retunrs the Event Data as a custom object.
.DESCRIPTION
Searches for specified SysMon Events and retunrs the Event Data as a custom object.
.EXAMPLE
Get-SysMonEventData -EventId 1 -MaxEvents 10 -EndTime (Get-Date) -StartTime (Get-Date).AddDays(-1)

All process creation events in the last 24hr
.EXAMPLE
Get-SysMonEventData -EventId 3 -MaxEvents 20 -Path .\export.evtx

last 20 network connection events from a exported SysMon log.
#>
function Get-SysmonEventData {
    [CmdletBinding(DefaultParameterSetName='ID',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/Get-SysmonEventData.md')]
    Param (
        # Sysmon Event ID of records to show
        [Parameter(Mandatory=$true,
            ParameterSetName='ID',
            ValueFromPipelineByPropertyName=$true,
            Position=0)]
        [ValidateSet(1,2,3,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,255)]
        [Int32[]]
        $EventId,

        # EventType that a Rule can be written against.
        [Parameter(Mandatory=$false,
            ParameterSetName='Type',
            ValueFromPipelineByPropertyName=$true,
            Position=0)]
        [string[]]
        [ValidateSet('NetworkConnect', 'ProcessCreate', 'FileCreateTime',
            'ProcessTerminate', 'ImageLoad', 'DriverLoad',
            'CreateRemoteThread', 'RawAccessRead', 'ProcessAccess', 'Error',
            'FileCreateStreamHash', 'RegistryValueSet', 'RegistryRename',
            'RegistryAddOrDelete', 'FileCreate','ConfigChange','PipeCreated',
            'PipeConnected', 'WmiFilter', 'WmiConsumer', 'WmiBinding',
            'DnsEvent', 'FileDelete', 'ClipboardChange', 'ProcessTampering')]
        $EventType,

        # Specifies the maximum number of events that Get-WinEvent returns. Enter an integer. The default is to return all the events in the logs or files.
        [Parameter(Mandatory=$false,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [int]
        $MaxEvents,

        # Specifies a path to one or more exported SysMon events in evtx format.
        [Parameter(Mandatory=$false,
            ValueFromPipeline=$true,
            ValueFromPipelineByPropertyName=$true,
            HelpMessage='Path to one or more locations.')]
        [Alias('PSPath')]
        [ValidateNotNullOrEmpty()]
        [string[]]
        $Path,

        # Start Date to get all event going forward.
        [Parameter(Mandatory=$false)]
        [datetime]
        $StartTime,

        # End data for searching events.
        [Parameter(Mandatory=$false)]
        [datetime]
        $EndTime
    )

    Begin
    {
        $EventTypeMap = @{
            ProcessCreate = 1
            FileCreateTime = 2
            NetworkConnect = 3
            ProcessTerminate = 5
            DriverLoad = 6
            ImageLoad = 7
            CreateRemoteThread = 8
            RawAccessRead = 9
            ProcessAccess = 10
            FileCreate = 11
            RegistryAddOrDelete = 12
            RegistryValueSet = 13
            RegistryRename = 14
            FileCreateStreamHash = 15
            ConfigChange = 16
            PipeCreated = 17
            PipeConnected = 18
            WmiFilter = 19
            WmiConsumer = 20
            WmiBinding = 21
            DnsEvent = 22
            FileDelete = 23
            ClipboardChange = 24
            ProcessTampering = 25
            Error = 255
        }

        $EventIdtoType = @{
            '1' = 'ProcessCreate'
            '2' = 'FileCreateTime'
            '3' = 'NetworkConnect'
            '5' = 'ProcessTerminate'
            '6' = 'DriverLoad'
            '7' = 'ImageLoad'
            '8' = 'CreateRemoteThread'
            '9' = 'RawAccessRead'
            '10' = 'ProcessAccess'
            '11' = 'FileCreate'
            '12' = 'RegistryAddOrDelete'
            '13' = 'RegistryValueSet'
            '14' = 'RegistryRename'
            '15' = 'FileCreateStreamHash'
            '16' = 'ConfigChange'
            '17' = 'PipeCreated'
            '18' = 'PipeConnected'
            '19' = 'WmiFilter'
            '20' = 'WmiConsumer'
            '21' = 'WmiBinding'
            '22' = 'DnsEvent'
            '23' = 'FileDelete'
            '24' = 'ClipboardChange'
            '25' = 'ProcessTampering'
            '255' = 'Error'

        }
    }
    Process
    {
        # Hash for filtering
        $HashFilter = @{LogName='Microsoft-Windows-Sysmon/Operational'}

        # Hash for command paramteters
        $ParamHash = @{}

        if ($MaxEvents -gt 0)
        {
            $ParamHash.Add('MaxEvents', $MaxEvents)
        }

        if ($Path -gt 0)
        {
            $ParamHash.Add('Path', $Path)
        }

        switch ($PSCmdlet.ParameterSetName) {
            'ID' { $HashFilter.Add('Id', $EventId) }
            'Type' {
                $EventIds = @()
                foreach ($etype in $EventType)
                {
                    $EventIds += $EventTypeMap[$etype]
                }
                $HashFilter.Add('Id', $EventIds)
            }
        }

        if ($StartTime)
        {
            $HashFilter.Add('StartTime', $StartTime)
        }

        if ($EndTime)
        {
            $HashFilter.Add('EndTime', $EndTime)
        }

        $ParamHash.Add('FilterHashTable',$HashFilter)
        Get-WinEvent @ParamHash | ForEach-Object {
            [xml]$evtxml = $_.toxml()
            $ProcInfo = [ordered]@{}
            $ProcInfo['EventId'] = $evtxml.Event.System.EventID
            $ProcInfo['EventType'] = $EventIdtoType[$evtxml.Event.System.EventID]
            $ProcInfo['Computer'] = $evtxml.Event.System.Computer
            $evtxml.Event.EventData.Data | ForEach-Object {
                $ProcInfo[$_.name] = $_.'#text'
            }
            New-Object psobject -Property $ProcInfo
        }
    }
    End {}
}

================================================
FILE: Functions/Get-SysmonHashingAlgorithm.ps1
================================================
#  .ExternalHelp Posh-SysMon.psm1-Help.xml
function Get-SysmonHashingAlgorithm
{
    [CmdletBinding(DefaultParameterSetName = 'Path',
                   HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/Get-SysmonHashingAlgorithm.md')]
    Param
    (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   ParameterSetName='Path',
                   Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [string]$Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   ParameterSetName='LiteralPath',
                   Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        [string]$LiteralPath
    )

    Begin{}
    Process
    {
        # Check if the file is a valid XML file and if not raise and error.
        try
        {
            switch($psCmdlet.ParameterSetName)
            {
                'Path'        {[xml]$Config = Get-Content -Path $Path}
                'LiteralPath' {[xml]$Config = Get-Content -LiteralPath $LiteralPath}
            }
        }
        catch [System.Management.Automation.PSInvalidCastException]
        {
            Write-Error -Message 'Specified file does not appear to be a XML file.'
            return
        }

        # Validate the XML file is a valid Sysmon file.
        if ($Config.SelectSingleNode('//Sysmon') -eq $null)
        {
            Write-Error -Message 'XML file is not a valid Sysmon config file.'
            return
        }

        if ($Config.Sysmon.schemaversion -notin $SysMonSupportedVersions)
        {
            Write-Error -Message 'This version of Sysmon Rule file is not supported.'
            return
        }

        $ObjOptions = @{}

        if ($Config.Sysmon.SelectSingleNode('//HashAlgorithms'))
        {
            $ObjOptions['Hashing'] = $config.Sysmon.HashAlgorithms
        }
        else
        {
            $ObjOptions['Hashing'] = ''
        }

        #$ObjOptions['Comment'] = $Config.'#comment'
        $ConfigObj = [pscustomobject]$ObjOptions
        $ConfigObj.pstypenames.insert(0,'Sysmon.HashingAlgorithm')
        $ConfigObj

    }
    End{}
}

================================================
FILE: Functions/Get-SysmonRule.ps1
================================================
#  .ExternalHelp Posh-SysMon.psm1-Help.xml
function Get-SysmonRule
{
    [CmdletBinding(DefaultParameterSetName = 'Path',
                   HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/Get-SysmonRule.md')]
    Param
    (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   ParameterSetName='Path',
                   Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [string]$Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   ParameterSetName='LiteralPath',
                   Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        [string]$LiteralPath,

        # Event type to parse rules for.
        [Parameter(Mandatory=$false,
                   ValueFromPipelineByPropertyName=$true,
                   Position=1)]
        [ValidateSet('ALL', 'NetworkConnect', 'ProcessCreate', 'FileCreateTime',
                     'ProcessTerminate', 'ImageLoad', 'DriverLoad', 'ProcessAccess',
                     'RawAccessRead','ProcessAccess', 'FileCreateStreamHash',
                     'RegistryEvent', 'FileCreate', 'PipeEvent', 'WmiEvent')]
        [string[]]
        $EventType = @('ALL')
    )

    Begin{}
    Process
    {
        # Check if the file is a valid XML file and if not raise and error.
        try
        {
            switch($psCmdlet.ParameterSetName)
            {
                'Path'        {[xml]$Config = Get-Content -Path $Path}
                'LiteralPath' {[xml]$Config = Get-Content -LiteralPath $LiteralPath}
            }
        }
        catch [System.Management.Automation.PSInvalidCastException]
        {
            Write-Error -Message 'Specified file does not appear to be a XML file.'
            return
        }

        # Validate the XML file is a valid Sysmon file.
        if ($Config.SelectSingleNode('//Sysmon') -eq $null)
        {
            Write-Error -Message 'XML file is not a valid Sysmon config file.'
            return
        }

         if ($Config.Sysmon.schemaversion -notin $SysMonSupportedVersions)
        {
            Write-Error -Message 'This version of Sysmon Rule file is not supported.'
            return
        }

        # Collect all individual rules if they exist.
        $Rules = $Config.Sysmon.EventFiltering

        if ($EventType -contains 'ALL')
        {
            $TypesToParse = @('NetworkConnect', 'ProcessCreate', 'FileCreateTime',
                              'ProcessTerminate', 'ImageLoad', 'DriverLoad','CreateRemoteThread',
                              'ProcessAccess', 'RawAccessRead', 'FileCreateStreamHash',
                              'RegistryEvent', 'FileCreate', 'PipeEvent', 'WmiEvent')
        }
        else
        {
            $TypesToParse = $EventType
        }

        foreach($Type in $TypesToParse)
        {
            $EvtType = $MyInvocation.MyCommand.Module.PrivateData[$Type]
            $RuleData = $Rules.SelectNodes("//EventFiltering/$($EvtType)")
            if($RuleData -ne $null)
            {
                Write-Verbose -Message "$($EvtType) Rule Found."
                Get-RuleWithFilter($RuleData)
            }

        }
    }
    End{}
}

================================================
FILE: Functions/Get-SysmonRuleFilter.ps1
================================================
<#
.SYNOPSIS
Get the configured filters for a specified Event Type Rule in a Sysmon configuration file.
.DESCRIPTION
Get the configured filters for a specified Event Type Rule in a Sysmon configuration file.
.EXAMPLE
C:\PS>  Get-SysmonRuleFilter -Path C:\sysmon.xml -EventType ProcessCreate
Get the filter under the ProcessCreate Rule.
#>
function Get-SysmonRuleFilter {
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/Get-SysmonRuleFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type rule to get filter for.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=1)]
        [ValidateSet('NetworkConnect', 'ProcessCreate', 'FileCreateTime',
            'ProcessTerminate', 'ImageLoad', 'DriverLoad',
            'CreateRemoteThread','RawAccessRead', 'ProcessAccess',
            'FileCreateStreamHash', 'RegistryEvent', 'FileCreate',
            'PipeEvent', 'WmiEvent','RuleName')]
        [string]
        $EventType,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch
    )

    Begin{}
    Process {
        $EvtType = $null
        # Check if the file is a valid XML file and if not raise and error.
        try {
            switch($psCmdlet.ParameterSetName){
                'Path'{
                    [xml]$Config = Get-Content -Path $Path
                    $FileLocation = (Resolve-Path -Path $Path).Path
                }
                'LiteralPath' {
                    [xml]$Config = Get-Content -LiteralPath $LiteralPath
                    $FileLocation = (Resolve-Path -LiteralPath $LiteralPath).Path
                }
            }
        }
        catch [System.Management.Automation.PSInvalidCastException] {
            Write-Error -Message 'Specified file does not appear to be a XML file.'
            return
        }

        # Validate the XML file is a valid Sysmon file.
        if ($Config.SelectSingleNode('//Sysmon') -eq $null){
            Write-Error -Message 'XML file is not a valid Sysmon config file.'
            return
        }

        $Rules = $Config.SelectSingleNode('//Sysmon/EventFiltering')

        if ($Rules -eq '') {
            Write-Error -Message 'Rule element does not exist. This appears to not be a valid config file'
            return
        } else {
            $EvtType = $MyInvocation.MyCommand.Module.PrivateData[$EventType]

            $EventRule = $Rules.SelectNodes("//EventFiltering/$($EvtType)")
        }

        if($EventRule -eq $null) {
            Write-Error -Message "No rule for $($EvtType) was found."
            return
        } else {
            if ($EventRule.count -eq $null -or $EventRule.Count -eq 1) {
                Write-Verbose -Message 'Single Node'
                if ($EventRule.onmatch -eq $OnMatch) {
                    $Filters = $EventRule.SelectNodes('*')
                    if ($Filters.ChildNodes.Count -gt 0) {
                        foreach($Filter in $Filters) {
                            $FilterObjProps = @{}
                            $FilterObjProps['EventField'] = $Filter.Name
                            $FilterObjProps['Condition'] = &{if($Filter.condition -eq $null){'is'}else{$Filter.condition}}
                            $FilterObjProps['Value'] =  $Filter.'#text'
                            $FilterObjProps['EventType'] =  $EvtType
                            $FilterObjProps['OnMatch'] =  $OnMatch
                            $FilterObj = [pscustomobject]$FilterObjProps
                            $FilterObj.pstypenames.insert(0,'Sysmon.Rule.Filter')
                            $FilterObj
                        }

                    }
                }
            }
            else
            {
                Write-Verbose -Message 'Mutiple nodes.'
                foreach ($rule in $EventRule)
                {
                    if ($rule.onmatch -eq $OnMatch)
                    {
                        $Filters = $rule.SelectNodes('*')
                        if ($Filters.ChildNodes.Count -gt 0)
                        {
                            foreach($Filter in $Filters)
                            {
                                $FilterObjProps = @{}
                                $FilterObjProps['EventField'] = $Filter.Name
                                $FilterObjProps['Condition'] = &{if($Filter.condition -eq $null){'is'}else{$Filter.condition}}
                                $FilterObjProps['Value'] =  $Filter.'#text'
                                $FilterObjProps['EventType'] =  $EvtType
                                $FilterObjProps['OnMatch'] =  $OnMatch
                                $FilterObj = [pscustomobject]$FilterObjProps
                                $FilterObj.pstypenames.insert(0,'Sysmon.Rule.Filter')
                                $FilterObj
                            }

                        }
                    }
                }
            }
        }
    }
    End{}
}

================================================
FILE: Functions/New-SysmonConfiguration.ps1
================================================
#  .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonConfiguration
{
    [CmdletBinding(HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonConfiguration.md')]
    Param
    (
        # Path to write XML config file.
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=0)]
        [String]
        $Path,

        # Specify one or more hash algorithms used for image identification
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=1)]
        [ValidateSet('ALL', 'MD5', 'SHA1', 'SHA256', 'IMPHASH')]
        [string[]]
        $HashingAlgorithm,

        # Log Network Connections
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=2)]
        [Switch]
        $NetworkConnect,

        # Log process loading of modules.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=3)]
        [Switch]
        $DriverLoad,

        # Log process loading of modules.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=4)]
        [Switch]
        $ImageLoad,

        # Log create remote thread actions.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=5)]
        [Switch]
        $CreateRemoteThread,

        # Log file creation time modifications.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=6)]
        [Switch]
        $FileCreateTime,

        # Log process creation.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=7)]
        [Switch]
        $ProcessCreate,

        # Log process termination.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=8)]
        [Switch]
        $ProcessTerminate,

        # Log when a running process opens another process.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=9)]
        [Switch]
        $ProcessAccess,

        # Log raw access reads of files.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=10)]
        [Switch]
        $RawAccessRead,

        # Check for signature certificate revocation.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=11 )]
        [Switch]
        $CheckRevocation,

        # Log Registry events.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=12 )]
        [Switch]
        $RegistryEvent,

        # Log File Creation events.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=13 )]
        [Switch]
        $FileCreate,

        # Log File Stream creations events.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=14 )]
        [Switch]
        $FileCreateStreamHash,

        # Log NamedPipes connection and creations events.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=15 )]
        [Switch]
        $PipeEvent,

        # WMI Permanent Event component events.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true,
                   Position=16 )]
        [Switch]
        $WmiEvent,

        # Comment for purpose of the configuration file.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true)]
        [String]
        $Comment,

        # Schema Vesion for the configuration file, default is 4.1.
        [Parameter(Mandatory=$False,
                   ValueFromPipelineByPropertyName=$true)]
                   [ValidateSet('4.0','4.1')]
        [string]
        $SchemaVersion = '4.1'
    )

    Begin{}
    Process {
        if ($HashingAlgorithm -contains 'ALL') {
            $Hash = '*'
        } else {
            $Hash = $HashingAlgorithm -join ','
        }

        $Config = ($ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Path))

        # get an XMLTextWriter to create the XML

        $XmlWriter = New-Object System.XMl.XmlTextWriter($Config,$Null)

        # choose a pretty formatting:
        $xmlWriter.Formatting = 'Indented'
        $xmlWriter.Indentation = 1

        # write the header
        if ($Comment)
        {
            $xmlWriter.WriteComment($Comment)
        }
        $xmlWriter.WriteStartElement('Sysmon')

        $XmlWriter.WriteAttributeString('schemaversion', $SchemaVersion)

        Write-Verbose -Message "Enabling hashing algorithms : $($Hash)"
        $xmlWriter.WriteElementString('HashAlgorithms',$Hash)

        # Enable checking revocation.
        if ($CheckRevocation) {
            Write-Verbose -message 'Enabling CheckRevocation.'
            $xmlWriter.WriteElementString('CheckRevocation','')
        }

        # Create empty EventFiltering section.
        $xmlWriter.WriteStartElement('EventFiltering')

        if ($NetworkConnect) {
            Write-Verbose -Message 'Enabling network connection logging for all connections by setting no filter and onmatch to exclude.'
            $xmlWriter.WriteStartElement('NetworkConnect')
            $XmlWriter.WriteAttributeString('onmatch', 'exclude')
            $xmlWriter.WriteFullEndElement()
        }

        if ($DriverLoad) {
            Write-Verbose -Message 'Enabling logging all driver loading by setting no filter and onmatch to exclude.'
            $xmlWriter.WriteStartElement('DriverLoad ')
            $XmlWriter.WriteAttributeString('onmatch', 'exclude')
            $xmlWriter.WriteFullEndElement()
        }

        if ($ImageLoad) {
            Write-Verbose -Message 'Enabling logging all image loading by setting no filter and onmatch to exclude.'
            $xmlWriter.WriteStartElement('ImageLoad ')
            $XmlWriter.WriteAttributeString('onmatch', 'exclude')
            $xmlWriter.WriteFullEndElement()
        }

        if ($CreateRemoteThread) {
            Write-Verbose -Message 'Enabling logging all  CreateRemoteThread API actions by setting no filter and onmatch to exclude.'
            $xmlWriter.WriteStartElement('CreateRemoteThread ')
            $XmlWriter.WriteAttributeString('onmatch', 'exclude')
            $xmlWriter.WriteFullEndElement()
        }

        if ($ProcessCreate) {
            Write-Verbose -Message 'Enabling logging all  process creation by setting no filter and onmatch to exclude.'
            $xmlWriter.WriteStartElement('ProcessCreate ')
            $XmlWriter.WriteAttributeString('onmatch', 'exclude')
            $xmlWriter.WriteFullEndElement()
        }

        if ($ProcessTerminate) {
            Write-Verbose -Message 'Enabling logging all  process termination by setting no filter and onmatch to exclude.'
            $xmlWriter.WriteStartElement('ProcessTerminate ')
            $XmlWriter.WriteAttributeString('onmatch', 'exclude')
            $xmlWriter.WriteFullEndElement()
        }

        if ($FileCreateTime) {
            Write-Verbose -Message 'Enabling logging all  process creation by setting no filter and onmatch to exclude.'
            $xmlWriter.WriteStartElement('FileCreateTime ')
            $XmlWriter.WriteAttributeString('onmatch', 'exclude')
            $xmlWriter.WriteFullEndElement()
        }

        if ($ProcessAccess) {
            Write-Verbose -Message 'Enabling logging all  process access by setting no filter and onmatch to exclude.'
            $xmlWriter.WriteStartElement('ProcessAccess ')
            $XmlWriter.WriteAttributeString('onmatch', 'exclude')
            $xmlWriter.WriteFullEndElement()
        }

        if ($RawAccessRead) {
            Write-Verbose -Message 'Enabling logging all  process access by setting no filter and onmatch to exclude.'
            $xmlWriter.WriteStartElement('RawAccessRead ')
            $XmlWriter.WriteAttributeString('onmatch', 'exclude')
            $xmlWriter.WriteFullEndElement()
        }

        # Log registry events.
        if ($RegistryEvent) {
            Write-Verbose -message 'Enabling RegistryEvent.'
            $xmlWriter.WriteStartElement('RegistryEvent ')
            $XmlWriter.WriteAttributeString('onmatch', 'exclude')
            $xmlWriter.WriteFullEndElement()
        }

        # Log file create events.
        if ($FileCreate) {
            Write-Verbose -message 'Enabling FileCreate.'
            $xmlWriter.WriteStartElement('FileCreate ')
            $XmlWriter.WriteAttributeString('onmatch', 'exclude')
            $xmlWriter.WriteFullEndElement()
        }

        # Log file create events.
        if ($FileCreateStreamHash) {
            Write-Verbose -message 'Enabling FileCreateStreamHash.'
            $xmlWriter.WriteStartElement('FileCreateStreamHash ')
            $XmlWriter.WriteAttributeString('onmatch', 'exclude')
            $xmlWriter.WriteFullEndElement()
        }

        # NamedPipes create and connect events.
        if ($PipeEvent) {
            Write-Verbose -message 'Enabling PipeEvent.'
            $xmlWriter.WriteStartElement('PipeEvent ')
            $XmlWriter.WriteAttributeString('onmatch', 'exclude')
            $xmlWriter.WriteFullEndElement()
        }

        # NamedPipes create and connect events.
        if ($WmiEvent) {
            Write-Verbose -message 'Enabling WmiEvent.'
            $xmlWriter.WriteStartElement('WmiEvent ')
            $XmlWriter.WriteAttributeString('onmatch', 'exclude')
            $xmlWriter.WriteFullEndElement()
        }

        # End Element of EventFiltering
        $xmlWriter.WriteFullEndElement()

        # Sysmon
        $xmlWriter.WriteEndElement()

        # finalize the document:
        #$xmlWriter.WriteEndDocument()
        $xmlWriter.Flush()
        $xmlWriter.Close()
        Write-Verbose -Message "Config file created as $($Config)"
        write-verbose -Message "Configuration is for Sysmon $($sysmonVerMap[$SchemaVersion])"
    }
    End {}
}

================================================
FILE: Functions/New-SysmonCreateRemoteThreadFilter.ps1
================================================
#  .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonCreateRemoteThreadFilter {
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonCreateRemoteThreadFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch,

        # Condition for filtering against and event field.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
            'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
        [string]
        $Condition,

        # Event field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=3)]
        [ValidateSet('SourceImage', 'TargetImage')]
        [string]
        $EventField,

        # Value of Event Field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=4)]
        [string[]]
        $Value,

        # Rule Name for the filter.
        [Parameter(Mandatory=$false,
            ValueFromPipelineByPropertyName=$true)]
        [string]
        $RuleName
    )

    Begin { }
    Process {
        $FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
        $cmdoptions = @{
            'EventType' =  'CreateRemoteThread'
            'Condition' = $Condition
            'EventField' = $FieldString
            'Value' = $Value
            'OnMatch' = $OnMatch

        }

        if($RuleName) {
            $cmdoptions.Add('RuleName',$RuleName)
        }

        switch($psCmdlet.ParameterSetName) {
            'Path' {
                $cmdOptions.Add('Path',$Path)
                New-RuleFilter @cmdOptions
            }

            'LiteralPath' {
                $cmdOptions.Add('LiteralPath',$LiteralPath)
                New-RuleFilter @cmdOptions
            }
        }
    }
    End {}
}

================================================
FILE: Functions/New-SysmonDriverLoadFilter.ps1
================================================
#  .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonDriverLoadFilter {
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonDriverLoadFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch,

        # Condition for filtering against and event field.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
            'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
        [string]
        $Condition,

        # Event field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=3)]
        [ValidateSet('UtcTime', 'ImageLoaded',
            'Hashes', 'Signed', 'Signature')]
        [string]
        $EventField,

        # Value of Event Field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=4)]
        [string[]]
        $Value,

        # Rule Name for the filter.
        [Parameter(Mandatory=$false,
            ValueFromPipelineByPropertyName=$true)]
        [string]
        $RuleName
    )

    Begin {}
    Process {
        $FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
        $cmdoptions = @{
            'EventType' =  'DriverLoad'
            'Condition' = $Condition
            'EventField' = $FieldString
            'Value' = $Value
            'OnMatch' = $OnMatch

        }

        if($RuleName) {
            $cmdoptions.Add('RuleName',$RuleName)
        }

        switch($psCmdlet.ParameterSetName) {
            'Path' {
                $cmdOptions.Add('Path',$Path)
                New-RuleFilter @cmdOptions
            }

            'LiteralPath' {
                $cmdOptions.Add('LiteralPath',$LiteralPath)

                New-RuleFilter @cmdOptions
            }
        }
    }
    End {}
}

================================================
FILE: Functions/New-SysmonFileCreateFilter.ps1
================================================
#  .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonFileCreateFilter {
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonFileCreateFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch,

        # Condition for filtering against and event field.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
        'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
        [string]
        $Condition,

        # Event field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=3)]
        [ValidateSet('UtcTime', 'ProcessGuid', 'ProcessId', 'Image',
            'TargetFilename', 'CreationUtcTime',
            'PreviousCreationUtcTime')]
        [string]
        $EventField,

        # Value of Event Field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=4)]
        [string[]]
        $Value,

        # Rule Name for the filter.
        [Parameter(Mandatory=$false,
            ValueFromPipelineByPropertyName=$true)]
        [string]
        $RuleName
    )

    Begin {}
    Process {
        $FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
        $cmdoptions = @{
            'EventType' =  'FileCreateStreamHash'
            'Condition' = $Condition
            'EventField' = $FieldString
            'Value' = $Value
            'OnMatch' = $OnMatch
        }

        if($RuleName) {
            $cmdoptions.Add('RuleName',$RuleName)
        }

        switch ($PSCmdlet.ParameterSetName) {
            'Path' {
                $cmdOptions.Add('Path',$Path)
                New-RuleFilter @cmdOptions
            }

            'LiteralPath' {
                $cmdOptions.Add('LiteralPath',$LiteralPath)
                New-RuleFilter @cmdOptions
            }
        }
    }
    End {}
}

================================================
FILE: Functions/New-SysmonFileCreateStreamHashFilter.ps1
================================================
<#
.SYNOPSIS
Create a new filter for the logging of the saving of data on a file stream.
.DESCRIPTION
Create a new filter for the logging of the saving of data on a file stream.
#>
function New-SysmonFileCreateStreamHashFilter {
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonFileCreateStreamHashFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch,

        # Condition for filtering against and event field.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
            'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
        [string]
        $Condition,

        # Event field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=3)]
        [ValidateSet('TargetFilename', 'ProcessGuid', 'ProcessId',
            'Image')]
        [string]
        $EventField,

        # Value of Event Field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=4)]
        [string[]]
        $Value,

        # Rule Name for the filter.
        [Parameter(Mandatory=$false,
            ValueFromPipelineByPropertyName=$true)]
        [string]
        $RuleName
    )

    Begin {}
    Process {
        $FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
        $cmdoptions = @{
            'EventType' =  'FileCreateStreamHash'
            'Condition' = $Condition
            'EventField' = $FieldString
            'Value' = $Value
            'OnMatch' = $OnMatch
        }

        if($RuleName) {
            $cmdoptions.Add('RuleName',$RuleName)
        }

        switch ($PSCmdlet.ParameterSetName) {
            'Path' {
                $cmdOptions.Add('Path',$Path)
                New-RuleFilter @cmdOptions
            }

            'LiteralPath' {
                $cmdOptions.Add('LiteralPath',$LiteralPath)
                New-RuleFilter @cmdOptions
            }
        }
    }
    End {}
}

================================================
FILE: Functions/New-SysmonImageLoadFilter.ps1
================================================
#  .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonImageLoadFilter {
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonImageLoadFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch,

        # Condition for filtering against and event field.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
            'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
        [string]
        $Condition,

        # Event field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=3)]
        [ValidateSet('UtcTime', 'ProcessGuid', 'ProcessId', 'Image',
            'ImageLoaded', 'Hashes', 'Signed',
            'Signature', 'FileVersion',
            'Description', 'Product', 'Company')]
        [string]
        $EventField,

        # Value of Event Field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=4)]
        [string[]]
        $Value,

        # Rule Name for the filter.
        [Parameter(Mandatory=$false,
            ValueFromPipelineByPropertyName=$true)]
        [string]
        $RuleName
    )

    Begin {}
    Process
    {
        switch($psCmdlet.ParameterSetName)
        {
            'Path'
            {
                $ConfigVer = Select-Xml -Path $Path -XPath '//Sysmon/@schemaversion'
            }

            'LiteralPath'
            {
                $ConfigVer = Select-Xml -LiteralPath $LiteralPath -XPath '//Sysmon/@schemaversion'
            }
        }

        if ($ConfigVer.Node."#text" -lt 4.0 -and ($EventField -in @('FileVersion','Description', 'Product', 'Company'))) {
            Write-Error -Message "The event field $($EventField) is not supported under this schema."
            Return
        }

        $FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
        $cmdoptions = @{
            'EventType' =  'ImageLoad'
            'Condition' = $Condition
            'EventField' = $FieldString
            'Value' = $Value
            'OnMatch' = $OnMatch

        }

        if($RuleName) {
            $cmdoptions.Add('RuleName',$RuleName)
        }

        switch($psCmdlet.ParameterSetName)
        {
            'Path'
            {
                $cmdOptions.Add('Path',$Path)
                New-RuleFilter @cmdOptions
            }

            'LiteralPath'
            {
                $cmdOptions.Add('LiteralPath',$LiteralPath)
                New-RuleFilter @cmdOptions
            }
        }

    }
    End { }
}

================================================
FILE: Functions/New-SysmonNetworkConnectFilter.ps1
================================================
#  .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonNetworkConnectFilter
{
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonNetworkConnectFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch,

        # Condition for filtering against and event field.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
            'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
        [string]
        $Condition,

        # Event field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=3)]
        [ValidateSet('UtcTime', 'ProcessGuid', 'ProcessId', 'Image',
            'User', 'Protocol', 'Initiated', 'SourceIsIpv6',
            'SourceIp', 'SourceHostname', 'SourcePort',
            'SourcePortName', 'DestinationIsIpv6',
            'DestinationIp', 'DestinationHostname',
            'DestinationPort', 'DestinationPortName')]
        [string]
        $EventField,

        # Value of Event Field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=4)]
        [string[]]
        $Value,

        # Rule Name for the filter.
        [Parameter(Mandatory=$false,
            ValueFromPipelineByPropertyName=$true)]
        [string]
        $RuleName
    )

    Begin {}
    Process {
        $FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
        $cmdoptions = @{
            'EventType' =  'NetworkConnect'
            'Condition' = $Condition
            'EventField' = $FieldString
            'Value' = $Value
            'OnMatch' = $OnMatch

        }

        if($RuleName) {
            $cmdoptions.Add('RuleName',$RuleName)
        }

        switch($psCmdlet.ParameterSetName) {
            'Path' {
                $cmdOptions.Add('Path',$Path)
                New-RuleFilter @cmdOptions
            }

            'LiteralPath' {
                $cmdOptions.Add('LiteralPath',$LiteralPath)
                New-RuleFilter @cmdOptions
            }
        }
    }
    End {}
}

================================================
FILE: Functions/New-SysmonPipeFilter.ps1
================================================
<#
.SYNOPSIS
Create a new filter for when a Named Pipe is created or connected.
.DESCRIPTION
Create a new filter for when a Named Pipe is created or connected.
Useful for watching malware inter process communication.
#>
function New-SysmonPipeFilter {
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonPipeFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch,

        # Condition for filtering against and event field.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
            'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
        [string]
        $Condition,

        # Event field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=3)]
        [ValidateSet('Pipe', 'ProcessGuid', 'ProcessId',
            'Image')]
        [string]
        $EventField,

        # Value of Event Field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=4)]
        [string[]]
        $Value,

        # Rule Name for the filter.
        [Parameter(Mandatory=$false,
            ValueFromPipelineByPropertyName=$true)]
        [string]
        $RuleName
    )

    Begin {}
    Process {
        $FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
        $cmdoptions = @{
            'EventType' =  'PipeEvent'
            'Condition' = $Condition
            'EventField' = $FieldString
            'Value' = $Value
            'OnMatch' = $OnMatch

        }

        if($RuleName) {
            $cmdoptions.Add('RuleName',$RuleName)
        }

        switch ($PSCmdlet.ParameterSetName) {
            'Path' {
                $cmdOptions.Add('Path',$Path)
                New-RuleFilter @cmdOptions
            }

            'LiteralPath' {
                $cmdOptions.Add('LiteralPath',$LiteralPath)
                New-RuleFilter @cmdOptions
            }
        }
    }
    End {}
}

================================================
FILE: Functions/New-SysmonProcessAccessFilter.ps1
================================================
<#
.SYNOPSIS
Create a new filter for the logging of when a running process opens another.
.DESCRIPTION
Create a new filter for the logging of when a running process opens another.
.EXAMPLE
C:\PS> New-SysmonProcessAccessFilter -Path .\testver31.xml -OnMatch include -Condition Contains -EventField TargetImage lsass.exe
Log any process trying to open lsass.exe.
#>
function New-SysmonProcessAccessFilter {
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonProcessAccessFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch,

        # Condition for filtering against and event field.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
            'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
            [string]
        $Condition,

        # Event field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=3)]
        [ValidateSet('UtcTime', 'SourceProcessGUID',
            'SourceProcessId', 'SourceThreadId', 'SourceImage',
            'TargetProcessGUID', 'TargetProcessId', 'TargetImage',
            'GrantedAccess','CallTrace')]
        [string]
        $EventField,

        # Value of Event Field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=4)]
        [string[]]
        $Value,

        # Rule Name for the filter.
        [Parameter(Mandatory=$false,
            ValueFromPipelineByPropertyName=$true)]
        [string]
        $RuleName
    )

    Begin {}
    Process {
        $FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
        $cmdoptions = @{
            'EventType' =  'ProcessAccess'
            'Condition' = $Condition
            'EventField' = $FieldString
            'Value' = $Value
            'OnMatch' = $OnMatch

        }

        if($RuleName) {
            $cmdoptions.Add('RuleName',$RuleName)
        }

        switch ($PSCmdlet.ParameterSetName) {
            'Path' {
                $cmdOptions.Add('Path',$Path)
                New-RuleFilter @cmdOptions
            }

            'LiteralPath' {
                $cmdOptions.Add('LiteralPath',$LiteralPath)
                New-RuleFilter @cmdOptions
            }
        }
    }
    End {}
}

================================================
FILE: Functions/New-SysmonProcessCreateFilter.ps1
================================================
#  .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonProcessCreateFilter
{
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonProcessCreateFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch,

        # Condition for filtering against and event field.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
            'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
        [string]
        $Condition,

        # Event field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=3)]
        [ValidateSet('UtcTime', 'ProcessGuid', 'ProcessId', 'Image',
            'CommandLine', 'User', 'LogonGuid', 'LogonId',
            'TerminalSessionId', 'IntegrityLevel',
            'Hashes', 'ParentProcessGuid', 'ParentProcessId',
            'ParentImage', 'ParentCommandLine', 'FileVersion',
            'Description', 'Product', 'Company')]
        [string]
        $EventField,

        # Value of Event Field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=4)]
        [string[]]
        $Value,

        # Rule Name for the filter.
        [Parameter(Mandatory=$false,
            ValueFromPipelineByPropertyName=$true)]
        [string]
        $RuleName
    )

    Begin {}
    Process {
        switch($psCmdlet.ParameterSetName)
        {
            'Path'
            {
                $ConfigVer = Select-Xml -Path $Path -XPath '//Sysmon/@schemaversion'
            }

            'LiteralPath'
            {
                $ConfigVer = Select-Xml -LiteralPath $LiteralPath -XPath '//Sysmon/@schemaversion'
            }
        }

        if ($ConfigVer.Node."#text" -lt 4.0 -and ($EventField -in @('FileVersion','Description', 'Product', 'Company'))) {
            Write-Error -Message "The event field $($EventField) is not supported under this schema."
            Return
        }

        $FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]

        $cmdoptions = @{
            'EventType' =  'ProcessCreate'
            'Condition' = $Condition
            'EventField' = $FieldString
            'Value' = $Value
            'OnMatch' = $OnMatch

        }

        if($RuleName) {
            $cmdoptions.Add('RuleName',$RuleName)
        }

        switch($psCmdlet.ParameterSetName) {
            'Path' {
                $cmdOptions.Add('Path',$Path)
                New-RuleFilter @cmdOptions
            }

            'LiteralPath' {
                $cmdOptions.Add('LiteralPath',$LiteralPath)
                New-RuleFilter @cmdOptions
            }
        }
    }
    End { }
}

================================================
FILE: Functions/New-SysmonProcessTerminateFilter.ps1
================================================
#  .ExternalHelp Posh-SysMon.psm1-Help.xml
function New-SysmonProcessTerminateFilter
{
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonProcessTerminateFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch,

        # Condition for filtering against and event field.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
            'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
        [string]
        $Condition,

        # Event field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=3)]
        [ValidateSet('UtcTime', 'ProcessGuid', 'ProcessId')]
        [string]
        $EventField,

        # Value of Event Field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=4)]
        [string[]]
        $Value,

        # Rule Name for the filter.
        [Parameter(Mandatory=$false,
            ValueFromPipelineByPropertyName=$true)]
        [string]
        $RuleName
    )

    Begin {}
    Process
    {
        $FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
        $cmdoptions = @{
            'EventType' =  'ProcessTerminate'
            'Condition' = $Condition
            'EventField' = $FieldString
            'Value' = $Value
            'OnMatch' = $OnMatch

        }

        if($RuleName) {
            $cmdoptions.Add('RuleName',$RuleName)
        }

        switch($psCmdlet.ParameterSetName)
        {
            'Path'
            {
                $cmdOptions.Add('Path',$Path)
                New-RuleFilter @cmdOptions
            }

            'LiteralPath'
            {
                $cmdOptions.Add('LiteralPath',$LiteralPath)
                New-RuleFilter @cmdOptions
            }
        }
    }
    End {}
}

================================================
FILE: Functions/New-SysmonRawAccessReadFilter.ps1
================================================
<#
.SYNOPSIS
Create a new filter for the logging of file raw access read actions.
.DESCRIPTION
Create a new filter for the logging of file raw access read actions.
.EXAMPLE
C:\PS> New-SysmonRawAccessReadFilter -Path .\testver31.xml -OnMatch include -Condition Contains -EventField Image NTDS.dit
Log any raw access read of the file NTDS.dit.
#>
function New-SysmonRawAccessReadFilter {
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonRawAccessReadFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch,

        # Condition for filtering against and event field.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
            'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
        [string]
        $Condition,

        # Event field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=3)]
        [ValidateSet('UtcTime', 'ProcessGuid', 'ProcessId',
            'Image', 'Device')]
        [string]
        $EventField,

        # Value of Event Field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=4)]
        [string[]]
        $Value,

        # Rule Name for the filter.
        [Parameter(Mandatory=$false,
            ValueFromPipelineByPropertyName=$true)]
        [string]
        $RuleName
    )

    Begin {}
    Process {
        $FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
        $cmdoptions = @{
            'EventType' =  'RawAccessRead'
            'Condition' = $Condition
            'EventField' = $FieldString
            'Value' = $Value
            'OnMatch' = $OnMatch

        }

        if($RuleName) {
            $cmdoptions.Add('RuleName',$RuleName)
        }


        switch ($PSCmdlet.ParameterSetName) {
            'Path' {
                $cmdOptions.Add('Path',$Path)
                New-RuleFilter @cmdOptions
            }

            'LiteralPath' {
                $cmdOptions.Add('LiteralPath',$LiteralPath)
                New-RuleFilter @cmdOptions
            }
        }
    }
    End {}
}

================================================
FILE: Functions/New-SysmonRegistryFilter.ps1
================================================
<#
.SYNOPSIS
Create a new filter for the actions against the registry.
.DESCRIPTION
Create a new filter for actions against the registry. Supports filtering
by aby of the following event types:
* CreateKey
* DeleteKey
* RenameKey
* CreateValue
* DeleteValue
* RenameValue
* SetValue

Hives on Schema 3.2 in TargetObject are referenced as:
* \REGISTRY\MACHINE\HARDWARE
* \REGISTRY\USER\Security ID number
* \REGISTRY\MACHINE\SECURITY
* \REGISTRY\USER\.DEFAULT
* \REGISTRY\MACHINE\SYSTEM
* \REGISTRY\MACHINE\SOFTWARE
* \REGISTRY\MACHINE\SAM

Hives on Schema 3.3 and above in TargetObject are referenced as:
* HKLM
* HKCR
* HKEY_USER

.EXAMPLE
C:\PS> New-SysmonRegistryFilter -Path .\32config.xml -OnMatch include -Condition Contains -EventField TargetObject 'RunOnce'
Capture persistance attemp by creating a registry entry in the RunOnce keys.
#>
function New-SysmonRegistryFilter {
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonRegistryFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({ Test-Path -Path $_ })]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch,

        # Condition for filtering against and event field.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
            'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
        [string]
        $Condition,

        # Event field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=3)]
        [ValidateSet('TargetObject', 'ProcessGuid', 'ProcessId',
            'Image', 'EventType')]
        [string]
        $EventField,

        # Value of Event Field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=4)]
        [string[]]
        $Value,

        # Rule Name for the filter.
        [Parameter(Mandatory=$false,
            ValueFromPipelineByPropertyName=$true)]
        [string]
        $RuleName
    )

    Begin {
        # Event types used to validate right type and string case
        $EventTypeMap = @{
            CreateKey = 'CreateKey'
            DeleteKey = 'DeleteKey'
            RenameKey = 'RenameKey'
            CreateValue = 'CreateValue'
            DeleteValue = 'DeleteValue'
            RenameValue = 'RenameValue'
            SetValue = 'SetValue'
        }

        $Etypes = $EventTypeMap.Keys
    }
    Process {
        $FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]

        if ($EventField -in 'EventType') {
            if ($Value -in $Etypes) {
                $Value = $EventTypeMap[$Value]
            } else {
                Write-Error -Message "Not a supported EventType. Supported Event types $($Etypes -join ', ')"
                return
            }
        }
        $cmdoptions = @{
            'EventType' =  'RegistryEvent'
            'Condition' = $Condition
            'EventField' = $FieldString
            'Value' = $Value
            'OnMatch' = $OnMatch

        }

        if($RuleName) {
            $cmdoptions.Add('RuleName',$RuleName)
        }

        switch ($PSCmdlet.ParameterSetName) {
            'Path' {
                $cmdOptions.Add('Path',$Path)
                New-RuleFilter @cmdOptions
            }

            'LiteralPath' {
                $cmdOptions.Add('LiteralPath',$LiteralPath)
                New-RuleFilter @cmdOptions
            }
        }
    }
    End {}
}

================================================
FILE: Functions/New-SysmonWmiFilter.ps1
================================================
<#
.SYNOPSIS
Create a new filter for WMI Permamanent Event Classes.
.DESCRIPTION
Create a new filter for WMI permamanent event classes are created or connected.
Useful for monitoring for persistence actions.
#>
function New-SysmonWmiFilter {
    [CmdletBinding(DefaultParameterSetName = 'Path',
    HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/New-SysmonWmiFilter.md')]
    Param (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Path',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='LiteralPath',
            Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type on match action.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=1)]
        [ValidateSet('include', 'exclude')]
        [string]
        $OnMatch,

        # Condition for filtering against and event field.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=2)]
        [ValidateSet('Is', 'IsNot', 'Contains', 'Excludes', 'Image',
            'BeginWith', 'EndWith', 'LessThan', 'MoreThan')]
        [string]
        $Condition,

        # Event field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=3)]
        [ValidateSet('Name', 'EventNamespace', 'Destination',
            'Type', 'Query', 'Operation', 'Consumer', 'Filter')]
        [string]
        $EventField,

        # Value of Event Field to filter on.
        [Parameter(Mandatory=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=4)]
        [string[]]
        $Value,

        # Rule Name for the filter.
        [Parameter(Mandatory=$false,
            ValueFromPipelineByPropertyName=$true)]
        [string]
        $RuleName
    )

    Begin {}
    Process {
        $FieldString = $MyInvocation.MyCommand.Module.PrivateData[$EventField]
        $cmdoptions = @{
            'EventType' =  'WmiEvent'
            'Condition' = $Condition
            'EventField' = $FieldString
            'Value' = $Value
            'OnMatch' = $OnMatch

        }

        if($RuleName) {
            $cmdoptions.Add('RuleName',$RuleName)
        }

        switch ($PSCmdlet.ParameterSetName) {
            'Path' {
                $cmdOptions.Add('Path',$Path)
                New-RuleFilter @cmdOptions
            }

            'LiteralPath' {
                $cmdOptions.Add('LiteralPath',$LiteralPath)
                New-RuleFilter @cmdOptions
            }
        }
    }
    End {}
}

================================================
FILE: Functions/Remove-SysmonRule.ps1
================================================
#  .ExternalHelp Posh-SysMon.psm1-Help.xml
function Remove-SysmonRule
{
    [CmdletBinding(DefaultParameterSetName = 'Path',
                   HelpUri = 'https://github.com/darkoperator/Posh-Sysmon/blob/master/docs/Remove-SysmonRule.md')]
    Param
    (
        # Path to XML config file.
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   ParameterSetName='Path',
                   Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        $Path,

        # Path to XML config file.
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   ParameterSetName='LiteralPath',
                   Position=0)]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('PSPath')]
        $LiteralPath,

        # Event type to remove. It is case sensitive.
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=1)]
        [ValidateSet('NetworkConnect', 'ProcessCreate', 'FileCreateTime',
                     'ProcessTerminate', 'ImageLoad', 'DriverLoad', 'CreateRemoteThread',
                     'ProcessAccess', 'RawAccessRead', 'FileCreateStreamHash',
                     'RegistryEvent', 'FileCreate', 'PipeEvent', 'WmiEvent','RuleName')]
        [string[]]
        $EventType,

        # Action for event type rule and filters.
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=2)]
        [ValidateSet('Include', 'Exclude')]
        [String]
        $OnMatch = 'Exclude'
    )

    Begin{}
    Process
    {
        # Check if the file is a valid XML file and if not raise and error.
        try
        {
            switch($psCmdlet.ParameterSetName)
            {
                'Path'
                {
                    [xml]$Config = Get-Content -Path $Path
                    $FileLocation = (Resolve-Path -Path $Path).Path
                }

                'LiteralPath'
                {
                    [xml]$Config = Get-Content -LiteralPath $LiteralPath
                    $FileLocation = (Resolve-Path -LiteralPath $LiteralPath).Path
                }
            }
        }
        catch [Management.Automation.PSInvalidCastException]
        {
            Write-Error -Message 'Specified file does not appear to be a XML file.'
            return
        }

        # Validate the XML file is a valid Sysmon file.
        if ($Config.SelectSingleNode('//Sysmon') -eq $null)
        {
            Write-Error -Message 'XML file is not a valid Sysmon config file.'
            return
        }

         if (
Download .txt
gitextract_jqcvzr7i/

├── .gitattributes
├── Config.ps1
├── Filters.ps1
├── Format/
│   ├── Sysmon.ConfigOption.ps1xml
│   ├── Sysmon.Rule.Filter.ps1xml
│   └── Sysmon.Rule.ps1xml
├── Functions/
│   ├── ConvertFrom-SysmonBinaryConfiguration.ps1
│   ├── ConvertTo-SysmonXMLConfiguration.ps1
│   ├── Get-SysmonConfiguration.ps1
│   ├── Get-SysmonEventData.ps1
│   ├── Get-SysmonHashingAlgorithm.ps1
│   ├── Get-SysmonRule.ps1
│   ├── Get-SysmonRuleFilter.ps1
│   ├── New-SysmonConfiguration.ps1
│   ├── New-SysmonCreateRemoteThreadFilter.ps1
│   ├── New-SysmonDriverLoadFilter.ps1
│   ├── New-SysmonFileCreateFilter.ps1
│   ├── New-SysmonFileCreateStreamHashFilter.ps1
│   ├── New-SysmonImageLoadFilter.ps1
│   ├── New-SysmonNetworkConnectFilter.ps1
│   ├── New-SysmonPipeFilter.ps1
│   ├── New-SysmonProcessAccessFilter.ps1
│   ├── New-SysmonProcessCreateFilter.ps1
│   ├── New-SysmonProcessTerminateFilter.ps1
│   ├── New-SysmonRawAccessReadFilter.ps1
│   ├── New-SysmonRegistryFilter.ps1
│   ├── New-SysmonWmiFilter.ps1
│   ├── Remove-SysmonRule.ps1
│   ├── Remove-SysmonRuleFilter.ps1
│   ├── Schemas/
│   │   ├── SysmonConfigurationSchema_3_40.xsd
│   │   └── SysmonConfigurationSchema_4_00.xsd
│   ├── Set-SysmonHashingAlgorithm.ps1
│   └── Set-SysmonRule.ps1
├── LICENSE
├── Posh-SysMon.psm1
├── Posh-Sysmon.psd1
├── README.md
├── build.ps1
├── docs/
│   ├── Get-SysmonEventData.md
│   ├── Get-SysmonHashingAlgorithm.md
│   ├── Get-SysmonRule.md
│   ├── Get-SysmonRuleFilter.md
│   ├── New-SysmonConfiguration.md
│   ├── New-SysmonDriverLoadFilter.md
│   ├── New-SysmonFileCreateFilter.md
│   ├── New-SysmonFileCreateStreamHash.md
│   ├── New-SysmonFileCreateStreamHashFilter.md
│   ├── New-SysmonImageLoadFilter.md
│   ├── New-SysmonNetworkConnectFilter.md
│   ├── New-SysmonPipeEvent.md
│   ├── New-SysmonPipeFilter.md
│   ├── New-SysmonProcessAccessFilter.md
│   ├── New-SysmonProcessCreateFilter.md
│   ├── New-SysmonProcessTerminateFilter.md
│   ├── New-SysmonRegistryEvent.md
│   ├── New-SysmonRegistryFilter.md
│   ├── Remove-SysmonRule.md
│   ├── Remove-SysmonRuleFilter.md
│   ├── Set-SysmonHashingAlgorithm.md
│   └── Set-SysmonRule.md
├── en-US/
│   ├── Posh-SysMon-help.xml
│   └── Posh-SysMon.psm1-Help.xml
└── lib/
    ├── sysmon3_1.dtd
    ├── sysmon3_2.dtd
    └── sysmon3_3.dtd
Condensed preview — 65 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (881K chars).
[
  {
    "path": ".gitattributes",
    "chars": 556,
    "preview": "# Auto detect text files and perform LF normalization\n* text=auto\n\n# Custom for Visual Studio\n*.cs     diff=csharp\n*.sln"
  },
  {
    "path": "Config.ps1",
    "chars": 30907,
    "preview": "\n#  .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction New-SysmonConfiguration\n{\n    [CmdletBinding(HelpUri = 'https://gi"
  },
  {
    "path": "Filters.ps1",
    "chars": 57322,
    "preview": "#  .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction New-SysmonImageLoadFilter {\n    [CmdletBinding(DefaultParameterSetN"
  },
  {
    "path": "Format/Sysmon.ConfigOption.ps1xml",
    "chars": 1141,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-16\"?>\n<Configuration>\n<ViewDefinitions>\n<View>\n    <Name>Sysmon.ConfigOption</Name>\n "
  },
  {
    "path": "Format/Sysmon.Rule.Filter.ps1xml",
    "chars": 1137,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-16\"?>\n<Configuration>\n<ViewDefinitions>\n<View>\n    <Name>Sysmon.Rule.Filter</Name>\n  "
  },
  {
    "path": "Format/Sysmon.Rule.ps1xml",
    "chars": 1127,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-16\"?>\n<Configuration>\n<ViewDefinitions>\n<View>\n    <Name>Sysmon.Rule</Name>\n    <View"
  },
  {
    "path": "Functions/ConvertFrom-SysmonBinaryConfiguration.ps1",
    "chars": 14443,
    "preview": "<#\n.SYNOPSIS\n\nParses a binary Sysmon configuration.\n\n.DESCRIPTION\n\nConvertFrom-SysmonBinaryConfiguration parses a binary"
  },
  {
    "path": "Functions/ConvertTo-SysmonXMLConfiguration.ps1",
    "chars": 8060,
    "preview": "<#\n.SYNOPSIS\n\nRecovers a Sysmon XML configuration from a binary configuration.\n\n.DESCRIPTION\n\nConvertTo-SysmonXMLConfigu"
  },
  {
    "path": "Functions/Get-SysmonConfiguration.ps1",
    "chars": 10129,
    "preview": "<#\n.SYNOPSIS\n\nParses a Sysmon driver configuration from the registry. Output is nearly identical to that of \"sysmon.exe "
  },
  {
    "path": "Functions/Get-SysmonEventData.ps1",
    "chars": 5924,
    "preview": "<#\n.Synopsis\nSearches for specified SysMon Events and retunrs the Event Data as a custom object.\n.DESCRIPTION\nSearches f"
  },
  {
    "path": "Functions/Get-SysmonHashingAlgorithm.ps1",
    "chars": 2326,
    "preview": "#  .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction Get-SysmonHashingAlgorithm\n{\n    [CmdletBinding(DefaultParameterSetN"
  },
  {
    "path": "Functions/Get-SysmonRule.ps1",
    "chars": 3376,
    "preview": "#  .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction Get-SysmonRule\n{\n    [CmdletBinding(DefaultParameterSetName = 'Path'"
  },
  {
    "path": "Functions/Get-SysmonRuleFilter.ps1",
    "chars": 5764,
    "preview": "<#\n.SYNOPSIS\nGet the configured filters for a specified Event Type Rule in a Sysmon configuration file.\n.DESCRIPTION\nGet"
  },
  {
    "path": "Functions/New-SysmonConfiguration.ps1",
    "chars": 10576,
    "preview": "#  .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction New-SysmonConfiguration\n{\n    [CmdletBinding(HelpUri = 'https://gith"
  },
  {
    "path": "Functions/New-SysmonCreateRemoteThreadFilter.ps1",
    "chars": 2732,
    "preview": "#  .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction New-SysmonCreateRemoteThreadFilter {\n    [CmdletBinding(DefaultParam"
  },
  {
    "path": "Functions/New-SysmonDriverLoadFilter.ps1",
    "chars": 2749,
    "preview": "#  .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction New-SysmonDriverLoadFilter {\n    [CmdletBinding(DefaultParameterSetN"
  },
  {
    "path": "Functions/New-SysmonFileCreateFilter.ps1",
    "chars": 2819,
    "preview": "#  .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction New-SysmonFileCreateFilter {\n    [CmdletBinding(DefaultParameterSetN"
  },
  {
    "path": "Functions/New-SysmonFileCreateStreamHashFilter.ps1",
    "chars": 2912,
    "preview": "<#\n.SYNOPSIS\nCreate a new filter for the logging of the saving of data on a file stream.\n.DESCRIPTION\nCreate a new filte"
  },
  {
    "path": "Functions/New-SysmonImageLoadFilter.ps1",
    "chars": 3501,
    "preview": "#  .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction New-SysmonImageLoadFilter {\n    [CmdletBinding(DefaultParameterSetNa"
  },
  {
    "path": "Functions/New-SysmonNetworkConnectFilter.ps1",
    "chars": 3011,
    "preview": "#  .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction New-SysmonNetworkConnectFilter\n{\n    [CmdletBinding(DefaultParameter"
  },
  {
    "path": "Functions/New-SysmonPipeFilter.ps1",
    "chars": 2899,
    "preview": "<#\n.SYNOPSIS\nCreate a new filter for when a Named Pipe is created or connected.\n.DESCRIPTION\nCreate a new filter for whe"
  },
  {
    "path": "Functions/New-SysmonProcessAccessFilter.ps1",
    "chars": 3216,
    "preview": "<#\n.SYNOPSIS\nCreate a new filter for the logging of when a running process opens another.\n.DESCRIPTION\nCreate a new filt"
  },
  {
    "path": "Functions/New-SysmonProcessCreateFilter.ps1",
    "chars": 3625,
    "preview": "#  .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction New-SysmonProcessCreateFilter\n{\n    [CmdletBinding(DefaultParameterS"
  },
  {
    "path": "Functions/New-SysmonProcessTerminateFilter.ps1",
    "chars": 2770,
    "preview": "#  .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction New-SysmonProcessTerminateFilter\n{\n    [CmdletBinding(DefaultParamet"
  },
  {
    "path": "Functions/New-SysmonRawAccessReadFilter.ps1",
    "chars": 3060,
    "preview": "<#\n.SYNOPSIS\nCreate a new filter for the logging of file raw access read actions.\n.DESCRIPTION\nCreate a new filter for t"
  },
  {
    "path": "Functions/New-SysmonRegistryFilter.ps1",
    "chars": 4275,
    "preview": "<#\n.SYNOPSIS\nCreate a new filter for the actions against the registry.\n.DESCRIPTION\nCreate a new filter for actions agai"
  },
  {
    "path": "Functions/New-SysmonWmiFilter.ps1",
    "chars": 2935,
    "preview": "<#\n.SYNOPSIS\nCreate a new filter for WMI Permamanent Event Classes.\n.DESCRIPTION\nCreate a new filter for WMI permamanent"
  },
  {
    "path": "Functions/Remove-SysmonRule.ps1",
    "chars": 3321,
    "preview": "#  .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction Remove-SysmonRule\n{\n    [CmdletBinding(DefaultParameterSetName = 'Pa"
  },
  {
    "path": "Functions/Remove-SysmonRuleFilter.ps1",
    "chars": 7516,
    "preview": "#  .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction Remove-SysmonRuleFilter {\n    [CmdletBinding(DefaultParameterSetName"
  },
  {
    "path": "Functions/Schemas/SysmonConfigurationSchema_3_40.xsd",
    "chars": 35603,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xs:schema targetNamespace=\"urn:schemas-specterops.io:SysmonConfiguration\"\n    e"
  },
  {
    "path": "Functions/Schemas/SysmonConfigurationSchema_4_00.xsd",
    "chars": 36579,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xs:schema targetNamespace=\"urn:schemas-specterops.io:SysmonConfiguration\"\n    e"
  },
  {
    "path": "Functions/Set-SysmonHashingAlgorithm.ps1",
    "chars": 3267,
    "preview": "#  .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction Set-SysmonHashingAlgorithm\n{\n    [CmdletBinding(DefaultParameterSetN"
  },
  {
    "path": "Functions/Set-SysmonRule.ps1",
    "chars": 6236,
    "preview": "#  .ExternalHelp Posh-SysMon.psm1-Help.xml\nfunction Set-SysmonRule\n{\n    [CmdletBinding(DefaultParameterSetName = 'Path'"
  },
  {
    "path": "LICENSE",
    "chars": 1482,
    "preview": "Copyright (c) 2016, Carlos Perez\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or withou"
  },
  {
    "path": "Posh-SysMon.psm1",
    "chars": 11789,
    "preview": "\n# Load functions\n . \"$($PSScriptRoot)\\Functions\\Get-SysmonEventData.ps1\"\n . \"$($PSScriptRoot)\\Functions\\Get-SysmonHash"
  },
  {
    "path": "Posh-Sysmon.psd1",
    "chars": 9566,
    "preview": "#\n# Module manifest for module 'PSGet_Posh-Sysmon'\n#\n# Generated by: Carlos Perez carlos_Perez@darkoperator.com\n#\n# Gene"
  },
  {
    "path": "README.md",
    "chars": 9478,
    "preview": "# Posh-Sysmon\nPowerShell 3.0 or above module for creating and managing Sysinternals Sysmon v2.0 config files. System Mon"
  },
  {
    "path": "build.ps1",
    "chars": 1097,
    "preview": "[CmdletBinding()]\nparam(\n    [ValidateSet(\"Release\",\"Debug\")]\n    $Configuration = \"Release\"\n)\n\nPush-Location $PSScriptR"
  },
  {
    "path": "docs/Get-SysmonEventData.md",
    "chars": 2986,
    "preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version:\nschema: 2.0.0\n---\n\n# Get-SysmonEve"
  },
  {
    "path": "docs/Get-SysmonHashingAlgorithm.md",
    "chars": 1721,
    "preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
  },
  {
    "path": "docs/Get-SysmonRule.md",
    "chars": 2180,
    "preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
  },
  {
    "path": "docs/Get-SysmonRuleFilter.md",
    "chars": 2139,
    "preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
  },
  {
    "path": "docs/New-SysmonConfiguration.md",
    "chars": 6289,
    "preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
  },
  {
    "path": "docs/New-SysmonDriverLoadFilter.md",
    "chars": 3318,
    "preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
  },
  {
    "path": "docs/New-SysmonFileCreateFilter.md",
    "chars": 2839,
    "preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
  },
  {
    "path": "docs/New-SysmonFileCreateStreamHash.md",
    "chars": 2385,
    "preview": "---\nexternal help file: Posh-SysMon-help.xml\nonline version: \nschema: 2.0.0\n---\n\n# New-SysmonFileCreateStreamHash\n\n## SY"
  },
  {
    "path": "docs/New-SysmonFileCreateStreamHashFilter.md",
    "chars": 2996,
    "preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
  },
  {
    "path": "docs/New-SysmonImageLoadFilter.md",
    "chars": 3387,
    "preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
  },
  {
    "path": "docs/New-SysmonNetworkConnectFilter.md",
    "chars": 3521,
    "preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
  },
  {
    "path": "docs/New-SysmonPipeEvent.md",
    "chars": 2214,
    "preview": "---\nexternal help file: Posh-SysMon-help.xml\nonline version: \nschema: 2.0.0\n---\n\n# New-SysmonPipeEvent\n\n## SYNOPSIS\nCrea"
  },
  {
    "path": "docs/New-SysmonPipeFilter.md",
    "chars": 2991,
    "preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
  },
  {
    "path": "docs/New-SysmonProcessAccessFilter.md",
    "chars": 3065,
    "preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
  },
  {
    "path": "docs/New-SysmonProcessCreateFilter.md",
    "chars": 3521,
    "preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
  },
  {
    "path": "docs/New-SysmonProcessTerminateFilter.md",
    "chars": 3338,
    "preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
  },
  {
    "path": "docs/New-SysmonRegistryEvent.md",
    "chars": 2517,
    "preview": "---\nexternal help file: Posh-SysMon-help.xml\nonline version: \nschema: 2.0.0\n---\n\n# New-SysmonRegistryEvent\n\n## SYNOPSIS\n"
  },
  {
    "path": "docs/New-SysmonRegistryFilter.md",
    "chars": 3533,
    "preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
  },
  {
    "path": "docs/Remove-SysmonRule.md",
    "chars": 2523,
    "preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
  },
  {
    "path": "docs/Remove-SysmonRuleFilter.md",
    "chars": 3458,
    "preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
  },
  {
    "path": "docs/Set-SysmonHashingAlgorithm.md",
    "chars": 2100,
    "preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
  },
  {
    "path": "docs/Set-SysmonRule.md",
    "chars": 2799,
    "preview": "---\nexternal help file: Posh-SysMon-help.xml\nModule Name: Posh-SysMon\nonline version: https://github.com/darkoperator/Po"
  },
  {
    "path": "en-US/Posh-SysMon-help.xml",
    "chars": 322468,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<helpItems schema=\"maml\" xmlns=\"http://msh\">\n  <command:command xmlns:maml=\"http"
  },
  {
    "path": "en-US/Posh-SysMon.psm1-Help.xml",
    "chars": 111095,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<helpItems xmlns=\"http://msh\" schema=\"maml\">\n\n<command:command xmlns:maml=\"http:"
  },
  {
    "path": "lib/sysmon3_1.dtd",
    "chars": 6764,
    "preview": "<!ELEMENT Sysmon (EventFiltering|HashAlgorithms|ProcessAccessConfig|CheckRevocation)*>\n<!ATTLIST Sysmon schemaversion CD"
  },
  {
    "path": "lib/sysmon3_2.dtd",
    "chars": 8158,
    "preview": "<!ELEMENT Sysmon (EventFiltering|HashAlgorithms|ProcessAccessConfig|CheckRevocation)*>\n<!ATTLIST Sysmon schemaversion CD"
  },
  {
    "path": "lib/sysmon3_3.dtd",
    "chars": 8494,
    "preview": "<!ELEMENT Sysmon (EventFiltering|HashAlgorithms|ProcessAccessConfig|CheckRevocation|PipeMonitoringConfig)*>\n<!ATTLIST Sy"
  }
]

About this extraction

This page contains the full source code of the darkoperator/Posh-Sysmon GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 65 files (822.3 KB), approximately 210.7k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!