PowerShell exit code - Calling from MSBuild PowerShell exit code - Calling from MSBuild powershell powershell

PowerShell exit code - Calling from MSBuild


This question is the top answer on a major search engine. The best answer is this from James Kovacs (of psake fame - i.e., he's kinda FizzBinned on PowerShell and MSBuild integration).

In summary, in a ps1 file:

  1. stick a $ErrorActionPreference='Stop' at the top of your script so it's not the default, which is SilentlyContinue (the trap bit in the accepted answer has the same effect but is far more indirect and confusing)
  2. stick in his function exec {... (or use psake itself)
  3. wrap invocations of external EXEs in an exec { x.exe }
  4. don't need to do any explicit exit ... stuff

The default error handling propagates an exception up as an ERRORLEVEL of 1 from the powershell.exe myscript.ps1, i.e. in an MSBuild <Exec you don't need to do any trickery re telling it to ignore exit codes etc. (unless you want to do something conditional on the specific exit code, in which you want to do IgnoreExitCode="true" and capture it with an <Output element)

A final important thing to understand is that within PowerShell, there's a $? which is the outcome of the last expression (which is not relevant if you're in ErrorAction='Stop' mode) which changes with every thing you do, whereas $LastExitCode is the 'DOS' exit code of the last .exe triggered in the system. Details here - be sure to read the comments


Add exit $lastexitcode to test.ps1

After comment:

Try this in test.ps1:

trap {Write-Host -foreground red $_.Exception.Message; exit 1; continue} Invoke-command   {Powershell.exe C:\a.ps1} -computername $computers

Basically, I don't think MSBuild is at fault here.

I tried your wrong Invoke-Command and the $lastexitcode was set to 0 even though the Invoke-Command had failed! You can test whether this works or not from cmd itself by doing echo %errorlevel% and see you get 1.


I tried several options but none works for me.

To capture the powershell error on msbuild target, best way is to return the error code from powershell script like $host.SetShouldExit($remotelastexitcode).

e.g.test1.ps1

function CallFromMSBuild {   Invoke-command {Powershell.exe C:\a.ps1} -computername $computers   $host.SetShouldExit(1)} <Target Name="AfterDropBuild" >        <Exec Command="powershell.exe -NoProfile -Noninteractive -command "& { $(ScriptLocation)%3Bexit $LASTEXITCODE }" " >        <Output TaskParameter="ExitCode" PropertyName="ErrorCode"/>        </Exec>   </Target>   

Worth to have a look at https://snagify.wordpress.com/2008/04/06/teambuild-powershell-and-exit-codes/