如何在Windows下使用PowerShell 7实现跨会话事件创建与监听
PowerShell 7 跨会话事件/消息通信方案
问题根因
你使用的New-Event创建的是当前PowerShell会话进程内的本地事件,仅在当前进程内存中存储,不会共享到其他进程,因此同设备的其他会话无法直接读取。
可行实现方案
方案1:基于系统事件日志(适合需要持久化存储事件的场景)
无需额外依赖,事件默认持久化存储在系统中,支持跨进程读取、删除。
- 【首次配置需管理员权限】注册自定义事件源(仅需执行一次)
New-EventLog -LogName Application -Source "PowerShellCustomEvent"
- 【发送端(会话1)】写入事件
Write-EventLog -LogName Application -Source "PowerShellCustomEvent" -EventId 1001 -EntryType Information -Message "Test message data"
- 【接收端(会话2)】持续监听事件
# 注册WMI事件监听,事件触发时自动执行回调逻辑 $query = "SELECT * FROM __InstanceCreationEvent WHERE TargetInstance ISA 'Win32_NTLogEvent' AND TargetInstance.SourceName='PowerShellCustomEvent' AND TargetInstance.LogFile='Application'" Register-WmiEvent -Query $query -SourceIdentifier "CustomLogListener" -Action { $eventData = $event.SourceEventArgs.NewEvent.TargetInstance Write-Host "收到事件:ID=$($eventData.EventCode) 内容=$($eventData.Message)" # 此处添加自定义处理逻辑 }
- 事件管理操作
- 读取所有未处理的自定义事件:
Get-WinEvent -FilterHashtable @{LogName='Application'; ProviderName='PowerShellCustomEvent'} - 清空该源所有事件:
Clear-EventLog -LogName Application -Source "PowerShellCustomEvent" - 停止监听:
Unregister-Event -SourceIdentifier "CustomLogListener"
方案2:基于命名管道(适合轻量实时通信场景)
无持久化、性能更高,无需管理员权限,适合高频实时消息传递。
- 【接收端(会话2)】先启动监听
# 创建命名管道客户端等待连接 $pipe = New-Object System.IO.Pipes.NamedPipeClientStream('.', 'PSCustomEventPipe', [System.IO.Pipes.PipeDirection]::In) $pipe.Connect() $reader = New-Object System.IO.StreamReader($pipe) # 循环监听消息 while($null -ne ($message = $reader.ReadLine())){ Write-Host "收到跨会话消息:$message" # 此处添加自定义处理逻辑 } # 资源释放 $reader.Dispose() $pipe.Dispose()
- 【发送端(会话1)】发送消息
# 创建命名管道服务端 $pipe = New-Object System.IO.Pipes.NamedPipeServerStream('PSCustomEventPipe', [System.IO.Pipes.PipeDirection]::Out) $pipe.WaitForConnection() $writer = New-Object System.IO.StreamWriter($pipe) $writer.AutoFlush = $true # 写入要发送的消息内容 $writer.WriteLine("Test message data") # 资源释放 $writer.Dispose() $pipe.Dispose()
- 消息管理:命名管道为流传输模式,消息被接收端消费后自动消失,无需额外删除操作,关闭监听进程即可停止接收。
补充说明
- 若需要传递结构化数据,可将消息序列化为JSON格式后再传输,接收端反序列化即可使用。
- 命名管道方案也支持跨主机通信,将命名管道客户端构造参数中的
.替换为目标主机IP/主机名即可。
内容的提问来源于stack exchange,提问作者satish
相关产品推荐
相关产品推荐

