1

I have my silent installation PowerShell script but I have issue that even if some of the arguments are not correct my execution of the powershell script will not fail.

$expression="C:\app\tool.exe  /COMPUTER=server1  /INSTALL  /SILENT"
try {
Invoke-Expression $expression -ErrorAction Stop
}
catch {
Write-Host "Entered Exception"
}

Unfortunately it's always "green", like execution was successful and no Errors have been thrown.

In the log however I can see that it was "Unintended cancel" of the setup.

******************************************************** Error:
Connect to computer registry failed
Computer 'SERVER1' does not exist
The network path was not found.

Unattended setup >>> 'Cancel'
********************************************************
Exit code = 0x4C7

My script does not enter the catch clause. Is it possible that I can somehow force this to fail, so I can catch that error. I am having big issue that my powershell does not fail, although it should because it got wrong installation argument.

Thank you!!!

vel
  • 1,000
  • 1
  • 13
  • 35
  • The explanation for this has been provided here: https://stackoverflow.com/questions/31086630/invoke-expression-doesnot-throw-an-error-in-powershell – Aditya Nair Oct 10 '21 at 08:25
  • @AdityaNair is it related if I execute the script without Invoke-Expression? If I execute without Invoke-Expression I am getting exactly the same behaviour - I do not get any error `"C:\app\tool.exe /COMPUTER=server1 /INSTALL /SILENT"` Can you please tell me why it doesn't then throw error if I run .exe file directly? – vel Oct 10 '21 at 08:30
  • 1
    Check for the output of `$LASTEXITCODE` at the end of execution of exe. if status is not 0, throw error. I have posted it in the answer for reference. – Aditya Nair Oct 10 '21 at 08:35
  • As an aside: [`Invoke-Expression` (`iex`) should generally be avoided](https://stackoverflow.com/a/51252636/45375); definitely [don't use it to invoke an external program or PowerShell script](https://stackoverflow.com/a/57966347/45375). – mklement0 Oct 10 '21 at 12:44
  • As of PowerShell 7.2, calls to external programs do _not_ cause PowerShell errors (even via `Invoke-Expression`), which means that PowerShell's error-handling features (e.g. `try { ... } catch { ... }`) do not apply (except accidentally, due to a bug with redirections up to v7.1). Instead, check if `$LASTEXITCODE` is nonzero to determine whether an external program failed. _Future_ PowerShell versions may offer an _opt-in_ mechanism for integrating external-program calls into PowerShell's error handling. See [the linked duplicate](https://stackoverflow.com/a/67743340/45375) for details. – mklement0 Oct 10 '21 at 16:16

1 Answers1

-1

Invoke-Expression only checks for the possibility to run a command and gives success when the command can be invoked. Use $LASTEXITCODE to check for output:

$expression="C:\app\tool.exe  /COMPUTER=server1  /INSTALL"
try {
    $result = Invoke-Expression $expression
    if ($LASTEXITCODE -ne 0) {
        throw $result
    }
}
catch {
    Write-Host "Entered Exception"
    $_
}
Aditya Nair
  • 514
  • 1
  • 9
  • 18
  • This does not help unfortunately. I still do not get any output. If I add some Write-Host it is being printed out but catch clause is not captured. `PS C:\> try {Write-Host "aaaa" >> $result = Invoke-Expression $expression >> Write-Host "bbb" >> if ($result -like "*not found*" -or $result -like "*Error*") { >> throw $result >> } >> } >> catch { >> Write-Host "Entered Exception" >> $_ >> } aaaa bbb` – vel Oct 10 '21 at 08:41
  • 1
    $LASTEXITCODE will work also with native app run with Invoke-Expression. To catch errors in the $result variable you need to redirect the error stream to the success steam `$result = Invoke-Expression ($expression + " 2>&1")` – Daniel Oct 10 '21 at 08:49
  • Thanks. The second solution by using the $LASTEXITCODE part works!!! ($reuslt like expression doesn't but when I use LASTEXITICODE I am getting what I need) Thanks a lot – vel Oct 10 '21 at 08:50
  • I didn't down-vote, but I think your answer could be improved: `Invoke-Expression` should be advised against in general, and [should especially be avoided for calling external programs](https://stackoverflow.com/a/57966347/45375). Success or failure should in general not be derived from an external program's _output_, but from its exit code (which makes your `$LASTEXITCODE` solution the proper one). Besides, in the case at hand, there's likely _no_ (stdout/stderr) output at all (only log-file output), due to `/SILENT`. – mklement0 Oct 10 '21 at 16:47
  • I have modified the answer according to the working solution @AndreyDonald – Aditya Nair Oct 11 '21 at 07:13