Powershell 控制台在 Register-ObjectEvent 操作中执行函数时出现问题

Lav*_*dil 3 powershell

在 powershell ISE 中工作正常,但在控制台中我得到:

术语“MainAction”不被识别为 cmdlet、函数、脚本文件或可操作程序的名称。检查名称的拼写,或者如果包含路径,请验证路径是否正确,然后重试。

怎么修?

function MainAction () {
    $test = "123"
    Write-Host $test
}

MainAction

$action = {
    try {
        Write-Host in action
        MainAction
    } catch {
        Write-Host $Error    
        $timer.Stop()
        Unregister-Event thetimer
    }
}

$timer = New-Object Timers.Timer    
Register-ObjectEvent -InputObject $timer -EventName elapsed `
                     -SourceIdentifier thetimer -Action $action -OutVariable out
$timer.Interval = 5000
$timer.AutoReset = $true
$timer.Start()
Run Code Online (Sandbox Code Playgroud)

编辑:

我发现我可以使用配置文件来存储函数定义。要创建配置文件,请使用:

New-Item -path $profile -itemType file -force
Run Code Online (Sandbox Code Playgroud)

但我仍然感兴趣为什么 powershell ISE 不需要配置文件来存储和使用Register-ObjectEvent.

use*_*407 7

当您注册时-ActionRegister-ObjectEventPowerShell 将创建新的动态模块来托管操作。因此,结果是,事件处理程序和其余代码之间仅共享全局范围。因此,您应该将所有需要的函数放在全局范围内:

function global:MainAction {
    Write-Host 'Do something'
}

$Action = { MainAction }

$Timer = New-Object Timers.Timer
$EventJob = Register-ObjectEvent -InputObject $Timer -EventName Elapsed -Action $Action

$Timer.Interval = 5000
$Timer.AutoReset = $true
$Timer.Start()
Run Code Online (Sandbox Code Playgroud)

或者将它们显式添加到由 PowerShell 创建的动态模块的范围内:

$Action = { MainAction }

$Timer = New-Object Timers.Timer
$EventJob = Register-ObjectEvent -InputObject $Timer -EventName Elapsed -Action $Action

. $EventJob.Module {
    function MainAction {
        Write-Host 'Do something'
    }
}

$Timer.Interval = 5000
$Timer.AutoReset = $true
$Timer.Start()
Run Code Online (Sandbox Code Playgroud)