PowerShell: $? is not set to $False even command fails

Prerequisites

Steps to reproduce

facing issue in version: Powershell version powershell-7.2 and on powershell-7.1.3 OS: centos 7 module used : ExchangeOnlineManagement Issue: I connected o365 via powershell using application. I connected succesfully. I tried to fetch any connector exists or not. That gets failed. But “$?” was not set to False. It always remains True. Earlier it was set to False in such a case. Same issue I faced when I create any connector. IF connector creations fails, “$?” remains True instead of False.

In below code sample:

  1. connector1 does not exist in my o365 exchange.
  2. “myrule” as not created as account has reached limit to no. of rules already.

code sample: $EncPassword = ConvertTo-SecureString -String ‘passowd’ -AsPlainText -Force Connect-ExchangeOnline -AppId ‘appid of mine’ -CertificateFilePath ‘/home/cert.pfx’ -CertificatePassword $EncPassword -Organization ‘myorgdomain.onmicrosoft.com’ write-host “connected” Get-InboundConnector ‘connector1’ if ($? -eq $True) { write-host “inbound connector exist” } else { write-host “inbound connector does not exist” } try { New-TransportRule -Name ‘myrule’ -FromScope NotInOrganization -SentToScope InOrganization -Enabled $true -Priority 0 -SetSCL -1 if ($? -eq $True) { write-host “inbound rule created” } else { write-host “inbound rule creation failed” } } catch { write-error “This is exception” }

Expected behavior

$? should be set to $False as both commands were actually failed. It was working before few days but suddenly behaviour looks changed.

Expected output:
connected
inbound connector does not exist
inbound rule creation failed

Actual behavior

$? always set to $True even both commands were actually failed. It was working before few days but suddenly behaviour looks changed.

actual output:
connected
inbound connector exist
inbound rule created

Error details

No response

Environment data

actual output:
connected
inbound connector exist
inbound rule created

Visuals

No response

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 24 (18 by maintainers)

Most upvoted comments

@jhoneill

Quick terminology note: There are two types of terminating errors:

  • A statement-terminating error (pipeline-terminating) occurs in an expression such as 1 / 0, an exception thrown by a .NET method, an reported by a compiled cmdlet with .ThrowTerminatingError() (which, as noted, you can also do in PowerShell code with $PSCmdlt.ThrowTerminatingError(), but it is cumbersome and rarely done in practice).

    • As the name implies, the scope of what is terminated by default is the current statement , meaning that execution continues with the next statement.
  • A script-terminating error (runspace-terminating, fatal) throw by default produces ; you can promote non-terminating errors to script-terminating ones with -ErrorAction Stop.

    • As the name (imperfectly) implies, the scope of what is terminated by default is the current script - at least - but actually the entire runspace the script and its callers). (In an earlier discussion, it was decided that “script” was good enough, and easier to understand than “runspace”).

    • You can also promote non-terminating errors to script-terminating ones with -ErrorAction Stop. You can additionally promote statement-terminating ones to script-terminating ones with $ErrorActionPreference = 'Stop.

This terminology isn’t official but it’s useful for making sense of what PowerShell does, and I’ve used it here and on Stack Overflow. (The names could be revisited, should they became part of the official docs; speaking of: A while back I’ve attempted a comprehensive overview of PowerShell’s error handling: Our Error Handing, Ourselves)