在 Linux 上进行远程处理时如何转发 Powershell.Exiting 事件

Posted

技术标签:

【中文标题】在 Linux 上进行远程处理时如何转发 Powershell.Exiting 事件【英文标题】:How to forward Powershell.Exiting event when remoting on Linux 【发布时间】:2021-12-15 08:31:51 【问题描述】:

我在 linux 上有一个连接到远程的脚本。退出时,我必须退出两次(一次从远程,一次从本地)。 我想把这两个连接起来,这样我只需要退出一次。

这是我希望的工作:

pwsh -NoExit -Command '
Register-EngineEvent -SourceIdentifier PowerShell.Exiting -Action 
  Write-Host "Received Exiting"

$creds = Get-Credential -UserName sysadm;
$pss = New-PSSession -ComputerName remote-pc -Authentication Negotiate -Credential $creds;
Invoke-Command -Session $pss 
  Register-EngineEvent -SourceIdentifier PowerShell.Exiting -Forward;

Enter-PSSession $pss
'

基于 Register-EngineEvent docs 我希望看到该消息 - 并且手动创建事件有效:

...
[remote-pc] PS C:\Users\sysadm\Documents> $null = New-Event PowerShell.Exiting
Received Exiting
[remote-pc] PS C:\Users\sysadm\Documents> exit
# Expecting a message here...
PS /home/local-user > $null = New-Event PowerShell.Exiting
Received Exiting
PS /home/local-user > exit
Received Exiting

我希望我能够描述我的问题。

为什么不退出会话发送PowerShell.Exiting 事件?

如果不是通过PowerShell.Exiting,是否可以通过其他方式实现“双退出”?

【问题讨论】:

这可能有点安慰,但我已经改写了正确解决问题的答案:如果不是因为Enter-PSSession 中的错误,你就不需要-NoExit,因此不需要事件处理。据推测,您的事件转发解决方法无效的原因是远程会话显然并没有真正结束,直到封闭的 local 会话也退出。 【参考方案1】:

如果不是 Enter-PSSession 中关于脚本内和 CLI 使用的错误,自 PowerShell (Core) 7.2.1 起仍然存在,您的问题就不需要解决问题,因为只需省略 -NoExit 即可满足您的要求,无需事件处理

# !! SHOULD work, but doesn't as of PowerShell (Core) 7.2.1
pwsh -Command '
  $creds = Get-Credential -UserName sysadm;
  $pss = New-PSSession -ComputerName remote-pc -Authentication Negotiate -Credential $creds;
  Enter-PSSession $pss
'

也就是说,如果不是因为这个错误,Enter-PSSession同步进入一个交互式远程会话,直到用户以交互方式终止它才会关闭,此时整个 @ 987654329@ 进程将自动终止并将控制权返回给调用者。

该错误在this answer 中有详细说明,并已在GitHub issue #16350 中报告

不幸的是,据我所知没有好的解决方法:

您对-NoExit 的使用绕过了一半的错误并允许进入远程交互会话。

但是,这也有保持封闭 local 会话活动的副作用,需要您试图避免的 second exit 命令。

正如您所观察到的,您通过从远程会话转发的引擎退出事件来避免这种情况的尝试是无效的;据我所知,原因是远程会话实际上并没有在它以exit(或等效的Exit-PSSession)退出时结束,而是仅在封闭时结束本地会话已退出 - 后者总是需要提交exit交互式

对于您的用例,为了在一定程度上减轻痛苦,您可以将远程会话设置和输入命令放在 *.ps1 脚本或放在 $PROFILE file 中的函数中,然后在首次输入后手动调用交互式(本地)pwsh 会话。

【讨论】:

以上是关于在 Linux 上进行远程处理时如何转发 Powershell.Exiting 事件的主要内容,如果未能解决你的问题,请参考以下文章

如何在远程 Java Web 应用程序上进行内存分析

在本地环境(MAC)上进行 MSA 开发的转发端口

如何将 X11 转发到运行在远程 linux 主机上的虚拟机?

远程调试无法连接

服务器xshell+xmanager实现远程服务器的图形显示

使用linux命令行界面调用windows远程桌面