How to make Execute-Process's -PassThru work when the process fails

When you use -PassThru parameter of the Execute-Process function, you’ll notice that the -PassThru parameter doesn’t work and the PSADT script terminates without running any code beyond the Execute-Process line.

That’s because at some point, the -ExitOnProcessFailure parameter was added and it defaults to $true.

Below is a FULL example of how to use -PassThru parameter after the setup.exe returns a NON-ZERO exitcode. I use this to copy the Acrobat Pro log files from %temp% to the temporary logging folder.

#AcrobatProDC's setup.exe is HARD CODED to create logs in %TEMP%. Be it a success of failure, we need the log files
$results = Execute-Process -Path "setup.exe" -Parameters "--silent" -ContinueOnError $true -PassThru -ExitOnProcessFailure $false

#The following will now work thanks to -ExitOnProcessFailure $false
Write-Log "results: [$($results.Output)] [$($results.error)]"

Write-log "Collecting log files created after PSADT started at [$($currentDateTime|Out-String -stream)]..."
[Array]$ArrLogFiles = get-childitem "$envTemp\*.log" 
If ($ArrLogFiles.Count -gt 0) {
	Try {
		Write-Log "Multiple log files found. Copying files dated AFTER `$currentDateTime (when the script was started)"
		$ArrLogFiles = $ArrLogFiles | where {$_.LastWriteTime -gt $currentDateTime}
		$ArrLogFiles.name | Out-String | Write-log
		for ($index = 0; $index -lt $($ArrLogFiles.Count); $index++) {
			Copy-File -Path "$envTemp\$($ArrLogFiles[$index].name)" -Destination $logTempFolder -ContinueOnError $true
		}
	} Catch { 
		Write-Log "Error while trying to copy additional log files. [$(Resolve-Error)]"
		Start-Sleep -Seconds 3
	}
} Else {
	Write-log "setup.exe created no log files. Nothing to copy." -severity 3
}

			
#Now that we have the log files regardless of what happened with setup.exe, we need to stop the script if things did go bad.
If (3010,1641,0 -contains $($results.ExitCode) ) {
	 Write-Log "Exitcode [$($results.ExitCode)] means success!" -Severity 5
	 #Continuing with the rest of the script
} Else {
	$mainExitCode = $results.ExitCode
	[String]$Message = "${$results.STDErr |Out-String} ${$results.STDOut |Out-String}"
	Write-Log "Exitcode [$($results.ExitCode)] means Setup.exe failed. [$Message]" -Severity 3
	Start-Sleep -Seconds 5
	Exit-Script $mainExitCode
}
2 Likes

Thanks for this - I know it’s an older post but will the same principal work for Execute-ProcessAsUser?

I’m looking to use the exit code as a verification before showing an installation prompt.

$AsUser = Execute-ProcessAsUser -Path "$PSHome\powershell.exe" -Parameters "-WindowStyle Hidden -Command `"& {
					Copy-Item -Path `"$env:SystemDrive\Temp\$ZippedFile`" -Destination '\\networkPath\folder$\' | Out-Null;
					Start-Sleep -Seconds 5;
					if (Test-Path -Path `"\\networkPath\folder$\\$ZippedFile`" -PathType Leaf){
						exit 0
					}
					else {
						exit 1
					}
				}`"" -RunLevel 'LeastPrivilege' -Wait -PassThru```

Execute-ProcessAsUser and Execute-Process are totally different functions!
This is off topic and will be deleted at some point.
Please repost this in General Discussions.