To invoke a function in a scriptblock run as a job you need to define the function (all functions invoked in the scriptblock) inside the context of the job. Otherwise you'll get an error like this:
ObjectNotFound: The term 'runjobs' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
To include the function definitions in the code run by the job you can either put them inside the invoked scriptblock or pass them as a separate scriptblock (parameter -InitializationScript
). The latter runs the given initialization code once before the actual job starts, similar to how a BEGIN {}
block in a function works.
So, if you want to invoke Start-Job
from within the script the code in your script would have to look somewhat like this:
[CmdletBinding()]
Param(
[Parameter(Mandatory = $true)]
[String]$currentPath
)
Start-Job -ScriptBlock {
function tfinit {
#...
}
function changes {
#...
}
function runjobs {
Param($path)
#...
}
runJobs -path $args[0]
} -ArgumentList "$currentPath" | Wait-Job | Receive-Job
or like this:
[CmdletBinding()]
Param(
[Parameter(Mandatory = $true)]
[String]$currentPath
)
$jobFunctions = {
function tfinit {
#...
}
function changes {
#...
}
function runjobs {
Param($path)
#...
}
}
Start-Job -InitializationScript $jobFunctions -ScriptBlock {
runJobs -path $args[0]
} -ArgumentList "$currentPath" | Wait-Job | Receive-Job
However, Start-Job
is not limited to running scriptblocks. It can also invoke scripts, so you could leave your script as it is, and run it as a job like this:
Start-Job -FilePath C:\path\to\your.ps1 -ArgumentList "some_path" |
Wait-Job |
Receive-Job
For example in a runner script like this (e.g. run_job.ps1
):
[CmdletBinding()]
Param(
[Parameter(Mandatory = $true)]
[String]$Script,
[Parameter(Mandatory = $true)]
[String]$Path,
[Parameter(Mandatory = $false)]
[ScriptBlock]$InitializationScript = {}
)
Start-Job -FilePath $Script -InitializationScript $InitializationScript -ArgumentList $Path |
Wait-Job |
Receive-Job
that you invoke with your script and the working directory:
.\run_job.ps1 -Script 'C:\path\to\foo.ps1' -Path 'D:\your\path'
As for "its running on a totally different folder," you're invoking Set-Location $path
at the beginning of runjobs()
, so the working directory should be fine unless you're passing a relative path (foo\bar
) rather than an absolute path (D:\foo\bar
). If it isn't: please provide evidence (edit your question to do so).