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 theConvertFrom-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
andSystem
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).