PowerShell Start-Job Working Directory PowerShell Start-Job Working Directory powershell powershell

PowerShell Start-Job Working Directory


There is nice solution from comments section of some dude's post. Commenter suggests to use Init parameter to setup working directory of script block.

function start-jobhere([scriptblock]$block) {    Start-Job -Init ([ScriptBlock]::Create("Set-Location '$pwd'")) -Script $block}


A possible solution would be to create a "kicker-script":

Start-Job -filepath .\emacs.ps1 -ArgumentList $workingdir, "RandomFile.txt"

Your script would look like this:

Set-Location $args[0]emacs $args[1]

Hope this helps.


Update:

PowerShell [Core] 7.0 brings the following improvements:

  • Background jobs (as well as thread jobs and ForEach-Object -Parallel) now - sensibly - inherit the caller's current (filesystem) location.

  • A new -WorkingDirectory parameter allows you to specify a directory explicitly.


To summarize the problem (applies to Windows PowerShell and PowerShell Core 6.x)

  • A background job started with Start-Job does not inherit the current location (working directory).

    • It defaults to $HOME\Documents in Windows PowerShell, and $HOME in PowerShell Core.

    • If you're using PowerShell Core and you're targeting a file in the current directory, you can use the following, because the new ... & syntax by default runs the job in the current directory:
      emacs RandomFile.txt &

  • You cannot directly reference variables from the current session in a script block passed to Start-Job.

To complement jdmichal's own helpful answer and asavartsov's helpful answer, which still work well:

PSv3 introduced a simple way to reference the current session's variable values in a script block that is executed in a different context (as a background job or on a remote machine), via the $using: scope:

Start-Job { Set-Location $using:PWD; emacs RandomFile.txt }

Alternatively:

Start-Job { emacs $using:PWD/RandomFile.txt }

See about_Remote_Variables


Note:

  • This GitHub issue reports the surprising inability to use $using: in the script block passed to -InitializationScript, even though it works in the main script block (the implied -ScriptBlock parameter).
    • Start-Job -Init { Set-Location $using:PWD } { emacs RandomFile.txt } # FAILS