4

I have a psake Task looking something like below (this is simplified for clarity):

Task Invoke-Deploy {

    Import-Module "somefunctions.psm1"

    Import-Module "morefunctions.psm1"

    Set-Something #This is a function defined in morefunctions.psm1
}

Function Set-Something (which is defined in module morefunctions.psm1) attempts to call function Get-Something (which is defined in somefunctions.psm1). When it does I get an error:

The term 'Get-Something' is not recognized as the name of a cmdlet, function, script file, or operable program.

Interestingly I modified "morefunctions.psm1" to also 'Import-Module "somefunctions.psm1"' and at that point everything worked fine. I would rather not have to do this however as i want my modules to be "loosely-coupled" insofar as they don't need to rely on the existence of other modules.

My knowledge of function/variable scope in Powershell is limited but I thought that functions in two different imported modules lived in the same scope and hence a function in one of those modules would be able to call a function in the other.

I am suspecting that that scope is being affected by the fact that I'm inside a psake task, I'm hoping that someone here can confirm that and also advise on what I should do to fix this. TIA.

jamiet
  • 10,501
  • 14
  • 80
  • 159

2 Answers2

2

I created a script module test-module.psm1:

function Invoke-Test {
    Import-Module ".\somefunctions.psm1"

    Import-Module ".\morefunctions.psm1"

    Set-Something #This is a function defined in morefunctions.psm1
}

and a couple of dummy modules, somefunctions.psm1:

function Get-Something {
    'Get-Something'
}

and morefunctions.psm1:

function Set-Something {
    Get-Something
    'Set-Something'
}

If I call

Import-Module .\test-module.psm1
Invoke-Test

then I get the error "Get-Something : The term 'Get-Something' is not recognized as the name of a cmdlet, function, script file, or operable program.". So it looks like a generic PowerShell issue dealing with script modules. I tried PowerShell v2.0, v3.0, and v4.0.

Perhaps this cannot be resolved in psake without workarounds because it is a script module. You can use the similar tool Invoke-Build. It is implemented as a script and avoids issues like these. It works fine with this build script:

Task Invoke-Deploy {

    Import-Module ".\somefunctions.psm1"

    Import-Module ".\morefunctions.psm1"

    Set-Something #This is a function defined in morefunctions.psm1
}

It outputs, as expected:

Build Invoke-Deploy ...\.build.ps1
Task /Invoke-Deploy
Get-Something
Set-Something
Done /Invoke-Deploy 00:00:00.0150008
Build succeeded. 1 tasks, 0 errors, 0 warnings 00:00:00.1450083
Roman Kuzmin
  • 40,627
  • 11
  • 95
  • 117
  • Hi Roman, really appreciate your taking a detailed look. Thx very much. Looks as though you've repro'd the problem, which is good news. I'll take this back to our devops guy (he's away until Monday) as he's the one who introduced psake here, and discuss our options with him. He did talk about psake alternatives (don't know if https://github.com/nightroman/Invoke-Build was one of them) so perhaps he'd be open to such things, altho we are quite well down the path with our use of psake. Thanks again. – jamiet Jul 31 '14 at 06:58
  • I have tried PS v4.0 and I can see the same issue. I hope Invoke-Build will help. It is the same as psake conceptually with some differences in syntax and tools. Build scripts are very similar but not compatible. – Roman Kuzmin Jul 31 '14 at 09:02
  • 3
    You could also use the "Import-Module '.\somefunctions.psm1' -Scope Global" This also solves the issue but you'd have to do a module cleanup at the end of your script. – Ben Guenter Jul 31 '14 at 13:28
  • Thanks @Epithanatios. I presume by "module cleanup" you mean "Remove-Module " ? – jamiet Sep 17 '14 at 11:13
0

I ran into this today and got it to work.

In your module "morefunctions.psm1" you need to export the method you want like this:

 Export-ModuleMember -Function Set-Something

In your psake task, you need to prepend the module name in front of the method so PowerShell can find it:

Import-Module "morefunctions.psm1"

morefunctions\Set-Something