Windows PowerShell:为忘记历史记录的用户支招献策
Windows PowerShell 总会有办法回调您最近使用的命令,这有时非常有用。
Don Jones
俗话说,“忘记历史者必会重踏覆辙。”不过,在 Windows PowerShell 中,您可能需要重复历史操作,因此需要准确地记住历史操作。Windows PowerShell 自动记住您最近运行的命令,将其保存在缓冲区(或历史记录)中,您可以方便地重新调用和运行这些命令。
历史选项
使用 Windows PowerShell 控制台时,实际上是在处理两种类型的命令历史记录。这两种方法彼此完全独立,毫无关联。
第一种是您可能非常熟悉的命令行缓冲区。当您按向上键以回调运行的上一条命令时使用的是这种方法。您也可以按 F7 以获取以前运行的命令菜单。看到菜单之后,使用箭头键来选择命令,然后按 Enter,命令就会运行。
默认情况下,命令行缓冲区保存最近的 50 条命令。您可以通过编辑控制台窗口本身的属性来增加或减少该设置。单击窗口的控件箱,然后选择“属性”。在“选项”选项卡上,更改“命令历史记录缓冲区大小”的大小。
此命令历史记录实际上与 Windows PowerShell 本身分离。它由控制台托管的应用程序维护。Windows PowerShell 甚至都不知道此历史记录的存在。
可供您使用的历史记录
Windows PowerShell 自身维护的历史记录更为有用。运行 Get-Command –noun history 可查看处理此扩展历史记录日志的全部四个内置 cmdlet:
- Add-History
- Clear-History
- Get-History
- Invoke-History
此外,还有内置变量:$MaximumHistoryCount。此变量设置 Windows PowerShell 内部命令历史记录缓冲区的大小。默认情况下设置为 64。如果要更改该值,只需将变量设置为新值。所做的任何更改仅对当前 shell 会话有效。如果要进行持久更改,请在配置文件脚本中添加类似以下的内容:
$MaximumHistoryCount = 100
这些内容会添加到名为 [My ]Documents\WindowsPowerShell\profile.ps1 的文件中,这是 shell 搜索并自动执行的四个配置文件脚本之一。
Get-History 是我们将主要了解的 cmdlet,因为它也许是这四个中最有用的一个。它生成 HistoryInfo 类型的对象。这些对象包含四个有趣的属性:
- CommandLine:实际运行的命令
- StartExecutionTime:命令启动的时间
- EndExecutionTime:命令结束的时间
- ExecutionStatus:命令完成之后的状态;例如,可以为“已完成”或“已停止”
将这些对象与其他 Windows PowerShell 命令结合起来即可实现一些非常奇妙的功能。例如,假设您打开了一个全新的 shell 窗口并且费力地运行了几个特定命令来完成复杂的任务。您是否希望将这些命令转换为脚本以便按照相同的顺序反复执行?只需运行下列命令:
Get-History | Select –Expand CommandLine | Out-File script.ps1
这里的技巧体现在 Select-Object 的 –ExpandProperty 参数。这使得 Select-Object 只输出指定属性的内容。在本例中为 HistoryInfo 对象的 CommandLine 属性。这包含了刚刚运行的命令的文本。然后,您可以在 Windows PowerShell ISE 或其他脚本编辑器中编辑得到的 Script.ps1 文件来调整命令、将硬编码值转换为参数、删除不需要的命令等等。
假如您采用了这种技巧并最终得到以下 Script.ps1 文件:
Import-Module ActiveDirectory
Import-CSV users.csv
Import-CSV users.csv | New-ADUser –path "ou=sales,dc=company,dc=com"
这是一个很短的例子,但通过交互运行这些命令,您可以逐步验证其运行。实际上,您可以看到第二条命令只是测试 CSV 文件的导入。这仅仅用于确保其中包含所需数据。然后,您可以清除脚本并添加参数:
Param(
[string]$filename = &(Read-Host "Specify input CSV filename"),
[string]$path = "cn=Users,dc=company,dc=com"
)
Import-Module ActiveDirectory
Import-CSV $filename | New-ADUser –path $path
“test import”命令和添加的参数收集 CSV 文件名和目标 OU。相比使用硬编码的值,这是一种更好的方法。请确保无论谁运行此脚本,在用户忘记指定文件名时都会提示需要文件名(这是一种不太好的提示方法,高级函数中将提供更为简洁一致的方法来进行提示)。对于第二个参数,请指定一个默认值,当用户未指定备用值时该值也可以满足需要。
通过这种方法,可以方便地执行已手动完成一次的流程,并将其快速转换为可重复的操作序列,已供其他用户使用。
更多历史记录技巧
“获取”命令行历史记录的功能提供了多种绝妙的技巧:
- 运行 Get-History | Export-CliXMLfilename 可以将命令导出为 XML 文件。将 XML 文件发送给同事,同事可以运行 Import-CliXMLfilename | Invoke-History 来快速重复这些命令。
- 使用 StartExecutionTime 和 EndExecutionTime 属性来衡量完成命令所用的时间。例如,get-history | select commandline,executionstatus,startexecutiontime,endexecutiontime,@{n='ExecutionDuration';e={$_.EndExecutionTime - $_.StartExecutionTime}}
- 快速找出以前的命令,无需使用向上键滚动。例如,如果知道运行了使用“Select”的命令,请尝试以下命令进行查找:get-history | where { $_.CommandLine -like '*select*' }
Windows PowerShell 始终将所有内容作为对象而不是大量文本来处理。这样,如果在文本日志文件或同样繁琐内容中扫描,会使这种搜索和筛选更为可行。
Don Jones是 Microsoft MVP 奖获得者,也是《Learn Windows PowerShell in a Month of Lunches》(Manning Publications Co.,2010)一书的作者,这本书可以帮助所有管理员高效地使用 Windows PowerShell。此外,Jones 还提供公开和现场 Windows PowerShell 培训。您可以通过他的网站 ConcentratedTech.com 与他联系。