Note:
tl;dr
Change the content of your PowerShell script (.ps1
) to the following:
# Invoke sasoact.exe *synchronously*.
# Note: If sasoact.exe isn't a *console* application, append `| Write-Output`
& 'C:\Program Files\SASHome\SASFoundation\9.4\core\sasexe\sasoact.exe' action=Submit datatype=SASFile filename='C:\MyProject\test.sas' progid=SAS.Application.940
# Report its exit code.
exit $LASTEXITCODE
- Direct invocation of
sasoact.exe
ensures synchronous execution and availability of its exit code via $LASTEXITCODE
, which can be passed through with exit
.
- This ensures that when your
process.WaitForExit();
call returns, both sasoact.exe
and your PowerShell script have finished executing and that accessing process.ExitCode
subsequently reflects sasoact.exe
's exit code.
Your primary problem is that Start-Process
launches a program asynchronously by default; while you can make the invocation synchronous with -Wait
, there is no reason to use Start-Process
to begin with - see next section. (If you still want to use it, pass both -Wait
and -PassThru
, and use exit
with the .ExitCode
property on the process-info object returned:
exit (
Start-Process -Wait -PassThru C:\Program Files\SASHome\SASFoundation\9.4\core\sasexe\sasoact.exe" -ArgumentList 'action=Submit datatype=SASFile filename="C:\MyProject\test.sas" progid=SAS.Application.940'
).ExitCode`
Typically, external executables that have CLIs are console applications, and, except in unusual circumstances, Start-Process
is not the right way to invoke them.
- The unusual circumstances where
Start-Process
is needed are: needing to run the program in a new console window (including with elevation) or needing to run with a different user identity. See here for guidance on when Start-Process
is and isn't appropriate.
Invoking console applications directly has the following benefits:
synchronous invocation (whereas with Start-Process
you'd have to use the -Wait
switch) in the current console window (whereas Start-Process
launches the process in a new window by default).[1]
the process exit code is reported in the automatic $LASTEXITCODE
variable (with Start-Process
, you'd have to use -Wait
and -PassThru
and query the .ExitCode
property on the System.Diagnostics.Process
instance that is returned)
the process' stdout and stderr streams are directly connected to PowerShell's output streams, allowing the output to be captured and redirected (whereas with Start-Process
you can only redirect to files with -RedirectStandardOutput
and -RedirectStandardError
).
Note that even if the program being invoked isn't a console application, you can still force its synchronous execution and reflection of its exit code in $LASTEXITCODE
by simply piping its direct invocation to | Write-Output
- see this answer for more information.
[1] Given that Start-Process
runs sasoact.exe in a new window by default, both powershell.exe and sasoact.exe will create a console window for themselves (assuming sasoact.exe
is a console application). You can modify this behavior with the -WindowStyle
parameter, but, as stated, unless you truly need to run in a separate window, there's no good reason to use Start-Process
to begin with.