You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何挂钩.NET/WMI事件实现PowerShell模块导入时触发操作

监听PowerShell模块导入事件的可行方案

好问题!我刚好研究过类似的场景,其实PowerShell本身就提供了直接针对模块导入的引擎事件,比你提到的事件日志、Runspace池状态变更要精准得多。下面给你分享两个亲测有效的方案:

一、使用PowerShell引擎内置事件(最推荐)

PowerShell的引擎会在模块加载(手动/自动)时触发两个专属事件,你可以用Register-EngineEvent直接挂钩:

1. 监听手动导入事件(PSModuleLoadedEvent)

当用户执行Import-Module手动导入模块时触发:

# 注册模块手动加载事件
$manualLoadEvent = Register-EngineEvent -SourceIdentifier "ManualModuleLoaded" -Action {
    $moduleInfo = $EventArgs.ModuleInfo
    Write-Host "[手动导入] 模块: $($moduleInfo.Name) | 版本: $($moduleInfo.Version) | 路径: $($moduleInfo.Path)"

    # 在这里添加你的条件判断和自定义操作
    if ($moduleInfo.Name -match "^AzureAD|ExchangeOnlineManagement$") {
        Write-Host "检测到目标模块,执行指定动作..."
        # 示例:记录日志、调用自定义函数等
        # Log-ModuleImport -Module $moduleInfo
        # Execute-MyCustomTask
    }
}

2. 监听自动导入事件(PSModuleAutoLoadedEvent)

当调用某个未加载模块的命令,导致PowerShell自动导入模块时触发:

# 注册模块自动加载事件
$autoLoadEvent = Register-EngineEvent -SourceIdentifier "AutoModuleLoaded" -Action {
    $moduleInfo = $EventArgs.ModuleInfo
    Write-Host "[自动导入] 模块: $($moduleInfo.Name) | 版本: $($moduleInfo.Version) | 触发命令: $($EventArgs.CommandName)"

    # 同样可以添加条件过滤逻辑
    if ($moduleInfo.Name -eq "PSScriptAnalyzer") {
        Write-Host "自动导入了目标模块,执行操作..."
    }
}

取消监听的方法

如果不再需要监听,记得注销事件:

Unregister-Event -SourceIdentifier "ManualModuleLoaded"
Unregister-Event -SourceIdentifier "AutoModuleLoaded"

二、关于你提到的其他方案的补充

  • 模块事件日志:默认情况下,PowerShell不会把模块导入操作写入事件日志,除非模块本身有自定义的日志逻辑,所以这个方案不够通用,不推荐。
  • Runspace池状态变更:这个事件的范围太宽泛,无法精准定位到“模块导入”这个动作,会产生大量无关触发,实用性不高。

额外注意事项

  • 事件的Action脚本块会在单独的Runspace中执行,如果你需要和主Runspace交互,可能需要用Get-Variable结合-Scope Global来传递数据。
  • 如果是在脚本中运行,要保持PowerShell会话处于打开状态,否则事件会失效;如果需要持续监听,可以在脚本末尾添加Wait-Event来阻塞会话。

内容的提问来源于stack exchange,提问作者Chris Magnuson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:26:42