Powershell - 哈希表对象之间的持续时间

Powershell - Time Duration Between Hashtable Objects

我正在尝试在哈希表中的对象之间创建一个持续时间。所以,我正在提取事件日志以显示机器何时被锁定和解锁:

$Unlocks = Get-WinEvent -FilterHashTable @{LogName = 'Security'; ID = '4801' }
$Locks = Get-WinEvent -FilterHashTable @{LogName = 'Security'; ID = '4800' }
$AllEvents = $Unlocks + $Locks
$OrderedEvents = $AllEvents | Sort-Object TimeCreated

这给了我这个输出:


TimeCreated                     Id LevelDisplayName Message
-----------                     -- ---------------- -------
24/07/2020 07:41:06           4800 Information      The workstation was locked.…
24/07/2020 07:42:27           4801 Information      The workstation was unlocked.…
24/07/2020 07:58:56           4800 Information      The workstation was locked.…
24/07/2020 07:59:13           4801 Information      The workstation was unlocked.…
24/07/2020 09:36:01           4800 Information      The workstation was locked.…
24/07/2020 09:41:50           4801 Information      The workstation was unlocked.…
24/07/2020 10:30:42           4800 Information      The workstation was locked.…
24/07/2020 10:31:25           4801 Information      The workstation was unlocked.…
24/07/2020 12:22:51           4800 Information      The workstation was locked.…
24/07/2020 12:35:55           4801 Information      The workstation was unlocked.…
24/07/2020 13:16:07           4800 Information      The workstation was locked.…
24/07/2020 13:27:28           4801 Information      The workstation was unlocked.…

所以我想添加事件之间的持续时间。

例如,

TimeCreated                     Id LevelDisplayName Message  Duration
-----------                     -- ---------------- ------- --------
24/07/2020 07:41:06           4800 Information      The workstation was locked.…   
24/07/2020 07:42:27           4801 Information      The workstation was unlocked.… 1min 21sec
24/07/2020 07:58:56           4800 Information      The workstation was locked.… 16min 29sec

显然第一个条目没有时间。持续时间正在查看上一个条目。时间的格式并不重要,我稍后会转换它。

当我寻找解决这个问题的方法时,结果并没有完全满足我的需要,但我确信这可能是我没有使用正确的词。

我试过了,但它没有提供我想要的,我也没有正确理解它:

$OrderedEvents | ForEach-Object { $_.TimeCreated = [datetime]$_.TimeCreated; $_ } | 
Group-Object  Id |
ForEach-Object { $_.Group | Sort-Object TimeCreated  }

刚刚为我提供了两个最新条目。

任何帮助或指点将不胜感激。

非常感谢 POC

有几种方法可以解决这个问题。你缺少的主要部分是一个变量来保存上一个条目。

$last = $null
$OrderedEvents | ForEach-Object { 
    $duration = [timespan]0
    $timeStamp = [datetime]$_.TimeCreated
    if ($null -ne $last) {
        $duration = $last - $timeStamp
    }
    $_ | Add-Member -MemberType NoteProperty -Name Duration -Value $duration -PassThru
    $last = $timeStamp
} | Select-Object -Property Duration, TimeCreated, Id, LevelDisplayName, Message

我添加了一个 $last 变量来保存上一个条目的时间戳。我还使用 Add-Member 将新的 Duration 属性 添加到现有对象。 Duration 将是一个 [Timespan] 对象,写入控制台时可能看起来像 00:05:00.0046918。如果您想要更多人类可读的值,可以通过将 $_ | Add-Member -MemberType NoteProperty -Name Duration -Value $duration -PassThru 更改为 $_ | Add-Member -MemberType NoteProperty -Name Duration -Value $duration.Humanize() -PassThru 来使用 PowerShellHumanizer,这会将 Duration 更改为类似“5 分钟,4 毫秒”的字符串。