Background Job in Powershell
One way to do this is use a script block with a param block.
If there is a single argument with a space in it such as a file/folder path it should be quoted to treat it as a single item. The arguments are an array passed to the script block.
This example uses a script block but you can also use a PowerShell script using the -FilePath
parameter of the Start-Job
cmdlet instead of the -ScriptBlock
parameter.
Here is another example that has arguments with spaces:
$scriptBlock = { param ( [string] $Source, [string] $Destination ) $output = & xcopy $Source $Destination 2>&1 return $output}$job = Start-Job -scriptblock $scriptBlock -ArgumentList 'C:\My Folder', 'C:\My Folder 2'Wait-Job $jobReceive-Job $job
Here is an example using the $args
built-in variable instead of the param
block.
$scriptBlock = { $output = & xcopy $args 2>&1 return $output}$path1 = "C:\My Folder"$path2 = "C:\My Folder 2""hello world" | Out-File -FilePath "$path1\file.txt"$job = Start-Job -scriptblock $scriptBlock -ArgumentList $path1, $path2Wait-Job $jobReceive-Job $job
Andy's trick generally works very well. If you have parameter sets, or otherwise want to move complex information into the job, you can also try this technique:
$jobArgs = @{Source="foo"; Destination="bar"}$jobArgs |Export-CliXml -Path $env:\Temp\MyArgs.clixml
and in the job...
Start-Job {.... $jobArgs = Import-CliXml -Path $env:\Temp\MyArgs.clixml} | Wait-Job | Receive-Job
I use both approaches routinely.
I use -ArgumentList / ScriptBlock parameters when:
- I am not dealing with parameter sets
- I'm using an In-Memory Job (like the -AsJob capability in ShowUI or WPK) where the arguments are real objects, and they cannot die
- I'm running in a user context where I can run a job, but can't store to disk (web servers, ISO compliant labs, etc)
If I need complex arguments, and they don't need to be passed in memory (or its otherwise convenient to have them on disk later), I'll use the hashtable approach.
Hope this Helps