File Audit report - to CSV part #2

This topic contains 30 replies, has 6 voices, and was last updated by Profile photo of Stuart Ray Stuart Ray 1 year, 3 months ago.

  • Author
    Posts
  • #30041
    Profile photo of 37mm
    37mm
    Participant

    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
      
        } 
        }
    
  • #30045
    Profile photo of Bob McCoy
    Bob McCoy
    Participant

    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"
    
  • #30046
    Profile photo of Brian B
    Brian B
    Participant
    #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
    
  • #30047
    Profile photo of Bob McCoy
    Bob McCoy
    Participant

    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
    
  • #30049
    Profile photo of Brian B
    Brian B
    Participant

    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

  • #30051
    Profile photo of Bob McCoy
    Bob McCoy
    Participant

    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.

  • #30052
    Profile photo of 37mm
    37mm
    Participant

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

  • #30053
    Profile photo of 37mm
    37mm
    Participant

    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.

  • #30055
    Profile photo of Bob McCoy
    Bob McCoy
    Participant

    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.

  • #30056
    Profile photo of Bob McCoy
    Bob McCoy
    Participant

    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])]
    
  • #30059
    Profile photo of 37mm
    37mm
    Participant

    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
    
  • #30060
    Profile photo of 37mm
    37mm
    Participant

    Delete operations don't populate though. Not sure why

  • #30062
    Profile photo of 37mm
    37mm
    Participant

    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.

  • #30070
    Profile photo of Brian B
    Brian B
    Participant

    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.

  • #30071
    Profile photo of 37mm
    37mm
    Participant

    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)

  • #30072
    Profile photo of Curtis Smith
    Curtis Smith
    Participant

    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 :
    `

  • #30074
    Profile photo of 37mm
    37mm
    Participant

    EDIT

  • #30076
    Profile photo of Curtis Smith
    Curtis Smith
    Participant

    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)"

  • #30077
    Profile photo of 37mm
    37mm
    Participant

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

  • #30078
    Profile photo of Curtis Smith
    Curtis Smith
    Participant

    No Problem

  • #30079
    Profile photo of Brian B
    Brian B
    Participant

    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

  • #30081
    Profile photo of Curtis Smith
    Curtis Smith
    Participant

    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

  • #30082
    Profile photo of Brian B
    Brian B
    Participant

    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.

  • #30094
    Profile photo of Curtis Smith
    Curtis Smith
    Participant

    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}
    
  • #30095
    Profile photo of 37mm
    37mm
    Participant

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

  • #30102
    Profile photo of Max Kozlov
    Max Kozlov
    Participant

    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

  • #30141
    Profile photo of Curtis Smith
    Curtis Smith
    Participant

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

  • #30147
    Profile photo of 37mm
    37mm
    Participant
    
    
    $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
    
    
  • #30148
    Profile photo of 37mm
    37mm
    Participant

    [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

  • #30149
    Profile photo of 37mm
    37mm
    Participant

    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!

  • #38203
    Profile photo of Stuart Ray
    Stuart Ray
    Participant

    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

You must be logged in to reply to this topic.