Calling a Function From Another Function in PowerShell Calling a Function From Another Function in PowerShell powershell powershell

Calling a Function From Another Function in PowerShell


You could move the functions and function call to an InlineScript (PowerShell ScriptBlock) inside the workflow like below.

workflow test {    InlineScript    {        function func1{            Write-Output "Func 1"            logMessage        }        function logMessage{            Write-Output "logMessage"        }        func1    }}

Would Output:

Func 1logMessage

As @JeffZeitlin mentioned in his answer, workflows are not PowerShell and are much more restrictive. The InlineScript block allows for normal PowerShell code to be interpreted however the scope will be tied to the InlineScript block. For instance, if you define the functions in the script block then attempt to call the func1 function outside of the InlineScript block (but still within the workflow) it will fail because it is out of scope.

The same would happen if you define the two functions either outside of the workflow or inside of the workflow but not in an InlineScript block.

Now for an example of how you can apply this to running a foreach -parallel loop.

workflow test {    ## workflow parameter    param($MyList)    ## parallel foreach loop on workflow parameter    foreach -parallel ($Item in $MyList)    {        ## inlinescript        inlinescript        {            ## function func1 declaration            function func1{                param($MyItem)                Write-Output ('Func 1, MyItem {0}' -f $MyItem)                logMessage $MyItem            }            ## function logMessage declaration            function logMessage{                param($MyItem)                Write-Output ('logMessage, MyItem: {0}' -f $MyItem)            }            ## func1 call with $Using:Item statement            ## $Using: prefix allows us to call items that are in the workflow scope but not in the inlinescript scope.            func1 $Using:Item        }    }}

Example call to this workflow would look like this

 PS> $MyList = 1,2,3 PS> test $MyList     Func 1, MyItem 3     Func 1, MyItem 1     Func 1, MyItem 2     logMessage, MyItem: 3     logMessage, MyItem: 2     logMessage, MyItem: 1

You will notice (and as expected) the output order is random since it was run in parallel.


Powershell requires that functions be defined before use ('lexical scope'). In your example, you are calling the logMessage function before you have defined it.

You have also structured your example as a Powershell workflow. Workflows have some restrictions that ordinary scripts do not; you need to be aware of those differences. I did this search to find some descriptions and discussions of the differences; the first "hit" provides good information. I have not (yet) found anything saying whether functions can be defined in workflows, but I would be very wary of defining functions within functions (or workflows) in the first place.


Your logMessage function is not visible from within func1 function. It's valid even though logMessage function is declared above func1 one.

For this simple case, you could use nested functions as follows:

workflow test {    function func1 {        function logMessage {            Write-Output "logMessage"        }        Write-Output "Func 1"        logMessage    }  func1}test

Output:

PS D:\PShell> D:\PShell\SO\41770877.ps1Func 1logMessage