我试图为外部命令输出的所有行添加时间戳。下面是我的代码:
function Out-Information
{
[CmdletBinding()]
param
(
[Parameter(ValueFromPipeline=$true)]
[String]$String
)
process
{
$datetime = (Get-Date).ToString('yyyy-MM-dd HH:mm:ss.fff', [System.Globalization.CultureInfo]::InvariantCulture)
Write-Information "[$datetime] $String"
}
}
$InformationPreference = 'Continue'
& ping 8.8.8.8 | Out-Information
使用ping命令可以正常工作。输出:
[2019-06-11 12:05:47.728]
[2019-06-11 12:05:47.729] Pinging 8.8.8.8 with 32 bytes of data:
[2019-06-11 12:05:51.697] Request timed out.
[2019-06-11 12:05:56.704] Request timed out.
[2019-06-11 12:06:01.698] Request timed out.
[2019-06-11 12:06:06.702] Request timed out.
[2019-06-11 12:06:06.702]
[2019-06-11 12:06:06.702] Ping statistics for 8.8.8.8:
[2019-06-11 12:06:06.702] Packets: Sent = 4, Received = 0, Lost = 4 (100% loss),
线条完全延迟5秒显示,正如我们在控制台窗口中运行时所看到的。
但是当我尝试运行iisreset命令时,所有行一次出现:
(Get-Date).ToString('yyyy-MM-dd HH:mm:ss.fff', [System.Globalization.CultureInfo]::InvariantCulture)
& iisreset /restart | Out-Information
输出:
2019-06-11 12:12:30.812
[2019-06-11 12:12:56.214]
[2019-06-11 12:12:56.214] Attempting stop...
[2019-06-11 12:12:56.214]
[2019-06-11 12:12:56.214] Internet services successfully stopped
[2019-06-11 12:12:56.214]
[2019-06-11 12:12:56.214] Attempting start...
[2019-06-11 12:12:56.214]
[2019-06-11 12:12:56.214] Internet services successfully restarted
[2019-06-11 12:12:56.214]
但是当我直接从控制台运行iisreset时,我看到输出是一行一行的。
为什么行为不同?在一般情况下,如何捕获正确的时间戳?
答案 0 :(得分:1)
考虑这两个过程如何起作用:
您的第一个示例@ParseClassName("Lesson")
提供了“活动输出”,这意味着该输出是实时发生的,您和您的脚本在前进时都可以看到。
ping
仅在命令完成后才输出,因此时间戳表示为同时返回所有这些值。虽然时间戳不一定准确,但这是应用程序的行为。
iisreset
与iisreset
开关一起运行时,实际上会产生一个新线程来分别执行/restart
和/stop
命令。所有这些都返回到原始/start
线程,然后该线程将所有iisreset /restart
和/stop
的输出显示为一个结果,而不是全部显示在同一时间戳上。