如何将时间戳添加到PowerShell的各个行和&输出?

时间:2014-12-08 15:40:13

标签: datetime powershell logging process

如果可以的话,是否可以为& PowerShell运算符生成的输出的每一行添加时间戳?

示例:

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

期望的结果:

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

我知道如何拆分/加入PowerShell数组,但这只能在&运算符完成后发生。我正在寻找更实时的解决方案,其中时间戳被添加到输出,而&运营商正在运行。

顺便说一下,时间戳本身是$($(Get-Date -Format o) + ":")

4 个答案:

答案 0 :(得分:45)

您可以使用过滤器:

filter timestamp {"$(Get-Date -Format o): $_"}
$result = & ping 192.168.1.1 | timestamp

$result的示例输出:

2014-12-08T11:42:59.2827202-05:00: 
2014-12-08T11:42:59.2857205-05:00: Pinging 192.168.1.1 with 32 bytes of data:
2014-12-08T11:43:03.1241043-05:00: Request timed out.
2014-12-08T11:43:08.1236042-05:00: Request timed out.
2014-12-08T11:43:13.1241042-05:00: Request timed out.
2014-12-08T11:43:18.1246042-05:00: Request timed out.
2014-12-08T11:43:18.1246042-05:00: 
2014-12-08T11:43:18.1246042-05:00: Ping statistics for 192.168.1.1:
2014-12-08T11:43:18.1246042-05:00:     Packets: Sent = 4, Received = 0, Lost = 4 (100% loss),

答案 1 :(得分:5)

对于正在寻找有关filterhere is the documentation的更多信息的任何人。由于搜索“过滤器”和“powershell”这两个单词的任何组合将会提供一百万个示例而没有文档,因此很难找到。此外,powershell中的help filter也没有提供明显的帮助。

mjolinor提供的答案是做这样的事情的最佳方式,但我想扩展它。

filter timestamp {"$(Get-Date): $_"}

是调用此

的快捷方式
function timestamp { Process{"$(Get-Date): $_"} }

这两个都创建了接受管道输入的命名函数。在powershell中运行help pipline以了解更多信息。管道将一次对单个对象进行操作,并且可以使用automatic variable $_引用该对象。因此,每个函数将使用|管道字符迭代管道中传递给它的每个项目。

这与普通函数的行为不同,因为它在对象到达时处理对象,而不是一次性对象。例如运行

function timestamp {
        "$(Get-Date): $input"
}
$result = & ping 127.0.0.1
$result | timestamp

将整个$result对象转储到一行上,并产生类似于此的响应

03/14/2018 15:23:16:  Pinging 127.0.0.1 with 32 bytes of data: Reply from 127.0.0.1: b
ytes=32 time<1ms TTL=128 Reply from 127.0.0.1: bytes=32 time<1ms TTL=128 Reply from 12
7.0.0.1: bytes=32 time<1ms TTL=128 Reply from 127.0.0.1: bytes=32 time<1ms TTL=128  Pi
ng statistics for 127.0.0.1:     Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), 
Approximate round trip times in milli-seconds:     Minimum = 0ms, Maximum = 0ms, Avera
ge = 0ms

由于函数作为一个整体在对象上运行,因此您必须迭代每一行。将其更改为

function timestampfunction {
    foreach ($i in $input){
        "$(Get-Date): $i"
    }
}

会给你很好的格式化

03/14/2018 15:23:16: 
03/14/2018 15:23:16: Pinging 127.0.0.1 with 32 bytes of data:
03/14/2018 15:23:16: Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
03/14/2018 15:23:16: Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
03/14/2018 15:23:16: Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
03/14/2018 15:23:16: Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
03/14/2018 15:23:16: 
03/14/2018 15:23:16: Ping statistics for 127.0.0.1:
03/14/2018 15:23:16:     Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
03/14/2018 15:23:16: Approximate round trip times in milli-seconds:
03/14/2018 15:23:16:     Minimum = 0ms, Maximum = 0ms, Average = 0ms

Here是关于这些方法之间差异的精美文章。

答案 2 :(得分:3)

您可以将Start-Transcript cmdlet与个人资料中的自定义提示结合使用:

# Configure PS prompt to show date and time
function prompt
{ 
    $promptStringStart = "PS:" + (Get-Date -format MM/dd/yy` hh:mm:ss)
    $promptStringEnd += ">"
    Write-Host $promptStringStart -NoNewline -ForegroundColor Yellow
    Write-Host $promptStringEnd -NoNewline -ForegroundColor Yellow
    return " "
}

这在我的Windows 7工作站上运行良好。但是,在一些较新的Server 2012 R2安装中,Start-Transcript似乎略有损坏。这修复了它的一部分:#10951

...但它仍无法修复自定义提示的问题。

例如,我在控制台上看到了这一点:

PS:02/14/17 08:28:20> hostname
server463

这就是写入日志的内容:

PS:02/14/17 08:28:20
>

PS>hostname
server463

答案 3 :(得分:0)

您可以仅使用ForEach-Object cmdlet(在下面的示例中使用%别名)

ping 192.168.1.1 | %{ "{0:HH:mm:ss:fff}: {1}" -f (Get-Date), $_ }

结果:

23:41:51:301:
23:41:51:302: Pinging 192.168.1.1 with 32 bytes of data:
23:41:55:255: Request timed out.
23:42:00:266: Request timed out.
23:42:05:254: Request timed out.
23:42:10:253: Request timed out.
23:42:10:261:
23:42:10:263: Ping statistics for 192.168.1.1:
23:42:10:265:     Packets: Sent = 4, Received = 0, Lost = 4 (100% loss),

或使用类似于mjolinor答案中的格式:

ping 192.168.1.1 | %{ "{0:o}: {1}" -f (Get-Date), $_ }

结果:

2019-04-23T23:45:40.5816185+02:00:
2019-04-23T23:45:40.5845856+02:00: Pinging 192.168.1.1 with 32 bytes of data:
2019-04-23T23:45:44.2560567+02:00: Request timed out.
2019-04-23T23:45:49.2549104+02:00: Request timed out.
2019-04-23T23:45:54.2547535+02:00: Request timed out.
2019-04-23T23:45:59.2547932+02:00: Request timed out.
2019-04-23T23:45:59.2577788+02:00:
2019-04-23T23:45:59.2607707+02:00: Ping statistics for 192.168.1.1:
2019-04-23T23:45:59.2627647+02:00:     Packets: Sent = 4, Received = 0, Lost = 4 (100% loss),