Home > Net >  Powershell Foreach with squarebracket list
Powershell Foreach with squarebracket list

Time:10-11

I've been trying to do a foreach loop through an square bracket list that results after running an executable with powershell.

Example: $json= .\chainsaw_windows.exe search C:\Windows\System32\winevt\Logs -e "test3.com" --json -q

The output of $json is:

[{"Event":{"EventData":{"CommandLine":"ping  test5.com","Company":"Microsoft Corporation","CurrentDirectory":"c:\\Users\\Administrator\\Downloads\\chainsaw\\","Description":"TCP/IP Ping Command","FileVersion":"10.0.19041.1 (WinBuild.160101.0800)","Hashes":"MD5=2F46799D79D22AC72C241EC0322B011D,SHA256=7AF50FA112932EA3284F7821B2EEA2B7582F558DBA897231BB82182003C29F8B,IMPHASH=8C3BE1286CDAD6AC1136D0BB6C83FF41","Image":"C:\\Windows\\System32\\PING.EXE","IntegrityLevel":"High","LogonGuid":"A7F7F064-C5F3-6321-E049-590100000000","LogonId":"0x15949e0","OriginalFileName":"ping.exe","ParentCommandLine":"\"C:\\Windows\\system32\\cmd.exe\" ","ParentImage":"C:\\Windows\\System32\\cmd.exe","ParentProcessGuid":"A7F7F064-378F-6344-C907-390000001A00","ParentProcessId":18128,"ParentUser":"DESKTOP-GI1ELAK\\Administrator","ProcessGuid":"A7F7F064-80A6-6344-010C-390000001A00","ProcessId":21596,"Product":"Microsoft® Windows® Operating System","RuleName":"-","TerminalSessionId":1,"User":"DESKTOP-GI1ELAK\\Administrator","UtcTime":"2022-10-10 20:29:26.108"},"System":{"Channel":"Microsoft-Windows-Sysmon/Operational","Computer":"DESKTOP-GI1ELAK","Correlation":null,"EventID":1,"EventRecordID":3504194,"Execution_attributes":{"ProcessID":3920,"ThreadID":6660},"Keywords":"0x8000000000000000","Level":4,"Opcode":0,"Provider_attributes":{"Guid":"5770385F-C22A-43E0-BF4C-06F5698FFBD9","Name":"Microsoft-Windows-Sysmon"},"Security_attributes":{"UserID":"S-1-5-18"},"Task":1,"TimeCreated_attributes":{"SystemTime":"2022-10-10T20:29:26.111941Z"},"Version":5}},"Event_attributes":{"xmlns":"http://schemas.microsoft.com/win/2004/08/events/event"}},{"Event":{"EventData":{"Image":"<unknown process>","ProcessGuid":"00000000-0000-0000-0000-000000000000","ProcessId":21596,"QueryName":"test5.com","QueryResults":"::ffff:104.200.22.130;::ffff:104.200.23.95;","QueryStatus":"0","RuleName":"-","User":"DESKTOP-GI1ELAK\\Administrator","UtcTime":"2022-10-10 20:28:51.351"},"System":{"Channel":"Microsoft-Windows-Sysmon/Operational","Computer":"DESKTOP-GI1ELAK","Correlation":null,"EventID":22,"EventRecordID":3504195,"Execution_attributes":{"ProcessID":3920,"ThreadID":6680},"Keywords":"0x8000000000000000","Level":4,"Opcode":0,"Provider_attributes":{"Guid":"5770385F-C22A-43E0-BF4C-06F5698FFBD9","Name":"Microsoft-Windows-Sysmon"},"Security_attributes":{"UserID":"S-1-5-18"},"Task":22,"TimeCreated_attributes":{"SystemTime":"2022-10-10T20:29:28.147643Z"},"Version":5}},"Event_attributes":{"xmlns":"http://schemas.microsoft.com/win/2004/08/events/event"}}]

I have tried this, but it doesn't work:

foreach ($result in $json)
{
  write-out $result
}

What should I do?

CodePudding user response:

  • $json contains text in JSON format.

  • In order to work with the objects that the JSON text represents you must first parse the text into objects (into a graph of [pscustomobject] instances), using the ConvertFrom-Json cmdlet.

# The output from your .\chainsaw_windows.exe ... call.
$json = '[{"Event":{"EventData":{"CommandLine":"ping  test5.com","Company":"Microsoft Corporation","CurrentDirectory":"c:\\Users\\Administrator\\Downloads\\chainsaw\\","Description":"TCP/IP Ping Command","FileVersion":"10.0.19041.1 (WinBuild.160101.0800)","Hashes":"MD5=2F46799D79D22AC72C241EC0322B011D,SHA256=7AF50FA112932EA3284F7821B2EEA2B7582F558DBA897231BB82182003C29F8B,IMPHASH=8C3BE1286CDAD6AC1136D0BB6C83FF41","Image":"C:\\Windows\\System32\\PING.EXE","IntegrityLevel":"High","LogonGuid":"A7F7F064-C5F3-6321-E049-590100000000","LogonId":"0x15949e0","OriginalFileName":"ping.exe","ParentCommandLine":"\"C:\\Windows\\system32\\cmd.exe\" ","ParentImage":"C:\\Windows\\System32\\cmd.exe","ParentProcessGuid":"A7F7F064-378F-6344-C907-390000001A00","ParentProcessId":18128,"ParentUser":"DESKTOP-GI1ELAK\\Administrator","ProcessGuid":"A7F7F064-80A6-6344-010C-390000001A00","ProcessId":21596,"Product":"Microsoft® Windows® Operating System","RuleName":"-","TerminalSessionId":1,"User":"DESKTOP-GI1ELAK\\Administrator","UtcTime":"2022-10-10 20:29:26.108"},"System":{"Channel":"Microsoft-Windows-Sysmon/Operational","Computer":"DESKTOP-GI1ELAK","Correlation":null,"EventID":1,"EventRecordID":3504194,"Execution_attributes":{"ProcessID":3920,"ThreadID":6660},"Keywords":"0x8000000000000000","Level":4,"Opcode":0,"Provider_attributes":{"Guid":"5770385F-C22A-43E0-BF4C-06F5698FFBD9","Name":"Microsoft-Windows-Sysmon"},"Security_attributes":{"UserID":"S-1-5-18"},"Task":1,"TimeCreated_attributes":{"SystemTime":"2022-10-10T20:29:26.111941Z"},"Version":5}},"Event_attributes":{"xmlns":"http://schemas.microsoft.com/win/2004/08/events/event"}},{"Event":{"EventData":{"Image":"<unknown process>","ProcessGuid":"00000000-0000-0000-0000-000000000000","ProcessId":21596,"QueryName":"test5.com","QueryResults":"::ffff:104.200.22.130;::ffff:104.200.23.95;","QueryStatus":"0","RuleName":"-","User":"DESKTOP-GI1ELAK\\Administrator","UtcTime":"2022-10-10 20:28:51.351"},"System":{"Channel":"Microsoft-Windows-Sysmon/Operational","Computer":"DESKTOP-GI1ELAK","Correlation":null,"EventID":22,"EventRecordID":3504195,"Execution_attributes":{"ProcessID":3920,"ThreadID":6680},"Keywords":"0x8000000000000000","Level":4,"Opcode":0,"Provider_attributes":{"Guid":"5770385F-C22A-43E0-BF4C-06F5698FFBD9","Name":"Microsoft-Windows-Sysmon"},"Security_attributes":{"UserID":"S-1-5-18"},"Task":22,"TimeCreated_attributes":{"SystemTime":"2022-10-10T20:29:28.147643Z"},"Version":5}},"Event_attributes":{"xmlns":"http://schemas.microsoft.com/win/2004/08/events/event"}}]'

# Convert the JSON text to objects (a [pscustomobject] object graph)
# Here, given that the JSON text represents an *array* ([ ... ]),
# an array of nested [pscustomobject]s is returned.
$objectsFromJson = $json | ConvertFrom-Json

# Process the array's elements.
foreach ($object in $objectsFromJson) {
  $object
}

This prints the following to the display:

Event                  Event_attributes
-----                  ----------------
@{EventData=; System=} @{xmlns=http://schemas.microsoft.com/win/2004/08/events/event}
@{EventData=; System=} @{xmlns=http://schemas.microsoft.com/win/2004/08/events/event}

While this representation isn't particularly helpful, it is to be expected, given that PowerShell's for-display formatting system isn't optimized for nested objects.

  • The tabular displays shows the two top-level properties that the array elements have.

  • The hashtable-like @{ ...; ... } representation is how nested [pscustomobject]s are represented by default.

  • That EventData and System appear to have no values is the manifestation of a long-standing bug, where calling .ToString() on [pscustomobject] instances unexpectedly yields the empty string - see GitHub issue #6163.

However:

  • All the data is there, and you can work with it.

    • For instance, use the following to extract the nested UtcTime property value from the objects:

      # ->  '2022-10-10 20:29:26.108', '2022-10-10 20:28:51.351' 
      foreach ($object in $objectsFromJson) {
        $object.Event.EventData.UtcTime
      }
      
    • Using member-access enumeration you can even access the nested property on the array itself, and have the elements' property values extracted:

      $objectsFromJson.Event.EventData.UtcTime
      
  • if you need a quick visualization of a nested object, simply reconvert it to JSON with ConvertTo-Json (though note that you may need a -Depth argument to avoid truncation - see this post).

  • Related