locked
Try Catch - Unexpected behaviour RRS feed

  • Question

  • Hi

    I have a script with an unexpectd behaviour when inside a try-catch block

    The $ErrorActionPreference is Continue
    The script does Get-ADUser xyz  -ErrorAction SilentlyContinue
    When no try-catch block is used, the script continues to next statements
    When the Get-ADUser xyz  -ErrorAction SilentlyContinue is used inside a try-catch block, the script jumps to the catch block (Cannot find an object with identity: 'xyz' under: xxx).

    Shouldn´t the -ErrorAction specified allow me to continue and have the try-catch take effect only to other errors on other commands inside the block?

    Thanks,

    JD

    Wednesday, May 27, 2020 4:15 PM

All replies

  • What you are claiming is just not true.  In PS 5.1 the command will always throw and exception in that configuration.

    PS C:\scripts> Get-ADUser xyz  -ErrorAction SilentlyContinue
    Get-ADUser : Cannot find an object with identity: 'xyz' under: 'DC=KAHLNET,DC=local'.
    At line:1 char:1
    + Get-ADUser xyz  -ErrorAction SilentlyContinue

    It will always behave like a "Stop" in this configuration:

    Try{Get-ADUser xyz  -ErrorAction SilentlyContinue}Catch{'Caught'}

    or these:

    Try{Get-ADUser xyz  -ErrorAction Stop}Catch{'Caught'}
    Try{Get-ADUser xyz }Catch{'Caught'}

    Earlier versions of PowerShell may not behave this way.  Depends on your version.


    \_(ツ)_/

    Wednesday, May 27, 2020 4:55 PM
  • There's 2 kinds of exceptions, script terminating, and command terminating.  get-aduser is throwing a command terminating exception.  You don't need to do anything extra.  Put it outside the try/catch without any -erroraction.



    • Edited by JS2010 Wednesday, May 27, 2020 7:52 PM
    Wednesday, May 27, 2020 7:51 PM
  • What you are claiming is just not true

    I have $ErrorActionPreference = Continue

    Doing this:

    Get-ADUser xyz  -ErrorAction SilentlyContinue
    write-host "Passed"

    try{
    Get-ADUser xyz  -ErrorAction SilentlyContinue
    write-host "Passed2"
    }
    catch{
    }

    "Passed" is writen

    "Passed2 is not

    Don´t you have the same result?

    Wednesday, May 27, 2020 11:10 PM
  • Your code makes no sense.

    The Catch will be called and "passed2" will be skipped.  You cannot specify two conditions.  The ErrorAction on the CmdLet will always win.

    When in a Try/Catch the exception will alwys be thrown no matter what you do.

    The following ill not thro an exception.

    try{
        if($account = Get-ADUser -Filter "SamAccountNAme -eq 'xyz'"){
            write-host "Passed2"
        }else{
           Write-Host 'Account not found'
        }
    }
    catch{
        Write-Host $_
    }
        


    \_(ツ)_/

    Wednesday, May 27, 2020 11:43 PM
  • What you are claiming is just not true

    I have $ErrorActionPreference = Continue

    Doing this:

    Get-ADUser xyz  -ErrorAction SilentlyContinue
    write-host "Passed"

    try{
    Get-ADUser xyz  -ErrorAction SilentlyContinue
    write-host "Passed2"
    }
    catch{
    }

    "Passed" is writen

    "Passed2 is not

    Don´t you have the same result?

    Hi junidev,

    situation that you have found is not unique because some commandlets working in some other way that users expect from them. Same problem you can reach when you will try to stop transcript, and some other cmdlets. For those cases you can simply find workarounds like that was provided by jrv or JS2010

    The opinion expressed by me is not an official position of Microsoft

    Thursday, May 28, 2020 7:09 AM
  • Hi Jrv

    Your code is different from the one I posted.

    Effectivelly your code has the result you mentioned.

    But if you substitute the "Get-ADUser -Filter ..." for the one I used "Get-ADUser xyz ..." or by  "Get-ADUSer -Identity  'xyz ...", you will see that the outcome is not the same when the user xyz does not exist in AD

    So, I feel the need to return to you your words and say: What you are claiming is just not true

    If you do not user the -filter, an exception will be thrown . your code will not enter the "else" when the -filter is not used (with or without the -ErrorAction SilentlyContinue)

    You can have a try :

    try{
        if($account = Get-ADUser 'xyz'){
            write-host "Passed2"
        }else{
           Write-Host 'Account not found'
        }
    }
    catch{
        Write-Host $_
    }

    Tks,

    JD

    Thursday, May 28, 2020 5:26 PM
  • I am trying to get you to see why this is happening and the correct way to obtain the behavior you seek.

    You need to spend a bit more time trying to understand both exceptions and teh behavior of the Get-AdUser command.  YOur issue has been posted here for years and the answer has never changed except that the most current version of  Net and PS and the AD module trap the exception whenever the command is in a T/Catch block instead of only when we use "Stop".

    To detect a missing account you must use the "Filter" when inside a Try/Catch block as it will never trigger an exception inside a Try/Catch or outside of a Try/Catch.


    \_(ツ)_/

    Thursday, May 28, 2020 5:59 PM
  • Well, you could have just said that at the beginning, and you didn´t'
    Your answer was quite different from that and it was even incorrect.

    You are a rude, impolite and cunning person

    Thursday, May 28, 2020 8:30 PM
  • Well, you could have just said that at the beginning, and you didn´t'
    Your answer was quite different from that and it was even incorrect.

    You are a rude, impolite and cunning person

    No.  All of what I have posted is true.  The issue is understanding how the system and the Windows Structured Exception Handling (SEH) works and how it is implemented in PS.  Variations in the AD module have occurred and the same is true of all CmdLets over time.  This is someth9ng we always have to keep in mind but learning the fundamentals of Windows is where you have to start then understand how PS or any language or subsystem implements and accesses these Windows support systems.

    The issue always becomes more complicated to explain when trying to explain to those who are not technically trained in Windows NT architecture and technology.   Sometimes the explanations aren't understood and it becomes necessary to try a different approach.  This can appear to be contradictory but review will show it isn't.

    If you really want to understand what lies beneath the prompt then here is a good book that will explain the fundamentals.


    There are also many other books like this that will explain how NT works.


    \_(ツ)_/



    • Edited by jrv Thursday, May 28, 2020 8:40 PM
    Thursday, May 28, 2020 8:39 PM
  • Also the behavior of the Get-AdUser CmdLet has been improved.

    Note also that both of these comands are identical:

    Get-AdUser xyz
    Get-AdUser -Identity xyz

    YOU can learn about this by reading the CmdLet help which will tell you about positional, default and named parameters.


    \_(ツ)_/

    Thursday, May 28, 2020 8:42 PM