Powershell控制台问题,函数在Register ObjectEvent的操作中执行

Powershell控制台问题,函数在Register ObjectEvent的操作中执行,powershell,Powershell,在powershell ISE中工作正常,但在控制台中我得到: 术语“MainAction”未被识别为cmdlet的名称, 函数、脚本文件或可操作程序。检查单词的拼写 名称,或者如果包含路径,请验证该路径是否正确,并且 再试一次 如何修复 function MainAction () { $test = "123" Write-Host $test } MainAction $action = { try { Write-Host in action

在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()
编辑:

我发现我可以使用profile来存储函数定义。使用:


但我仍然感兴趣的是,为什么powershell ISE不需要配置文件来存储和使用
注册ObjectEvent

的函数。当您使用
注册ObjectEvent
注册
-action
时,powershell将创建新的动态模块来承载该操作。这样,事件处理程序和其余代码之间只共享全局范围。因此,您应该将所有需要的函数放在全局范围内:

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()
或者显式地将它们添加到由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()

function MainAction
->
function global:MainAction
你说得对,这比profile更方便,谢谢你。我现在还想补充一点,如果你的函数和变量也必须可以从主线程访问,那么使用动态模块来存储它们会更方便。
$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()