如何在PowerShell中的Scriptblock中运行模块?
我目前正在尝试将.psm1文件动态导入脚本块以执行它 我在作业中使用并行化,因为我需要作为不同的用户同时触发多个模块 代码如下:如何在PowerShell中的Scriptblock中运行模块?,powershell,Powershell,我目前正在尝试将.psm1文件动态导入脚本块以执行它 我在作业中使用并行化,因为我需要作为不同的用户同时触发多个模块 代码如下: $tasksToRun | ForEach-Object -Parallel { $ScriptBlock = { param ($scriptName, $Logger, $GlobalConfig, $scriptsRootFolder ) Write-Output ("hell
$tasksToRun | ForEach-Object -Parallel {
$ScriptBlock = {
param ($scriptName, $Logger, $GlobalConfig, $scriptsRootFolder )
Write-Output ("hello $($scriptsRootFolder)\tasks\$($scriptName)")
Import-Module ("$($scriptsRootFolder)\tasks\$($scriptName)")
& $scriptName -Logger $Logger -GlobalConfig $GlobalConfig
}
$job = Start-Job -scriptblock $ScriptBlock `
-credential $Cred -Name $_ `
-ArgumentList ($_, $using:Logger, $using:globalConfig, $using:scriptsRootFolder) `
Write-Host ("Running task $_")
$job | Wait-job -Timeout $using:timeout
if ($job.State -eq 'Running') {
# Job is still running, stop it
$job.StopJob()
Write-Host "Stopped $($job.Name) task as it took too long"
}
else {
# Job completed normally, get the results
$job | Receive-Job
Write-Host "Finished task $($job.Name)"
}
}
logger变量是如下定义的哈希表:
$Logger = @{
generalLog = $function:Logger
certificateLog = $function:LoggerCertificate
alertLog = $function:LoggerAlert
endpointServiceLog = $function:LoggerEndpointService
}
目前,它出现以下错误:
ObjectNotFound: The term
' blah blah blah, this is the code straight from the logger function '
is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
logger函数用于以特定方式记录到文件,一般来说,它可以用于许多任务
一个简化的记录器示例(可能不会编译,只是删除了一堆行以提供总体思路):
如果有人能帮忙,那太好了,谢谢 如评论中所述,PowerShell作业在单独的进程中执行,您不能跨进程边界共享活动对象 当作业执行时,
$Logger.generalgo
不再是调用过程中注册为Logger
函数的脚本块的引用-它只是一个字符串,包含源函数的定义
您可以从源代码重新创建它:
$actualLogger = [scriptblock]::Create($Logger.generalLog)
或者,在您的情况下,重新创建所有这些:
@($Logger.Keys) |ForEach-Object { $Logger[$_] = [scriptblock]::Create($Logger[$_]) }
只有当日志函数完全独立于它们的环境时,这才会起作用-对调用范围内的变量或属于源模块的变量的任何引用都将无法解析
Start Job
创建一个新进程,并且由于引用类型的序列化方式的实现,$Logger.generalgo
在作业运行时不再是一个可执行函数,它只是一个字符串。您可以根据定义重新创建函数,但它只有在不引用调用范围中的任何其他对象时才能工作。你能展示一个记录器
函数实现吗?当然,我只是编辑了主要帖子,让你知道它们是什么样子。如果你删除了一堆代码,那么我真的不能告诉你如果你试图在作业中重新创建函数是否会遇到问题:)我只删除了非函数部分,比如变量,我会为你把这些都扔掉,只是不想把帖子弄得乱七八糟。对不起!对,因此在作业中重新创建函数将不起作用,因为$LogFile
将不存在,它在scriptblock定义中使用时起作用。非常感谢您的帮助!:)
@($Logger.Keys) |ForEach-Object { $Logger[$_] = [scriptblock]::Create($Logger[$_]) }