1

VS / TFS 2017 This post was updated to reflect new information

There are 2 PowerShell scripts:

p1.ps1
p2.ps1 

p1 is executed as a PowerShell task in a TFS build process. p2 is used twice within p1.

Use 1: p2 is called from p1, meaning p2 is executed inline

Use 2: p2 is launched from p1, meaning p1 does a fire and forget execution of p2, i.e. as a background task.

Within the TFS build process, use 1 works exactly as expected, use 2 does not.

Near the end of p1 are the following 2 different sets of code that have been attempted for the fire and forget execution of p2:

$powershellArguments = "-file C:\conf\p2.ps1" , "refresh" , "C:\agent\_work\4\a\for-deploy\website\"
Start-Process powershell.exe -Argument $powershellArguments

And the 2nd methodology:

Start-Job -FilePath $baseFolder"p2.ps1" -ArgumentList "refresh", $sourceRoot

If I manually execute p1 in a Command Prompt PowerShell Window, the fire and forget p2 execution happens as expected with either sets of code above.

But when I run the build and p1 is executed as a task within the build, p2 does not fire and forget. Again, to be clear, within the TFS build, the use 1 inline process does execute properly.

At the head of the script I embedded some code to write a small text file to confirm the script is at least being started and the code also writes out the arguments received to ensure the argument syntax has been used correctly. The arguments are passed to p2 properly when p1 is executed outside of the build environment. But when p1 is executed as a PowerShell Script within the build, the small text file does not reflect that p2 even started in the fire and forget mode.

It turns out that p1 and p2 are the same script, they just use switches to execute slightly differently. But I copied p1 and named it p2 just to separate the 2 scripts and the result is the same. I can't get p2 to start using the Start-Process cmdlet or the Start-Job cmdlet when p1 is executing within the build.

I think I've been pretty diligent to narrow this down and it seems there is something about launching a separate script from within a script inside the build process.

Why might this be and is there a way around this?

I did wonder if it relates to the basic script policies such as in a batch file that attempts to run a PowerShell script for which we include -executionpolicy remotesigned. Is that possible?

6
  • Does using the full path to the script help? often PowerShell.exe starts in the System32 folder, and it would be trying to execute the script from there. Commented Mar 25, 2019 at 23:07
  • I think we had async posts here. I now have the full path and still have problems, but as I just commented above, my problems seem to be with the argument passing. Still working on it but will leave the post up until I solve it... Commented Mar 25, 2019 at 23:29
  • Argument passing and full path addressing confirmed good, as discussed in the revised post above. Commented Mar 26, 2019 at 0:57
  • I guess when the p1 build task finished the p2 also terminated, try to put Start-Sleep in the end of p1 (with how much time take p2 run) and check the p2 results. Commented Mar 26, 2019 at 10:35
  • I will try the sleep as an exercise because that will help diagnose what's going on, but sadly long term it won't solve my issue. I'm trying to drive the build time as low as possible. The p2 execution is a refresh of destination data using time-consuming FTP commands. I was trying to kick-off the refresh as a separate task so the build can exit early. There's no need to delay build completion just for the data update. But that's a great insight into what may be happening. It's hard to tell because build execution is mostly hidden from view. The logs don't really help with that. Commented Mar 26, 2019 at 14:37

1 Answer 1

1

@Shayik-Abramczyk in the comments was correct. When you use Start-Job, if the PowerShell session terminates, any executing jobs started via Start-Job also terminate.

There are a few ways you could accomplish what you want. It depends on your particular scenario. You could use Register-ScheduledJob or use Start-Process. I'm thinking you probably want Start-Process:

Start-Process PowerShell.exe -ArgumentList "-NonInteractive", "-NoLogo", "-File", ".\$(Join-Path $baseFolder p2.ps1)", 
 "refresh", "$sourceRoot" -NoNewWindow

HTH.

Sign up to request clarification or add additional context in comments.

2 Comments

Will try this when I revisit it and post back with results. Thx!
I updated my answer to add some options to the PowerShell process--otherwise, it may have resulted in a window being opened, which may be undesirable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.