powershell - 将参数传递给 Register-EngineEvent 动作脚本块
问题描述
我想在 PowerShell 脚本完成时捕获它,以便在它停止之前进行一些最终处理。Register-EngineEvent -SourceIdentifier PowerShell.Exiting
似乎是这样做的方法,但它不适用于琐碎的应用程序以外的任何东西。
简单的例子有效。例如:
Register-EngineEvent -SourceIdentifier PowerShell.Exiting -Action {write-host "This is trivial"}
脚本完成后将打印“This is trivial”。但是,任何需要将数据传递给它的操作块都不会获得该数据。例如:
Register-EngineEvent -SourceIdentifier PowerShell.Exiting -Action {write-host ">> " $($event.MessageData)} -MessageData "This doesn't work"
只会打印两个前导尖括号,而不是字符串“这不起作用”。
请注意,我从命令提示符 ( cmd.exe
) 调用脚本,并且Write-Host
在 PowerShell 退出后最终打印出来。
此外,除了$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
或是什么Register-EngineEvent
并且它们不能以我的方式使用我正在尝试这也会很有帮助。
解决方案
注意:虽然此答案包含希望有用的背景信息,但它并不能解决 OP想要将自定义事件数据传递给PowerShell.Exiting
事件处理程序的问题。
Colin 遇到的显然是一个已知错误:请参阅GitHub 问题 #7000。
通常,只是为了澄清:该PowerShell.Exiting
事件仅在退出 PowerShell session时触发,而不是在 session 中运行的脚本。
在运行会话本身中使用它(而不是在将事件转发给调用者的远程会话中使用它)限制您:
- 会话结束时采取幕后行动
- using
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
开关)时才会填充;如果该属性为空,则表示该事件在本地计算机上触发。
$EventSubscriber
存在,但不包含任何可用信息。$EventArgs
,$Sender
并且$Args
未填充。
鉴于上述情况,您可以将输出简化为仅包含事件的时间戳和本地计算机名称:
PS> 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
推荐阅读
- javascript - 如何将图像添加到 javascript 中 achor 标记的特定部分?
- reactjs - 使用带有 typesafe-actions 和 Connected React Router 的史诗
- android - getExternalStorageState().equals(Environment.MEDIA_MOUNTED) 在没有 WRITE_EXTERNAL_STORAGE 的情况下通过
- javascript - 使用 redux-toolkit 将状态重置为初始状态
- c# - gRPC 中的安全性如何发挥作用?
- java - 在 Maven 中设置 Java 版本,系统 Java 版本为 11.0
- function - mariadb fonction, procedure error 你的 SQL 有错误
- pyodbc - 无法打开 lib '/usr/local/lib/libmsodbcsql.13.dylib':找不到文件
- php - PHP - 在前端显示 PDF、AI、EPS 和 SVG 文件的预览
- c++ - 为什么我的程序崩溃并给出“分段错误(核心转储)”,但前提是我有太多对象?