Powershell Finally the block is skipped with Ctrl-C

I am writing a monitoring script in Powershell using Try / finally to log a message at the end of the script. The script is for unlimited use, so I want to be able to track unexpected activities.

Every other StackOverflow entry and Help Page I've checked the states:

A Finally the block is executed even if you use CTRL + C to stop the script. The finally block is also executed if the Exit keyword stops the script from the Catch block.

In practice, I have not found this to be true. I use the following contrived example to test this:

Try {
    While($True) {
        echo "looping"
        Start-Sleep 3
    }
} Finally {
    echo "goodbye!"
    pause
}

      

The block Finally

is skipped here every time after Ctrl+ C(no echo, no pause), both when running as a saved script and when running through the built-in PowerShell ISE. The only way out I've ever gotten:

looping
looping
...(repeat until Ctrl-C)

      

I'm clearly missing something, but I have no idea what it is, especially in a small piece of code.

+3


source to share


2 answers


Correct answer: Ctrl+ Cbreaks the pipeline as mentioned in this link and echo

uses the pipeline to process its output. Therefore, once you Ctrl+ C, writing to the pipeline will result in a script block error and will not process further commands. Therefore, do not use commands that directly send output to stdout, and there are many that use a pipeline indirectly. Write-Host

on the other hand does not use a pipeline and thus does not throw an error.



+4


source


Functional code

This will give you the behavior that I assume is after you:

Try {
    While($True) {
        echo "looping"
        Start-Sleep 3
    }
} Finally {
    Write-Host "goodbye!"
    pause
}

      

Links

Write-Output / echo - Short description

Sends the specified objects to the next command in the pipeline. If the command is the last command in the pipeline, the objects are displayed in the console.

Write-Host - Short Description

Writes customized output to the host.

Try-Catch-finally - syntax note

Note that pressing CTRL + C stops the conveyor. Objects that are sent to the pipeline will not appear as output. Therefore, if you include a statement that will be displayed, such as "End Block", it will not appear after you press CTRL + C, even if the finally block was running.

Explanation

The key, as per TheIncorrigible1's comment and Vesper's answer, is that the pipeline is stopped . But this is not due to an error in the Write-Output

. And I don't think that this is a satisfactory explanation in and of itself.



  • "If the command is the last command in the pipeline, the objects are displayed in the console." - it looks like this statement is false in the finally block. However, going to Out-Host

    explicitly will give the desired result.
  • In the comment Try-Catch-finally
    • The encoded section is confusing as it applies to the raw objects sent to the pipeline.
    • The objects sent to the pipeline and processed in the block Finally

      are fine.
    • It says "even if the finally block is running", but pause

      does not run if it is preceded Write-Output

      .

More code

In the block Finally

, several actions were performed to investigate the behavior with comments on what was happening.

} Finally {
    Write-Output "goodbye!" | Out-Default # works fine
    pause
}

      


} Finally {
    Write-Output "goodbye!" | Out-Host    # works fine
    pause
}

      


} Finally {
    pause                     # works fine
    Write-output "goodbye!"   # not executed
}

      


} Finally {
    try{
        Write-Output "goodbye!" -ErrorAction Stop
    }catch{
        Write-Host "error caught"   # this is not executed.
    }                               # $error[0] after script execution is empty
    pause
}

      


} Finally {
    try{
        ThisCommandDoesNotExist
    }catch{
        Write-Host "error caught"   # this is executed
    }                               # $error[0] contains CommandNotFoundException      
    pause
}

      

+1


source







All Articles