PowerShell:如何取消注册孤立的 WMI 事件

标签 powershell wmi wmi-query

以下代码块将生成 100 个 WMI 事件订阅。这种特殊情况只是一个示例,只要插入键盘,就会将字符串写入文件(100 次):

$KeyboardQuery = "SELECT * FROM __InstanceCreationEvent Within 1 WHERE TargetInstance ISA 'Win32_Keyboard'"
for ($i = 0; $i -lt 100; $i++) {
    Register-WmiEvent -Query $KeyboardQuery -Action {
        "A keyboard was just inserted." >> ~\event-log.txt
    }
}
在 PowerShell 中执行此操作时,进程 WmiPrvSE.exe消耗30%-40%的CPU。如果随后执行以下操作,则删除事件订阅并 WmiPrvSE.exe降至正常水平的 CPU 使用率或完全关闭:
Get-EventSubscriber | Unregister-Event
这一切都按预期工作。但是,如果 PowerShell 窗口在运行前关闭 Get-EventSubscriber | Unregister-Event , WmiPrvSE.exe不退出,继续消耗30%-40%的CPU。插入键盘后,不再将字符串写入文件。如果打开一个新的 PowerShell 窗口,Get-EventSubscriberGet-EventSubscriber -Force找不到事件订阅者。如果 WmiPrvSE.exe 的所有实例被强制关闭,它们再次启动并继续消耗 30%-40% 的 CPU。 即使在注销并重新登录后,WmiPrvSE.exe继续消耗CPU。 我发现结束这些事件订阅的唯一方法是重新启动计算机。
如何结束在之前的 PowerShell session 中启动的事件订阅?
更新

我发现孤立事件订阅的 CPU 使用率可以通过触发它们订阅的事件来结束,即使在 PowerShell 窗口关闭后它们似乎没有运行操作 block 中的代码。所以在这种情况下,关闭 PowerShell 后插入键盘会导致 WmiPrvSE.exe恢复其正常行为。就像事件订阅正在等待最后一次触发事件才能被清理,但现在归 WMI 系统本身所有。

最佳答案

这是此问答的潜在副本。

Unregister-Event not removing orphaned event subscriptions

引用帖子:

I had the same problem with a timer. I had somehow left a timer with the same SourceIdentifier name in my PowerShell session. Whenever I would wait for my 10 second timer, it would always return immediately.

I saved the output of the Wait-Event and could access the EventIdentifier, which allowed me to Remove-Event by the EventIdentifier. If I used the SourceIdentifier, I could not access the orphaned event. I could tell it was orphaned by examining the output of my Wait-Event.TimeGenerated, which was old. You will need to be able to access the orphaned event by the EventIdentifier which is unique.



帖子中的代码:
$eventDone = "Done"
$job2 = Register-ObjectEvent -InputObject $timer2 -EventName Elapsed -SourceIdentifier $eventDone

$timer2.Interval = 10000;
$timer2.AutoReset = $false;
$timer2.Enabled = $true;

$waitEvent = Wait-Event -SourceIdentifier $eventDone;
# Look at the $waitEvent.TimeGenerated for a clue it is old
# use the $waitEvent.EventIdentifier to access the event and remove it
$orphanEventID = $waitEvent.EventIdentifier
Remove-Event -EventIdentifier $orphanEventID

关于PowerShell:如何取消注册孤立的 WMI 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54016050/

相关文章:

windows - 如何启动 PowerShell 3.0?

c# - 使用 C# 或 Powershell 扫描所有可用的无线网络并连接到特定的 SSID

xml - 访问带或不带节点属性的innerXML

c# - WQL Like 语句和语法

c# - 使用 C# 和 WMI 计算的 CPU 使用率错误

sql-server - 查找使用SQL Server登录名的NT用户(Windows登录名)

Powershell - 检查文件是否已完成写入

c# - 如何构建 WMI 查询

c# - 使用 WMI 监控驱动器

c# - WMI - 读取远程域计算机中的 IIS 应用程序时抛出异常 'Access Denied'