How do I call Start-Job which depends on a function in the same powershell module as the function calling Start-Job?
Asked Answered
I

4

10

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" }.

Intelligibility answered 22/2, 2012 at 13:24 Comment(0)
K
9

move you module awsutils.psm1 in the canonical path for powershell modules:

$env:userprofile\documents\WindowsPowerShell\Modules\awsutils"

then initialize start-job like this

-InitializationScript { Import-Module awsutils }

Tested with my custom modules and start-job works.

try also, if you don't want move your psm1 this:

-InizializationScript { import-module -name c:\yourpath\yourmodulefolder\ }

where yourmoduleforder contain only one psm1 file.

Korten answered 22/2, 2012 at 13:43 Comment(1)
I guess if the OP wanted to be more dynamic the main script could copy the module into the C:\Windows...\Powershell modules directory so it could just use Import-Module without a full path. It could be removed later... heheAntre
A
3

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.

Antre answered 22/2, 2012 at 13:44 Comment(0)
I
1

What I ended up doing was setting $env:WhereAmI = Get-Location before the call to Start-Job, and then changing to -InitializationScript { Import-Module "$env:WhereAmI\awsutils.psm1 }. After the Start-Job call, I called Remove-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.

Intelligibility answered 22/2, 2012 at 17:10 Comment(0)
D
1
$root = $PSScriptRoot

$initScript = [scriptblock]::Create("Import-Module -Name '$root\Modules\Publish-Assigned_CB_Reports.psm1'")

$job1 = Start-Job -InitializationScript $initScript -ScriptBlock {} -ArgumentList
Destruction answered 20/10, 2015 at 17:12 Comment(2)
Could you please add some explanation to your answer? Code-only answers are frowned upon on SO.Backsaw
this is the answer I sought, and I think for anyone knowledgeable enough to attempt running background jobs will see the answer as self-explanatoryThermaesthesia

© 2022 - 2024 — McMap. All rights reserved.