Как добавить метки времени в отдельные строки PowerShell & output?

как, если вообще, можно добавить временные метки к каждой строке вывода, генерируемого & оператор 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) + ":")

3 ответов


вы можете использовать фильтр:

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),

для тех, кто ищет дополнительную информацию о filter, вот документация. Это было удивительно трудно найти, так как поиск любой комбинации слов "фильтр" и "powershell" даст миллион примеров и никакой документации. Также help filter в powershell также не предоставляет очевидной помощи.

ответ, предоставленный mjolinor, - лучший способ сделать что-то подобное, но я хотел бы расширить его.

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

- это ярлык для вызова этого

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

оба они создают именованные функции, которые принимают входные данные из конвейера. Запустить help pipline в PowerShell, чтобы узнать больше. Конвейер будет работать на одном объекте за раз, и этот объект можно ссылаться на автоматическая переменная $_. Таким образом, каждая функция будет перебирать каждый элемент в конвейере, который был передан ему с помощью | символ.

это ведет себя иначе, чем обычно функция в том, что он работает над объектами по мере их поступления, а не все сразу. Например, под управлением

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

здесь очень красиво написана статья о различиях между этими подходами.


вы можете использовать командлет Start-Transcript в сочетании с пользовательским приглашением в вашем профиле:

# 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, похоже, немного нарушен. Это исправляет часть его: https://support.microsoft.com/en-us/help/3014136/powershell-transcript-file-doesn-t-contain-the-correct-information-in-windows-server-2012-r2

... но это не исправить проблема с пользовательским приглашением, по-прежнему.

например, я вижу это в консоли:

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

и вот что написано в журнале:

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

PS>hostname
server463