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

Don Jones是 Microsoft MVP 奖获得者,也是《Learn Windows PowerShell in a Month of Lunches》(Manning Publications Co.,2010)一书的作者,这本书可以帮助所有管理员高效地使用 Windows PowerShell。此外,Jones 还提供公开和现场 Windows PowerShell 培训。您可以通过他的网站 ConcentratedTech.com 与他联系。

相关内容