Author Posts

September 24, 2015 at 8:58 am

I got a little further having trouble get the data into a csv. Would appreciate any help!

$evt = Get-Eventlog -ComputerName sql -LogName Security  -InstanceId 5145 -after (Get-date).AddDays(-7)
foreach ($evt in $evts) {

Get-Eventlog -ComputerName sql -LogName Security  -InstanceId 5145 %{ 

   
    $timecreated = $_.TimeGenerated.DateTime
    $accountname =$_.ReplacementStrings[1]
    $objectype = $_.ReplacementStrings[4]
    $hostip = $_.ReplacementStrings[5]
    $filelocation =$_.ReplacementStrings[8]
    $whatfile = $_.ReplacementStrings[9]
    $whappend = $_.ReplacementStrings[10] `
   -Replace "0x100000", "Write Access (Synchronize)" `
   -Replace "0x80000", "Change Ownership" `
   -Replace "0x40000", "Modify Security" `
   -Replace "0x20000", "Read Access (Security)" `
   -Replace "0x10000", "Delete operation" `
   -Replace "0x100", "Write Access (Attributes)" `
   -Replace "0x80", "Read Access (Attributes)" `
   -Replace "0x40","Delete operation" `
   -Replace "0x20", "Read operation" `
   -Replace "0x10", "Write operation (Attributes)" `
   -Replace "0x8", "Read operation (Attributes)" `
   -Replace "0x4", "Write operation (Append)" `
   -Replace "0x2", "Write operation" `
   -Replace "0x1", "Write operation" `
   -Replace "0x0", "Read operation"

   $auditevent = New-Object System.Object
   $auditevent | Add-Member -Type NoteProperty -Name Time Created -SecondValue $timecreated
   $auditevent | Add-Member -type NoteProperty -Name UserName -SecondValue $accountname
   $auditevent | Add-Member -type NoteProperty -Name Object -SecondValue $objectype
   $auditevent | Add-Member -type NoteProperty -Name HostIP -SecondValue $hostip
   $auditevent | Add-Member -type NoteProperty -Name FileLocation -SecondValue $filelocation
   $auditevent | Add-Member -type NoteProperty -Name WhatFile -SecondValue $whatfile
   $auditevent | Add-Member -type NoteProperty -Name WhatHappened -SecondValue $whappend
  
    } 
    }

September 24, 2015 at 10:04 am

Here's a snippet that gets rids of all those serial replacements (as you're only going to do one replace per item) based on a hash table lookup.

$code = @{
   "0x100000" = "Write Access (Synchronize)"
   "0x80000" = "Change Ownership"
   "0x40000" = "Modify Security"
   "0x20000" = "Read Access (Security)"
   "0x10000" = "Delete operation"
   "0x100" = "Write Access (Attributes)"
   "0x80" = "Read Access (Attributes)"
   "0x40" = "Delete operation"
   "0x20" = "Read operation"
   "0x10" = "Write operation (Attributes)"
   "0x8" = "Read operation (Attributes)"
   "0x4" = "Write operation (Append)"
   "0x2" = "Write operation"
   "0x1" = "Write operation"
   "0x0" = "Read operation"
}

$replacementString10 = "0x80"
$text = $code[$replacementString10]
"The event text is $text"

September 24, 2015 at 10:06 am

#Create Array to hold results:
$ObjArray = @()

Get-Eventlog -ComputerName sql -LogName Security  -InstanceId 5145 -Newest 100  | %{ 

#Create a new object for every event so we can trap data
$ObjData = New-Object System.Object

#Each value needs to be added to the array.  I picked ID1 through ID7 just to have a property name   
$ObjData | Add-Member -type NoteProperty -name ID1 -value $_.TimeGenerated.DateTime
$ObjData | Add-Member -type NoteProperty -name ID2 -value $_.ReplacementStrings[1]
$ObjData | Add-Member -type NoteProperty -name ID3 -value $_.ReplacementStrings[4]
$ObjData | Add-Member -type NoteProperty -name ID4 -value $_.ReplacementStrings[5]
$ObjData | Add-Member -type NoteProperty -name ID5 -value $_.ReplacementStrings[8]
$ObjData | Add-Member -type NoteProperty -name ID6 -value $_.ReplacementStrings[9]
$ObjData | Add-Member -type NoteProperty -name ID7 -value $_.ReplacementStrings[10] `
   -Replace "0x100000", "Write Access (Synchronize)" `
   -Replace "0x80000", "Change Ownership" `
   -Replace "0x40000", "Modify Security" `
   -Replace "0x20000", "Read Access (Security)" `
   -Replace "0x10000", "Delete operation" `
   -Replace "0x100", "Write Access (Attributes)" `
   -Replace "0x80", "Read Access (Attributes)" `
   -Replace "0x40","Delete operation" `
   -Replace "0x20", "Read operation" `
   -Replace "0x10", "Write operation (Attributes)" `
   -Replace "0x8", "Read operation (Attributes)" `
   -Replace "0x4", "Write operation (Append)" `
   -Replace "0x2", "Write operation" `
   -Replace "0x1", "Write operation" `
   -Replace "0x0", "Read operation"

   #Add the completed single entry into the Array/Table
   $objArray += $ObjData
    }

#Output the completed Array to CSV (-NoTypeInformation is added to strip off the junk at the top)
$ObjArray | Export-Csv C:\Temp\MyOutput.csv -NoTypeInformation

September 24, 2015 at 10:19 am

You spend a lot of time generating intermediate results and then do a lot of unnecessary Add-Member. Try this on for size. I can't verify since I don't seem to have server generating that event.

$code = @{
   "0x100000" = "Write Access (Synchronize)"
    "0x80000" = "Change Ownership"
    "0x40000" = "Modify Security"
    "0x20000" = "Read Access (Security)"
    "0x10000" = "Delete operation"
      "0x100" = "Write Access (Attributes)"
       "0x80" = "Read Access (Attributes)"
       "0x40" = "Delete operation"
       "0x20" = "Read operation"
       "0x10" = "Write operation (Attributes)"
        "0x8" = "Read operation (Attributes)"
        "0x4" = "Write operation (Append)"
        "0x2" = "Write operation"
        "0x1" = "Write operation"
        "0x0" = "Read operation"
}
$results = Get-Eventlog -ComputerName sql -LogName Security  -InstanceId 5145 -after (Get-date).AddDays(-7) | foreach {

    [PSCustomObject]@{
        TimeCreated = $_.TimeGenerated.DateTime
        UserName =$_.ReplacementStrings[1]
        Object = $_.ReplacementStrings[4]
        HostIP = $_.ReplacementStrings[5]
        FileLocation = $_.ReplacementStrings[8]
        WhatFile = $_.ReplacementStrings[9]
        WhatHappened = $code[$_.ReplacementStrings[10]]
    }
}

# Sample outputs - pick one or more, your choice
$results
$results | Format-Table -AutoSize
$results | Out-GridView
$results | Export-Csv -Path .\foo.csv -NoTypeInformation -Encoding ASCII
$results | Out-File -FilePath .\foo.txt -Encoding ASCII
$results | Export-Clixml -Path .\foo.xml -Encoding ASCII

September 24, 2015 at 10:26 am

Totally agree Bob, your way is cleaner and now I have a reason to go back and update all my old scripts! haha. I've been doing it that old way for years. Thanks!

Brian

September 24, 2015 at 10:31 am

It seems to be a common approach to create an empty object and then do a bunch of Add-Member. It's WAY more efficient to create a hash and then create (touch) the object once. I typically only use Add-Member for existing objects that I want to add additional properties, e.g., file system objects or process objects.

The other thing to keep in mind is that there is no true append to an array in PowerShell. So the "+=" operation ends up having to recreate the entire array every time it's used. Needless to say, that can get expensive (read that as slow) as the array grows.

September 24, 2015 at 10:39 am

Thank you, bob and brian. Your knowledge is valuable beyond belief. Again Thanks!

September 24, 2015 at 10:45 am

Now Bob when I run the code the "what happened" field doesn't populate with any data. I presume the way we are replace the value in string 10 isn't correct? Only the read access shows up in the csv.

September 24, 2015 at 11:02 am

Are you running the fuller (later) example. The snippet above it was hardcoded to 0x80 (Read Access) just for an example of how to access the value in a has table. That makes me wonder if you copied from the later code.

September 24, 2015 at 11:05 am

Just to be sure we aren't seeing an artifact from a previous run, change the last line of the splat to ...

WhatHappened = $code[$($_.ReplacementStrings[10])]

September 24, 2015 at 11:40 am

Ok I the code to do the -replace after string 10 and it made it work.


$results = Get-Eventlog -ComputerName sql -LogName Security  -InstanceId 5145 -after (Get-date).AddDays(-1) | foreach {

    [PSCustomObject]@{
        TimeCreated = $_.TimeGenerated.DateTime
        UserName =$_.ReplacementStrings[1]
        Object = $_.ReplacementStrings[4]
        HostIP = $_.ReplacementStrings[5]
        FileLocation = $_.ReplacementStrings[8]
        WhatFile = $_.ReplacementStrings[9]
       WhatHappened = $_.ReplacementStrings[10]`
                        -Replace "0x100000", "Write Access (Synchronize)" `
                        -Replace "0x80000", "Change Ownership" `
                        -Replace "0x40000", "Modify Security" `
                        -Replace "0x20000", "Read Access (Security)" `
                        -Replace "0x10000", "Delete operation" `
                        -Replace "0x100", "Write Access (Attributes)" `
                        -Replace "0x80", "Read Access (Attributes)" `
                        -Replace "0x40","Delete operation" `
                        -Replace "0x20", "Read operation" `
                        -Replace "0x10", "Write operation (Attributes)" `
                        -Replace "0x8", "Read operation (Attributes)" `
                        -Replace "0x4", "Write operation (Append)" `
                        -Replace "0x2", "Write operation" `
                        -Replace "0x1", "Write operation" `
                        -Replace "0x0", "Read operation"
    }
}

# Sample outputs - pick one or more, your choice
#$results
#$results | Format-Table -AutoSize
#$results | Out-GridView
$results | Export-Csv -Path .\foo.csv -NoTypeInformation -Encoding ASCII
#$results | Out-File -FilePath .\foo.txt -Encoding ASCII
#$results | Export-Clixml -Path .\foo.xml -Encoding ASCII

September 24, 2015 at 11:45 am

Delete operations don't populate though. Not sure why

September 24, 2015 at 11:58 am

0xc0080
Read operation080
Write operation7019f
Write operation30089
Write operation30089
0xc0080
Read operation080
Read Access (Attributes)
Write operation30197
Write operation30197

I get data for example that look like this.

September 24, 2015 at 12:25 pm

Can you attach a screenshot or a copy/paste of the entire event from EventViewer (block out any proprietary info you don't want shared) so we can see what it's trying to parse out? We don't have that advanced file auditing turned on here so i have no 5145's to go by so i can try this.

September 24, 2015 at 12:30 pm

A network share object was checked to see whether client can be granted desired access.

Subject:
Security ID: BRAENSTONE\JessicaP
Account Name: JessicaP
Account Domain: BRAENSTONE
Logon ID: 0x3F786A5E

Network Information:
Object Type: File
Source Address: XXXXXXXX (hidden)
Source Port: 54887

Share Information:
Share Name: \\*\Zdrive
Share Path: \??\C:\Zdrive
Relative Target Name: JessicaP\1. Projects\Stone\2014-6-17 STONE-0013 Lancaster Farming Advertisement\STONE-0013 Lancaster Farming Tear Sheet 4-4-15.pdf

Access Request Information:
Access Mask: 0x80
Accesses: ReadAttributes

Access Check Results:
ReadAttributes: Granted by D:(A;;FA;;;DU)

September 24, 2015 at 12:52 pm

37mm, I would take a slightly different approach using Get-WinEvent instead of Get-EventLog. With Get-WinEvent you can convert it the event into XML for manipulation. It also seems to run faster than Get-EventLog for me remotely. I definately think Bob's approach of using a hashtable instead of a bunch of string replacements is the better of the two options. You are, however, going to have to build up your hash table over time just as you would your string replacements. The list you have is far from complete, as you can see in the results below, two of the returned code do not have matching text values from the hashtable. In fact, the first result did not either, I had to add it so it would show in the example output.

$codes = @{
   "0x100080" = "Read Attributes (Synchronize)"
   "0x100000" = "Write Access (Synchronize)"
   "0x80000" = "Change Ownership"
   "0x40000" = "Modify Security"
   "0x20000" = "Read Access (Security)"
   "0x10000" = "Delete operation"
   "0x100" = "Write Access (Attributes)"
   "0x80" = "Read Access (Attributes)"
   "0x40" = "Delete operation"
   "0x20" = "Read operation"
   "0x10" = "Write operation (Attributes)"
   "0x8" = "Read operation (Attributes)"
   "0x4" = "Write operation (Append)"
   "0x2" = "Write operation"
   "0x1" = "Write operation"
   "0x0" = "Read operation"
}

$Events = Get-WinEvent -ComputerName server1 -FilterHashtable @{LogName="Security"; ID=5145}

Foreach ($Event in $Events) {
    $EventDataXML = ([xml]$Event.ToXML()).Event.EventData.Data
    [PSCustomObject]@{
        TimeCreated = $Event.TimeCreated;
        UserName = ($EventDataXML | Where-Object {$_.Name -eq 'SubjectUserName'}).'#text';
        Object = ($EventDataXML | Where-Object {$_.Name -eq 'ObjectName'}).'#text';
        HostIP = ($EventDataXML | Where-Object {$_.Name -eq 'SourceAddress'}).'#text';
        FileLocation = ($EventDataXML | Where-Object {$_.Name -eq 'ShareName'}).'#text';
        WhatFile = ($EventDataXML | Where-Object {$_.Name -eq 'ShareLocalPath'}).'#text';
        WhatHappenedCode = ($EventDataXML | Where-Object {$_.Name -eq 'AccessMask'}).'#text';
        WhatHappenedText = $codes[($EventDataXML | Where-Object {$_.Name -eq 'AccessMask'}).'#text']
    }#pscustomobject
}#foreach 

Results
`
TimeCreated : 9/24/2015 3:05:37 PM
UserName : user1
Object :
HostIP :
FileLocation : \\*\test$
WhatFile : \??\C:\Users\Public\Desktop\Automation
WhatHappenedCode : 0x100080
WhatHappenedText : Read Attributes (Synchronize)

TimeCreated : 9/24/2015 3:04:27 PM
UserName : user2
Object :
HostIP :
FileLocation : \\*\IPC$
WhatFile :
WhatHappenedCode : 0x12019f
WhatHappenedText :

TimeCreated : 9/24/2015 3:04:27 PM
UserName : user2
Object :
HostIP :
FileLocation : \\*\IPC$
WhatFile :
WhatHappenedCode : 0x12019f
WhatHappenedText :
`

September 24, 2015 at 1:00 pm

Correct, that is what is being done here


WhatHappenedText = $codes[($EventDataXML | Where-Object {$_.Name -eq 'AccessMask'}).'#text']

($EventDataXML | Where-Object {$_.Name -eq 'AccessMask'}).'#text' returns the value that is stored in the "AccessMask" field in the message of the event, so essentially our result is


WhatHappenedText = $codes[AccessMaskValue]

Ex:
WhatHappenedText = $codes["0x100000"]

Since $codes is a hashtable, and you are passing in a name of "0x100000" it results in

WhatHappendText = "Write Access (Synchronize)"

September 24, 2015 at 1:09 pm

Ok. I will work on getting this together and filling out the hash table. Thanks for the help Curtis!

September 24, 2015 at 1:16 pm

I might just be tired here, but the list he has is complete as far as the way it's listed on the Microsoft site. What i may be missing here is maybe those AccessMasks can be added together to form the value? Not sure where 0x1209f comes from.

https://msdn.microsoft.com/en-us/library/windows/desktop/aa822867(v=vs.85).aspx

September 24, 2015 at 1:20 pm

Yes, the property is a bitmap, so it is a conglomeration of all of the different masks together. In the first result "0x100080" is the result of "FILE_READ_ATTRIBUTES (0x80) and "SYNCHRONIZE (0x100000)"

0x12019f is:
Access Request Information:
Access Mask: 0x12019f
Accesses: READ_CONTROL
SYNCHRONIZE
ReadData (or ListDirectory)
WriteData (or AddFile)
AppendData (or AddSubdirectory or CreatePipeInstance)
ReadEA
WriteEA
ReadAttributes
WriteAttributes

September 24, 2015 at 1:23 pm

Ahh ok. That makes complete sense. So yeah... time to maybe run a script to come up with all possible options. That's rough though, because many of them won't ever happen if you do that.

September 24, 2015 at 7:08 pm

Hey 37mm, this should help. Instead of having to build out a static list of all of the combinations, I created a function called "Expand-AccessRights" that will convert your AccessMask into an array containing all of the Access Rights the mask represents. I then use this function to populate the "WhatHappenedText" property of the custom object. Hope this helps.

Function Expand-AccessRights {
    [CmdLetBinding()]
    Param (
       [int]$AccessMask 
    )#param

    $AccessRightsConstants = @(
        (0x1, "FILE_READ_DATA, FILE_LIST_DIRECTORY"),
        (0x2, "FILE_WRITE_DATA, FILE_ADD_FILE"),
        (0x4, "FILE_APPEND_DATA, FILE_ADD_SUBDIRECTORY"),
        (0x8, "FILE_READ_EA"),
        (0x10, "FILE_WRITE_EA"),
        (0x20, "FILE_EXECUTE, FILE_TRAVERSE"),
        (0x40, "FILE_DELETE_CHILD"),
        (0x80, "FILE_READ_ATTRIBUTES"),
        (0x100, "FILE_WRITE_ATTRIBUTES"),
        (0x10000, "DELETE"),
        (0x20000, "READ_CONTROL"),
        (0x40000, "WRITE_DAC"),
        (0x80000, "WRITE_OWNER"),
        (0x100000, "SYNCHRONIZE")
    )

    ($AccessRightsConstants.Count - 1) .. 0 | ForEach-Object {
        If ($AccessRightsConstants[$_][0] -le $AccessMask) {
            $AccessRights += @($AccessRightsConstants[$_][1])
            $AccessMask = $AccessMask - $AccessRightsConstants[$_][0]
        }#if
    }#foreach
    $AccessRights
}#function

$Events = Get-WinEvent -ComputerName server1 -FilterHashtable @{LogName="Security"; ID=5145}

Foreach ($Event in $Events) {
    $EventDataXML = ([xml]$Event.ToXML()).Event.EventData.Data
    [PSCustomObject]@{
        TimeCreated = $Event.TimeCreated;
        UserName = ($EventDataXML | Where-Object {$_.Name -eq 'SubjectUserName'}).'#text';
        Object = ($EventDataXML | Where-Object {$_.Name -eq 'ObjectType'}).'#text';
        HostIP = ($EventDataXML | Where-Object {$_.Name -eq 'IpAddress'}).'#text';
        FileLocation = ($EventDataXML | Where-Object {$_.Name -eq 'ShareName'}).'#text';
        WhatFile = ($EventDataXML | Where-Object {$_.Name -eq 'ShareLocalPath'}).'#text';
        WhatHappenedCode = ($EventDataXML | Where-Object {$_.Name -eq 'AccessMask'}).'#text';
        WhatHappenedText = Expand-AccessRights -AccessMask ($EventDataXML | Where-Object {$_.Name -eq 'AccessMask'}).'#text'
    }#pscustomobject
}#foreach

Results:

TimeCreated      : 9/24/2015 10:00:20 PM
UserName         : user1
Object           : File
HostIP           : 111.111.111.111
FileLocation     : \\*\IPC$
WhatFile         : 
WhatHappenedCode : 0x12019f
WhatHappenedText : {SYNCHRONIZE, READ_CONTROL, FILE_WRITE_ATTRIBUTES, FILE_READ_ATTRIBUTES...}

TimeCreated      : 9/24/2015 10:00:19 PM
UserName         : user1
Object           : File
HostIP           : 111.11.111.111
FileLocation     : \\*\test$
WhatFile         : \??\C:\Users\Public\Desktop\Automation
WhatHappenedCode : 0x100081
WhatHappenedText : {SYNCHRONIZE, FILE_READ_ATTRIBUTES, FILE_READ_DATA, FILE_LIST_DIRECTORY}

TimeCreated      : 9/24/2015 10:00:19 PM
UserName         : user1
Object           : File
HostIP           : 111.111.111.111
FileLocation     : \\*\test$
WhatFile         : \??\C:\Users\Public\Desktop\Automation
WhatHappenedCode : 0x120089
WhatHappenedText : {SYNCHRONIZE, READ_CONTROL, FILE_READ_ATTRIBUTES, FILE_READ_EA...}

TimeCreated      : 9/24/2015 10:00:19 PM
UserName         : user1
Object           : File
HostIP           : 111.111.111.111
FileLocation     : \\*\test$
WhatFile         : \??\C:\Users\Public\Desktop\Automation
WhatHappenedCode : 0x100081
WhatHappenedText : {SYNCHRONIZE, FILE_READ_ATTRIBUTES, FILE_READ_DATA, FILE_LIST_DIRECTORY}

TimeCreated      : 9/24/2015 10:00:19 PM
UserName         : user1
Object           : File
HostIP           : 111.111.111.111
FileLocation     : \\*\IPC$
WhatFile         : 
WhatHappenedCode : 0x12019f
WhatHappenedText : {SYNCHRONIZE, READ_CONTROL, FILE_WRITE_ATTRIBUTES, FILE_READ_ATTRIBUTES...}

TimeCreated      : 9/24/2015 10:00:19 PM
UserName         : user1
Object           : File
HostIP           : 111.111.111.111
FileLocation     : \\*\test$
WhatFile         : \??\C:\Users\Public\Desktop\Automation
WhatHappenedCode : 0x100080
WhatHappenedText : {SYNCHRONIZE, FILE_READ_ATTRIBUTES}

TimeCreated      : 9/24/2015 10:00:05 PM
UserName         : user1
Object           : File
HostIP           : ::1
FileLocation     : \\*\test$
WhatFile         : \??\C:\Users\Public\Desktop\Automation
WhatHappenedCode : 0x100080
WhatHappenedText : {SYNCHRONIZE, FILE_READ_ATTRIBUTES}

TimeCreated      : 9/24/2015 10:00:05 PM
UserName         : user1
Object           : File
HostIP           : ::1
FileLocation     : \\*\test$
WhatFile         : \??\C:\Users\Public\Desktop\Automation
WhatHappenedCode : 0x100080
WhatHappenedText : {SYNCHRONIZE, FILE_READ_ATTRIBUTES}

September 24, 2015 at 7:32 pm

That is a great solution to the problem! Basically 99% of the way. amazing

September 24, 2015 at 10:40 pm

instead of Expand-AccessRights may be just use
[System.Security.AccessControl.FileSystemRights] (for simplicity 😉 ? )


PS D:\> [System.Security.AccessControl.FileSystemRights]0x10080
ReadAttributes, Delete
PS D:\> [System.Security.AccessControl.FileSystemRights]0x12019f
Write, Read, Synchronize

September 25, 2015 at 11:06 am

Very Nice Max. Didn't know that was out there.

September 25, 2015 at 1:00 pm



$AuditEvents = @();

Get-WinEvent -ComputerName sql -FilterHashTable @{ LogName ="Security"; ID = 5145 } -MaxEvents 100 | %{

$AccessListDesc = [System.Security.AccessControl.FileSystemRights]($_.Properties[10].Value)

   $auditevent = New-Object System.Object
   $auditevent | Add-Member -Type NoteProperty -Name TimeCreated -Value $_.TimeCreated.ToString("o") # output in sortable format
   $auditevent | Add-Member -type NoteProperty -Name UserName -Value $_.Properties[1].Value # username
   $auditevent | Add-Member -type NoteProperty -Name Object -Value $_.Properties[4].Value # Object Type
   $auditevent | Add-Member -type NoteProperty -Name HostIP -Value  $_.Properties[5].Value # originating IP
   $auditevent | Add-Member -type NoteProperty -Name ShareName -Value $_.Properties[8].Value # Share name
   $auditevent | Add-Member -type NoteProperty -Name ShareLocalPath -Value $_.Properties[9].Value # Share local path
   $auditevent | Add-Member -type NoteProperty -Name WhatHappened -Value $AccessListDesc # access List


   $AuditEvents += $auditEvent
}

$auditevents | Export-Csv -Path .\foo.csv -NoTypeInformation -Encoding ASCII

September 25, 2015 at 1:08 pm

[System.Security.AccessControl.FileSystemRights] the problem with this is it doesn't tell me if it was deleted.

Curtis Smith code allows me too look for 0x10080 which is basically a delete. Another way after talking with curtis would be to use the handle ID I presume not sure if it would or how but *WE* would run a if then else loop when event id 0x10080 shows up and see if the corresponding handle ID is link to an event id 4663. I am pretty much passed my scope of coding here but I think that would give me an affirmative DELETE output.

*we* = All the brilliant mind that have contributed to this piece

September 25, 2015 at 1:13 pm

I also want to be able to exclude certain share names for instance " \??\C:\EIS\ " anything that returns that value I want to exclude from the output. This would allow me to exclude an access database that fills this log up with info I don't want. It probably be easier to move the share I want to audit to a different VM honestly.

This will be a great open source tool for file auditing for the community and small shops!

April 24, 2016 at 10:38 pm

Very informative. Also many time there is a need to Export Error log events using Powershell. I read this article explaining exactly that. Read this eventlogxp.com/blog/exporting-event-logs-with-windows-powershell