function F2([String]$var2)
{
.........
.........
}
function F1([String]$var1)
{
.........
F2 $
This is practically the same answer as Dong Mao's, which was here first, but I wrote it on the duplicate without realizing this was here.
Anyway, this method (using modules) may better address the scaling and duplication of code issue.
It's not so much that F2
is out of scope, it's that it doesn't even exist in the job.
Jobs are run as separate processes, so nothing is included from the calling process unless you explicitly give it.
When you reference ${function:F1}
you're using the PSDrive form of variable. In essence, it is the equivalent of Get-Content -LiteralPath Function:\F1
.
If you look at what is returned, you'll see that 1) it's a [ScriptBlock]
(which is exactly the type you need for Start-Job
's -ScriptBlock
parameter), but you'll also see that it is the function's contents; it doesn't even include the name.
This means that in the job you're directly executing the body of the function but you are not actually calling a function.
You could work around this re-generating the function definition part, defining the functions, or just defining F2
over again in the script block. This will start to get messy quickly.
My recommendation is to break your functions out into a module that is available on the system, then inside the script block, just call Import-Module MyFunctions
and they will be available.
If you don't want to go through that process of having separate files, and want to keep it contained, you can create a module on the fly. Just define your functions as a module in your script, and if you like, do it again in the job. Something like this:
$moduleDefinition = {
function F2([String]$var2)
{
"~$var2~"
}
function F1([String]$var1)
{
F2 $var1
}
}
# this makes the module loaded in this context
New-Module -Name MyFunctions -ScriptBlock $moduleDefinition
while ($i -le $count)
{
F1 "dir$i"
Start-Job -ScriptBlock {
param([String]$jobArg)
$modDef = [ScriptBlock]::Create($Using:moduleDefinition)
New-Module -Name MyFunctions -ScriptBlock $modDef
F1 $jobArg
} -ArgumentList @($i)
$i = $i + 1
}