英文:
Get date/time of commands from history on windows (cmd/ps)
问题
这篇文章似乎展示了在Linux上使用HISTTIMEFORMAT环境变量的等效方法,用于显示日期和时间:
# history
1 2017-08-16 15:30:15 yum install -y mysql-server mysql-client
2 2017-08-16 15:30:15 service mysqld start
3 2017-08-16 15:30:15 sysdig proc.name=sshd
在Windows事件查看器中可能存在一个日志或订阅,可以启用或注册此功能。这个功能可能已经存在于PowerShell中...
检查了doskey /?
,但没有找到相关信息。
❓ 是否可能获取命令执行的详细信息,以及可用的方法有哪些?
英文:
https://www.2daygeek.com/display-date-time-linux-bash-history-command/
Found this article which seems to show equivalent how to for linux, using HISTTIMEFORMAT environment variable,
# history
1 2017-08-16 15:30:15 yum install -y mysql-server mysql-client
2 2017-08-16 15:30:15 service mysqld start
3 2017-08-16 15:30:15 sysdig proc.name=sshd
There may be a log, or a subscription, in windows event viewer that can be enabled or registered
This feature may already exist in powershell...
Checked doskey /?
but nothing jumps out.
❓ Is it possible to get details of when commands were executed, and what methods are available to achieve?
答案1
得分: 1
以下是您要翻译的内容:
<!-- language-all: sh -->
PowerShell的[`Get-History`](https://learn.microsoft.com/powershell/module/microsoft.powershell.core/get-history) cmdlet(内置别名为`ghy`,`h`和`history`)输出[`Microsoft.PowerShell.Commands.HistoryInfo`](https://learn.microsoft.com/en-US/dotnet/api/Microsoft.PowerShell.Commands.HistoryInfo)对象,您可以使用[`Format-Table`](https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/format-table)轻松选择其属性以显示,例如:
```powershell
Get-History | Format-Table Id, StartExecutionTime, CommandLine
示例输出:
Id StartExecutionTime CommandLine
-- ------------------ -----------
77 4/17/2023 9:59:58 AM Get-ChildItem *.txt
78 4/17/2023 10:00:00 AM Get-Date
Get-History
的默认显示格式在PowerShell(Core)7+中显示Duration
属性值而不是StartExecutionTime
,在Windows PowerShell中两者都不显示。
当然,您可以自由选择包括Duration
和StartExecutionTime
。
注意:
-
截至PowerShell 7.3.4,
Get-History
只显示当前会话的历史记录,不包括由PSReadLine
模块维护的持久历史记录 - 参见GitHub问题#12061以了解讨论。 -
由于这里提供的解决方案是基于
Get-History
构建的,它们也仅适用于当前会话历史记录,与bash
的history
内置命令不同。 -
如果将来实现与持久会话历史的集成,那么后者的文件格式将需要扩展,因为它当前仅存储_命令_。
如果要更改_默认_格式,您有两个基本选项:
-
创建一个带有所需列的
*.format.ps1xml
文件,并使用Update-FormatData
-PrependPath
从您的$PROFILE
文件中加载它。这是最佳方法,但不太简单。请参阅下文。 -
次优地,但_更简单地_,创建一个包装
Get-History
的_自定义函数_;您还可以重新定义别名以指向您的自定义函数(例如,Set-Alias h Format-HistoryCustom
) - 再次将这些定义放在您的$PROFILE
文件中:function Format-HistoryCustom { Get-History @args | Format-Table Id, StartExecutionTime, CommandLine }
通过从$PROFILE
加载的自定义格式数据向Get-History
的输出添加StartExecutionTime
列:
以下实现了上述讨论的第一种方法。请注意,在_Windows PowerShell_上还添加了Duration
列(在_PowerShell(Core)_中默认存在)。
下面使用的自定义XML数据是通过以下方式获取的,然后手动更新:
Get-FormatData Microsoft.PowerShell.Commands.HistoryInfo |
Export-FormatData -IncludeScriptBlock -LiteralPath HistoryInfo.format.ps1xml
运行此命令一次,将在$PROFILE
文件旁边放置一个HistoryInfo.format.ps1xml
文件,并将一个命令附加到$PROFILE
本身,以使用Update-FormatData -PrependPath
加载该文件。
# 确保$PROFILE所在的目录存在。
$profileDir = New-Item -Type Directory -Force (Split-Path $PROFILE)
# 在配置文件旁边创建一个“HistoryInfo.format.ps1xml”文件。
$customFormatFile = 'HistoryInfo.format.ps1xml'
@'
<?xml version="1.0" encoding="utf-8"?><!-- 添加StartExecutionTime列到Get-History输出,以及在WinPS中也添加Duration列(在PowerShell(Core)中默认包含)。 --><Configuration><ViewDefinitions><View><Name>history</Name><ViewSelectedBy><TypeName>Microsoft.PowerShell.Commands.HistoryInfo</TypeName></ViewSelectedBy><TableControl><TableHeaders><TableColumnHeader><Width>4</Width><Alignment>Right</Alignment></TableColumnHeader><TableColumnHeader><Width>21</Width><Alignment>Right</Alignment></TableColumnHeader><TableColumnHeader><Label>Duration</Label><Width>12</Width><Alignment>Right</Alignment></TableColumnHeader><TableColumnHeader /></TableHeaders><TableRowEntries><TableRowEntry><TableColumnItems><TableColumnItem><PropertyName>Id</PropertyName></TableColumnItem><TableColumnItem><PropertyName>StartExecutionTime</PropertyName></TableColumnItem><TableColumnItem><ScriptBlock>
$duration = $_.EndExecutionTime - $_.StartExecutionTime
if ($duration.TotalHours -ge 10) {
return "{0}:{1:mm}:{1:ss}.{1:fff}" -f [int]$duration.TotalHours, $duration
}
elseif ($duration.TotalHours -ge 1) {
$formatString = "h\:mm\:ss\.fff"
}
elseif ($duration.TotalMinutes -ge 1) {
$formatString = "m\:ss\.fff"
}
else {
$formatString = "s\.fff"
}
$duration.ToString($formatString)
</ScriptBlock></TableColumnItem><TableColumnItem><PropertyName>CommandLine</PropertyName></TableColumnItem></TableColumnItems></TableRowEntry></TableRowEntries></TableControl></View><View><Name>history</Name><ViewSelectedBy><TypeName>Microsoft.PowerShell.Commands.HistoryInfo</TypeName></ViewSelectedBy><WideControl><WideEntries><WideEntry><WideItem><PropertyName>CommandLine</PropertyName></WideItem></WideEntry></WideEntries></WideControl></View></ViewDefinitions></Configuration>
'@ > (Join-Path $profileDir $customFormatFile)
# 在配置文件中追加一个命令,将格式数据加载到每
<details>
<summary>英文:</summary>
<!-- language-all: sh -->
PowerShell's [`Get-History`](https://learn.microsoft.com/powershell/module/microsoft.powershell.core/get-history) cmdlet (whose built-in aliases are `ghy`, `h`, and `history`) outputs [`Microsoft.PowerShell.Commands.HistoryInfo`](https://learn.microsoft.com/en-US/dotnet/api/Microsoft.PowerShell.Commands.HistoryInfo) objects, whose properties you can easily select for display with [`Format-Table`](https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/format-table), for instance:
Get-History | Format-Table Id, StartExecutionTime, CommandLine
Sample output:
Id StartExecutionTime CommandLine
77 4/17/2023 9:59:58 AM Get-ChildItem *.txt
78 4/17/2023 10:00:00 AM Get-Date
`Get-History`'s *default* [for-display formatting](https://docs.microsoft.com/en-us/powershell/scripting/developer/format/formatting-file-overview) shows the `Duration` property values instead of `StartExecutionTime` in [_PowerShell (Core) 7+_](https://github.com/PowerShell/PowerShell/blob/master/README.md), and _neither_ in *Windows PowerShell*.
Of course, you're free to include _both_ `Duration` and `StartExecutionTime`.
Note:
* As of PowerShell 7.3.4, `Get-History` only ever shows the _current session_'s history, not also the _persisted_ history maintained by the [`PSReadLine` module](https://learn.microsoft.com/en-us/powershell/module/psreadline/about/about_psreadline) - see [GitHub issue #12061](https://github.com/PowerShell/PowerShell/issues/12061) for a discussion.
* Since the **solutions presented here** build on `Get-History`, they too are **effective for the *current-session* history only**, unlike `bash`'s `history` builtin.
* Should integration with the persistent session history ever be implemented, the latter's file format would have to be extended, given that it currently stores _commands only_.
---
If you want to change the _default_ formatting, you have two fundamental options:
* Author a `*.format.ps1xml` file with the desired columns and load it with [`Update-FormatData`](https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/update-formatdata) `-PrependPath`, from your [`$PROFILE` file](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Profiles).
This is the best approach, but non-trivial, unfortunately. See below.
* _Suboptimally_, but _more simply_, create a _custom function_ that wraps `Get-History`; you may also redefine the aliases to point to your custom function (e.g., `Set-Alias h Format-HistoryCustom`) - again, place these definitions in your `$PROFILE` file:
function Format-HistoryCustom {
Get-History @args |
Format-Table Id, StartExecutionTime, CommandLine
}
---
#### Adding a `StartExecutionTime` column to `Get-History`'s output, via custom formatting data loaded from `$PROFILE`:
The following implements the first approach discussed above.
Note that on _Windows PowerShell_ a `Duration` column is added as well (which is present by default in _PowerShell (Core) 7+_).
The customized XML data used below was obtained by obtaining the current definitions as follows, followed by updating it by hand:
Get-FormatData Microsoft.PowerShell.Commands.HistoryInfo |
Export-FormatData -IncludeScriptBlock -LiteralPath HistoryInfo.format.ps1xml
Run this _once_, which will place a `HistoryInfo.format.ps1xml` file alongside your `$PROFILE` file and append a command to load that file with `Update-FormatData -PrependPath` to `$PROFILE` itself.
Make sure that the directory in which $PROFILE is located exists.
$profileDir = New-Item -Type Directory -Force (Split-Path $PROFILE)
Create a "HistoryInfo.format.ps1xml" file next to the profile file.
$customFormatFile = 'HistoryInfo.format.ps1xml'
@'
<?xml version="1.0" encoding="utf-8"?><!-- Add a StartExecutionTime column to Get-History output, and on WinPS also a Duration column (included by default in PowerShell (Core)). --><Configuration><ViewDefinitions><View><Name>history</Name><ViewSelectedBy><TypeName>Microsoft.PowerShell.Commands.HistoryInfo</TypeName></ViewSelectedBy><TableControl><TableHeaders><TableColumnHeader><Width>4</Width><Alignment>Right</Alignment></TableColumnHeader><TableColumnHeader><Width>21</Width><Alignment>Right</Alignment></TableColumnHeader><TableColumnHeader><Label>Duration</Label><Width>12</Width><Alignment>Right</Alignment></TableColumnHeader><TableColumnHeader /></TableHeaders><TableRowEntries><TableRowEntry><TableColumnItems><TableColumnItem><PropertyName>Id</PropertyName></TableColumnItem><TableColumnItem><PropertyName>StartExecutionTime</PropertyName></TableColumnItem><TableColumnItem><ScriptBlock>
$duration = $.EndExecutionTime - $.StartExecutionTime
if ($duration.TotalHours -ge 10) {
return "{0}:{1:mm}:{1:ss}.{1:fff}" -f [int]$duration.TotalHours, $duration
}
elseif ($duration.TotalHours -ge 1) {
$formatString = "h:mm:ss.fff"
}
elseif ($duration.TotalMinutes -ge 1) {
$formatString = "m:ss.fff"
}
else {
$formatString = "s.fff"
}
$duration.ToString($formatString)
</ScriptBlock></TableColumnItem><TableColumnItem><PropertyName>CommandLine</PropertyName></TableColumnItem></TableColumnItems></TableRowEntry></TableRowEntries></TableControl></View><View><Name>history</Name><ViewSelectedBy><TypeName>Microsoft.PowerShell.Commands.HistoryInfo</TypeName></ViewSelectedBy><WideControl><WideEntries><WideEntry><WideItem><PropertyName>CommandLine</PropertyName></WideItem></WideEntry></WideEntries></WideControl></View></ViewDefinitions></Configuration>
'@ > (Join-Path $profileDir $customFormatFile)
Append a command to the profile that loads the formatting data into every session.
@"
Load custom formatting data for Get-History.
Update-FormatData -PrependPath "`$PSScriptRoot/$customFormatFile"
"@ | Add-Content $PROFILE
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论