'How to assign and append stream of data to a variable in PowerShell as opposed to a file
Using PowerShell, how does one assign and append the output of a command that produces a continuous 'stream' of data to a variable in memory as opposed to a file?
I am attempting to write a script that captures DHCP Offer packets returned to the client device. When I issue the following commands one by one natively in PowerShell (while a DHCP discover packet generator is executed on the same client device):
pktmon filter add -t udp -p 68
pktmon start --etw --log-mode real-time | Select-String ".67 > 255.255.255.255.68"
The expected output is shown on the console. I have to press CTRL+C to exit.
PS C:\Test> pktmon start --etw --log-mode real-time | Select-String ".67 > 255.255.255.255.68" | Select-String -notmatch "ssap SNAP"
E0-CB-BC-2A-C7-20 > FF-FF-FF-FF-FF-FF, ethertype IPv4 (0x0800), length 342: 10.0.0.254.67 > 255.255.255.255.68: UDP, length 300
E0-CB-BC-2A-C7-20 > FF-FF-FF-FF-FF-FF, ethertype IPv4 (0x0800), length 342: 10.0.0.254.67 > 255.255.255.255.68: UDP, length 300
E0-CB-BC-2A-C7-20 > FF-FF-FF-FF-FF-FF, ethertype IPv4 (0x0800), length 342: 10.0.0.254.67 > 255.255.255.255.68: UDP, length 300
E0-CB-BC-2A-C7-20 > FF-FF-FF-FF-FF-FF, ethertype IPv4 (0x0800), length 342: 10.0.0.254.67 > 255.255.255.255.68: UDP, length 300
E0-CB-BC-2A-C7-20 > FF-FF-FF-FF-FF-FF, ethertype IPv4 (0x0800), length 342: 10.0.0.254.67 > 255.255.255.255.68: UDP, length 300
But when I add the same command to a variable within a script:
pktmon filter add -t udp -p 68 | Out-Null
Write-Host "Detecting DHCP Servers...." -ForegroundColor Green
$result = pktmon start --etw --log-mode real-time | Select-String ".67 > 255.255.255.255.68" | Select-String -notmatch "ssap SNAP"
$result
pktmon stop | Out-Null
pktmon filter remove | Out-Null
The script runs through and completes without any output, or any errors. I have no issue when appending it to a text file. I am assuming that the line:
$result = pktmon start --etw --log-mode real-time | Select-String ".67 > 255.255.255.255.68" | Select-String -notmatch "ssap SNAP" | Out-Null
doesn't wait for data to be received and stored in the $result variable and the script immediately executes the lines of code that follow.
Please forgive me as this is my first PowerShell script. I have tried searching the forums but I am obviously not using the correct terminology.
--UPDATE--
Simply adding | Write-Output to capture the variable did the trick for me.
$result = pktmon start --etw --log-mode real-time | Select-String ".67 > 255.255.255.255.68" | Select-String -notmatch "ssap SNAP" | Write-Output
Thanks
Solution 1:[1]
Trying to catch output from native binaries in PowerShell can sometimes be tricky.
With this line (below), you are discarding the output to NULL, therefore it would never be stored in the $result variable.
$result = pktmon start --etw --log-mode real-time | Select-String ".67 > 255.255.255.255.68" | Select-String -notmatch "ssap SNAP" | Out-Null
I recommend removing the | Out-Null at the end of this line, and it should put the output in the $result variable.
If removing the pipe to Out-Null still does not capture the output from pktmon to the $result variable, you can try using a function like Invoke-NativeCommand. This function is nice because it can redirect native command output streams to the desired PowerShell output stream, too.
$result = (Invoke-NativeCommand pktmon start --etw --log-mode real-time) | Select-String ".67 > 255.255.255.255.68" | Select-String -notmatch "ssap SNAP"
If you prefer not to use a function and want to try and keep things 'vanilla', see this question How do I capture the output into a variable from an external process in PowerShell?.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | codaamok |
