How, if at all, is it possible to add timestamps to each line of an output generated by the &
PowerShell operator?
Example:
PS H:\> $result = & ping 192.168.1.1
PS H:\> echo $result
Pinging 192.168.1.1 with 32 bytes of data:
Reply from 192.168.1.1: bytes=32 time=104ms TTL=250
Reply from 192.168.1.1: bytes=32 time=106ms TTL=250
Reply from 192.168.1.1: bytes=32 time=102ms TTL=250
Reply from 192.168.1.1: bytes=32 time=102ms TTL=250
Ping statistics for 192.168.1.1:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 102ms, Maximum = 106ms, Average = 103ms
Desired result:
PS H:\> echo $result
2014-12-08T14:45:48.8898125+00:00:Pinging 192.168.1.1 with 32 bytes of data:
2014-12-08T14:45:48.8932661+00:00:Reply from 192.168.1.1: bytes=32 time=104ms TTL=250
2014-12-08T14:45:48.9233451+00:00:Reply from 192.168.1.1: bytes=32 time=106ms TTL=250
2014-12-08T14:45:48.9765438+00:00:Reply from 192.168.1.1: bytes=32 time=102ms TTL=250
2014-12-08T14:45:49.0233105+00:00:Reply from 192.168.1.1: bytes=32 time=102ms TTL=250
2014-12-08T14:45:49.0233201+00:00:
2014-12-08T14:45:49.0238753+00:00:Ping statistics for 192.168.1.1:
2014-12-08T14:45:49.0239210+00:00: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
2014-12-08T14:45:49.0233318+00:00:Approximate round trip times in milli-seconds:
2014-12-08T14:45:49.0237209+00:00: Minimum = 102ms, Maximum = 106ms, Average = 103ms
I know how to split / join a PowerShell array, but this can only happen AFTER the &
operator completes. I am looking for more realtime-like solution, where timestamps are added to the output while the & operator is running.
By the way, the timestamp itself is $($(Get-Date -Format o) + ":")
You could use the Start-Transcript cmdlet in combination with a custom prompt in your profile:
This works great on my Windows 7 workstation. However, on some newer Server 2012 R2 installations Start-Transcript seems to be slightly broken. This fixes part of it: https://support.microsoft.com/en-us/help/3014136/powershell-transcript-file-doesn-t-contain-the-correct-information-in-windows-server-2012-r2
... but it does not fix the issue with the custom prompt, still.
For example, I see this on the console:
And this is what's written to the log:
You can just use
ForEach-Object
cmdlet for it (used%
alias in below example)result:
Or use format like in mjolinor answer:
result:
You could use a filter:
Sample output from
$result
:For anyone that is looking for more information on
filter
, here is the documentation. It was surprising difficult to find since searching any combination of the word "filter" and "powershell" will give a million examples and no documentation. Alsohelp filter
in powershell provides no obvious help either.The answer provided by mjolinor is the best way to do something like this, but I wanted to expand on it.
Is a shortcut for calling this
Both of these create named functions that accept input from the pipeline. Run
help pipline
in powershell to learn more. The pipeline will operate on a single object at a time, and that object can be referred to with the automatic variable$_
. So each function will iterate over every item in the pipeline that was piped to it using the|
pipe character.This behaves differently than a normal function in that it's working on the objects as they arrive, instead of all at once. For example running
Would dump the entire
$result
object on a single line and result in a response that looks like thisSince the function is operating on the object as a whole you would have to iterate over each line. Changing it to this
Would give you the nicely formatted
Here is a nicely written article on the differences between these approaches.