将参数传递给Register-EngineEvent操作脚本块

时间:2019-03-26 02:33:12

标签: powershell events event-handling

我想在完成时捕获PowerShell脚本,以便可以在停止之前进行一些最终处理。 Register-EngineEvent -SourceIdentifier PowerShell.Exiting似乎是这样做的方法,但它对琐碎的应用程序不起作用。

简单的示例有效。例如:

Register-EngineEvent -SourceIdentifier PowerShell.Exiting -Action {write-host "This is trivial"}
脚本完成后,

将打印“这很简单”。但是,任何需要将数据传递给它的操作块都不会获取该数据。例如:

Register-EngineEvent -SourceIdentifier PowerShell.Exiting -Action {write-host ">> " $($event.MessageData)} -MessageData "This doesn't work"

将仅打印两个前角括号,而不打印字符串“这不起作用”。

请注意,我是从命令提示符(cmd.exe)调用脚本的,在PowerShell退出后,Write-Host最终会在那里打印。

此外,除了$Event自动变量以外,其他所有变量,例如$Sender$Args$EventArgs等均未填充。此外,$Event的某些属性未填充。例如,$Event.ComputerName不打印任何内容,而$Event.TimeGenerated不打印当前日期和时间。我的计算机有一个名字。

我提供了一个很小的示例程序,该程序演示要么我做错了,要么Register-EngineEvent可以做些限制,甚至可能是我想的一个错误。

我花了很多时间搜索网站,但没有找到任何示例将它们传递数据到Register-EngineEvent的操作块中。

sleep 1
write-host "Starting"
sleep 1
write-host "Finished"
Register-EngineEvent -SourceIdentifier PowerShell.Exiting -MessageData "This doesn't work" -Action {write-host ">> " $($event.MessageData)}
sleep 2

我希望那个小脚本打印“开始”,然后在1秒后打印“完成”,然后再过2秒后打印事件处理程序 “ >>这不起作用”。我确实收到了前两个消息,但是从处理程序中得到的只是“ >>”。

我在带有Powershell V5的Windows 10上运行。我不在ISE中运行它。我使用命令行powershell -file .\try6.ps1,其中try6.ps1是我上面包含的脚本。

如果有人可以建议我做错了什么或做这件事的替代方法,那很好,但即使仅仅是已知错误或我误解了PowerShell.exiting或{{1} }是,并且不能以我尝试的方式使用它们,这也将非常有帮助。

1 个答案:

答案 0 :(得分:0)

注意:尽管此答案包含希望有用的背景信息,但它不能解决OP希望将自定义事件数据传递给OP的问题 PowerShell.Exiting事件处理程序。

科林遇到的是显然是已知错误 :请参见this GitHub issue


通常,为了澄清一下:PowerShell.Exiting事件仅在退出PowerShell session 时触发,而不在会话内部运行的 script 时触发。

在运行的会话本身中使用它(而不是在将事件转发给调用者的远程会话中使用它)将您限制为:

  • 会话结束时采取幕后行动
  • 使用Write-Host编写调用进程可能看到的输出(不再选择使用隐式输出或Write-Output,因为PowerShell的输出流不再可用事件触发时)。

您正在通过PowerShell的CLI powershell.exe在本地运行脚本,这意味着上述限制适用于您。

事件触发时,about_Automatic_Variables中记录的与事件相关的自动变量似乎并不包含太多信息,如以下命令所示:

PS> powershell -c '$null = 
     Register-EngineEvent -SourceIdentifier PowerShell.Exiting -Action {
      $Event, $EventSubscriber, $Sender, $EventArgs, $Args | Out-string | Write-Host 
     }'
ComputerName     :
RunspaceId       : 1a763430-5cd8-4b74-aaaf-7a90e514518d
EventIdentifier  : 1
Sender           :
SourceEventArgs  :
SourceArgs       : {}
SourceIdentifier : PowerShell.Exiting
TimeGenerated    : 3/26/19 12:15:48 AM
MessageData      :

SubscriptionId   : 1
SourceObject     :
EventName        :
SourceIdentifier : PowerShell.Exiting
Action           : System.Management.Automation.PSEventJob
HandlerDelegate  :
SupportEvent     : False
ForwardEvent     : False
  • $Event存在,并且提供了运行空间ID和反映事件时间的时间戳。

      推测
    • $Event.ComputerName仅在远程处理的情况下(是通过Register-EngineEvent-Forward开关)通过另一台计算机(通过{{3}}的$EventSubscriber开关)转发事件时才填充的;如果该属性为空,则表示该事件在本地计算机上触发。
  • $EventArgs存在,但不包含任何可用信息。

  • $Sender$ArgsPS> powershell -c ' $null = Register-EngineEvent -SourceIdentifier PowerShell.Exiting -Action { [pscustomobject] @{ TimeGenerated = $Event.TimeGenerated; ComputerName = $env:COMPUTERNAME }| Format-List | Out-String | Write-Host } # ... call your script .\try6.ps1 ' TimeGenerated : 3/26/2019 8:57:53 AM ComputerName : Workstation10 未填充。

鉴于上述情况,您可以简化输出以仅包含事件的时间戳记和本地计算机名称:

{{1}}