Register-WmiEvent在PS5可用但PS7报错未识别的问题
问题:PowerShell 7中
Register-WmiEvent存在但无法调用的矛盾及解决办法 问题背景
- 以下脚本可在PowerShell 5/ISE/CMD中正常运行:
#Just incase Event has been previously registered Try { Unregister-Event -SourceIdentifier 'disk' -Force -ErrorAction Stop } Catch {} $REArgs = @{Query = "Select * from __InstanceCreationEvent within 1 where targetinstance isa 'win32_logicaldisk'" SourceIdentifier = "disk" Timeout = 1000 } Register-WmiEvent @REArgs
- 但在PowerShell 7.2.6中运行该脚本时,出现错误:
PSv7>..\test\set-wmidisklistener.ps1 Register-WmiEvent: G:\BEKDocs\Scripts\test\Set-WMIDiskListener.ps1:11 Line | 11 | Register-WmiEvent @REArgs | ~~~~~~~~~~~~~~~~~ | The term 'Register-WmiEvent' is not recognized as a name of a cmdlet, function, script file, or executable program. Check the spelling of | the name, or if a path was included, verify that the path is correct and try again.
- 执行
get-command Register*时,却能查到该cmdlet:
PSv7>get-command Register* CommandType Name Version Source ----------- ---- ------- ------ Function Register-ClusteredScheduledTask 1.0.0.0 ScheduledTasks Function Register-DnsClient 1.0.0.0 DnsClient Function Register-IscsiSession 1.0.0.0 iSCSI Function Register-PSRepository 2.2.5 PowerShellGet Function Register-PSRepository 2.2.5 PowerShellGet Function Register-PSRepository 1.0.0.1 PowerShellGet Function Register-ScheduledTask 1.0.0.0 ScheduledTasks Function Register-StorageSubsystem 2.0.0.0 Storage Cmdlet Register-ArgumentCompleter 7.2.6.500 Microsoft.PowerShell.Core Cmdlet Register-CimIndicationEvent 7.0.0.0 CimCmdlets Cmdlet Register-EngineEvent 7.0.0.0 Microsoft.PowerShell.Utility Cmdlet Register-ObjectEvent 7.0.0.0 Microsoft.PowerShell.Utility Cmdlet Register-PackageSource 1.4.7 PackageManagement Cmdlet Register-PSSessionConfiguration 7.2.6.500 Microsoft.PowerShell.Core Cmdlet Register-ScheduledJob 1.1.0.0 PSScheduledJob Cmdlet Register-WmiEvent 3.1.0.0 Microsoft.PowerShell.Management ExternalScript RegisterManifest.ps1 C:\Program Files\PowerShell\7\RegisterManifest.ps1 Application Register-CimProvider.exe 10.0.1904… C:\Windows\system32\Register-CimProvider.exe
原因分析
PowerShell 7是跨平台的核心版本,Register-WmiEvent这类传统WMI cmdlet属于Windows专属的兼容性功能,默认不会在PS7核心环境中自动加载。Get-Command能查到该cmdlet是因为它会扫描所有已安装模块(包括Windows PowerShell的兼容模块),但实际调用时,PS7不会自动初始化兼容模块的运行环境,导致找不到命令。
解决办法
1. 改用CIM命令(推荐,长期方案)
WMI cmdlet已被微软弃用,官方推荐使用CIM系列命令替代。Register-CimIndicationEvent是Register-WmiEvent的替代命令,功能完全一致,且兼容PS7。修改后的脚本如下:
#Just incase Event has been previously registered Try { Unregister-Event -SourceIdentifier 'disk' -Force -ErrorAction Stop } Catch {} $REArgs = @{Query = "Select * from __InstanceCreationEvent within 1 where targetinstance isa 'win32_logicaldisk'" SourceIdentifier = "disk" Timeout = 1000 } Register-CimIndicationEvent @REArgs
2. 强制加载Windows兼容模块(临时应急方案)
如果必须使用Register-WmiEvent,可在脚本开头添加命令,强制加载Windows PowerShell的兼容模块:
# 加载Windows PowerShell兼容模块 Import-Module Microsoft.PowerShell.Management -UseWindowsPowerShell #Just incase Event has been previously registered Try { Unregister-Event -SourceIdentifier 'disk' -Force -ErrorAction Stop } Catch {} $REArgs = @{Query = "Select * from __InstanceCreationEvent within 1 where targetinstance isa 'win32_logicaldisk'" SourceIdentifier = "disk" Timeout = 1000 } Register-WmiEvent @REArgs
注意:此方法会启动Windows PowerShell兼容会话,存在性能损耗,仅作为临时过渡方案使用。
内容的提问来源于stack exchange,提问作者RetiredGeek
相关产品推荐
相关产品推荐

