如何调用 Start-Job,它依赖于与调用 Start-Job 的函数位于同一 powershell 模块中的函数?
我正在单个模块中编写一些 powershell 来与 AWS API 对话。我编写了一个函数 Get-CloudFormation
,它返回 CloudFormation 的状态。我编写了另一个函数 Delete-CloudFormation
,在发出删除 CF API 请求后,尝试启动一个作业,该作业使用我的方法轮询 CloudFormation 的状态获取-CloudFormation
。
我在 Get-CloudFormation
上调用 Export-ModuleMember
(但不是 Delete-CloudFormation
;这是一个私有函数)。 Get-CloudFormation
在模块文件中的定义早于 Delete-CloudFormation
。
我的 Start-Job
调用(在 Delete-CloudFormation
内)如下所示:
$job = Start-Job -Name "CloudFormationWaitForDeleteSuccess" -ScriptBlock {
$status = ""
$time = 0
while($status -ne "DELETE_COMPLETE") {
Write-Verbose ("Checking CloudFormation status")
$stack = Get-CloudFormation -accessKey $accessKey -secretKey $secretKey -stackName $stackName
$status = $stack.Status
Start-Sleep -seconds 10
$time += 10
}
Write-Host "CloudFormation delete-complete after $time seconds $stackName"
}
当 Delete-CloudFormation
运行时,我收到异常:
The term 'Get-CloudFormation' 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.
+ CategoryInfo : ObjectNotFound: (Get-CloudFormation:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
为什么?我该如何解决它?
我发现7152090 我认为是相似的,但是使用 -InitializationScript { Get-CloudFormation }
调用 Start-Job
会产生大致相同的错误。
如果我使用 -InitializationScript { Import-Module ".\awsutils.psm1" }
调用 Start-Job,则 .
是我的配置文件的文档目录。即使我将变量绑定到 Start-Job
外部的 Get-Location
并像 -InitializationScript { Import-Module "$location\awsutils.psm1" 那样调用它}
。
I'm writing some powershell to talk to the AWS API, in a single module. I have written one function, Get-CloudFormation
, which returns the status of a CloudFormation. I've written another function, Delete-CloudFormation
, which after firing off a delete-CF API request, tries to start a job which polls the status of the CloudFormation using my Get-CloudFormation
.
I call Export-ModuleMember
on Get-CloudFormation
(but not Delete-CloudFormation
; that's a private function). Get-CloudFormation
is defined earlier in the module-file than Delete-CloudFormation
.
My Start-Job
call (inside Delete-CloudFormation
) looks like:
$job = Start-Job -Name "CloudFormationWaitForDeleteSuccess" -ScriptBlock {
$status = ""
$time = 0
while($status -ne "DELETE_COMPLETE") {
Write-Verbose ("Checking CloudFormation status")
$stack = Get-CloudFormation -accessKey $accessKey -secretKey $secretKey -stackName $stackName
$status = $stack.Status
Start-Sleep -seconds 10
$time += 10
}
Write-Host "CloudFormation delete-complete after $time seconds $stackName"
}
When Delete-CloudFormation
runs, I get an exception:
The term 'Get-CloudFormation' 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.
+ CategoryInfo : ObjectNotFound: (Get-CloudFormation:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Why? And how do I fix it?
I found 7152090 which I think is similar, but calling Start-Job
with -InitializationScript { Get-CloudFormation }
gives roughly the same error.
If I call Start-Job with -InitializationScript { Import-Module ".\awsutils.psm1" }
then .
is my profile's documents directory. Even if I bind a variable to Get-Location
outside the Start-Job
and call it like -InitializationScript { Import-Module "$location\awsutils.psm1" }
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
将模块
awsutils.psm1
移动到 powershell 模块的规范路径中:然后像这样初始化启动作业
使用我的自定义模块进行测试,启动作业有效。
如果您不想移动您的 psm1,也请尝试:
其中
yourmoduleforder
仅包含一个 psm1 文件。move you module
awsutils.psm1
in the canonical path for powershell modules:then initialize start-job like this
Tested with my custom modules and start-job works.
try also, if you don't want move your psm1 this:
where
yourmoduleforder
contain only one psm1 file.后台工作是自主的事情。它们不是共享资源的单独线程,它们实际上在全新的 PowerShell.exe 进程中运行。因此,我认为您需要在脚本块内使用
Import-Module
以使模块成员可用。Background jobs are autonomous things. They aren't a separate thread sharing resources, they are actually run in a whole new PowerShell.exe process. So I think you will need to use
Import-Module
inside your script block to have you module members available there.我最终做的是在调用
Start-Job
之前设置$env:WhereAmI = Get-Location
,然后更改为-InitializationScript { Import-Module "$env:WhereAmI\awsutils.psm1 }
。在Start-Job
调用之后,我调用Remove-Item env:\WhereAmI
进行清理。(我想要一个不需要我在 $PSModulePath 中开发模块的解决方案,因为那样源代码控制的设置会有点痛苦。)
感谢您的回复。
What I ended up doing was setting
$env:WhereAmI = Get-Location
before the call toStart-Job
, and then changing to-InitializationScript { Import-Module "$env:WhereAmI\awsutils.psm1 }
. After theStart-Job
call, I calledRemove-Item env:\WhereAmI
to clean-up.(I wanted a solution that didn't require me to be developing the module within the $PSModulePath, because then source-control is a little more painful to set up.)
Thanks for the responses.