Why does -Verbose make Copy-Item ignore ErrorActionPreference?

Viewed 243

Adding -Verbose to a Copy-Item command seems to make the command ignore the value of $ErrorActionPreference. Is that a bug or something that I don't understand?

I think this script should stop before it displays "Why is this displayed...".

$ErrorActionPreference="Stop"
Get-Variable ErrorActionPreference | out-default
Get-Variable ErrorActionPreference -Scope Script | out-default
Get-Variable ErrorActionPreference -Scope Global | out-default

Copy-Item This.Is.Not.There.dat $Home -Verbose
Write-Host "Why is this displayed? The script should have stopped."

Copy-Item This.Is.Not.There.dat $Home
Write-Host "This is not displayed because the script stops."

Here is the output that I get:


Name                           Value
----                           -----
ErrorActionPreference          Stop



Name                           Value
----                           -----
ErrorActionPreference          Stop



Name                           Value
----                           -----
ErrorActionPreference          Continue


Copy-Item : Cannot find path 'C:\users\John\Documents\This.Is.Not.There.dat' because it does not exist.
At C:\users\John\Documents\VerboseDoesNotStop.ps1:6 char:1
+ Copy-Item This.Is.Not.There.dat $Home -Verbose
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\users\John\D...s.Not.There.dat:String) [Copy-Item], ItemNotFoundExce
   ption
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.CopyItemCommand

Why is this displayed? The script should have stopped.
Copy-Item : Cannot find path 'C:\users\John\Documents\This.Is.Not.There.dat' because it does not exist.
At C:\users\John\Documents\VerboseDoesNotStop.ps1:9 char:1
+ Copy-Item This.Is.Not.There.dat $Home
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\users\John\D...s.Not.There.dat:String) [Copy-Item], ItemNotFoundExce
   ption
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.CopyItemCommand
1 Answers

It is a known bug in Windows PowerShell that has since been fixed in PowerShell [Core] as of (at least) v7.0.3, which is the LTS version as of this writing (I'm not sure in what specific version the fix was introduced).

Here's a minimal example to reproduce the problem:

& { 
  $ErrorActionPreference = 'Stop'
  Get-Item \no\such\path -Verbose
  '!! Should not get here' 
}

With the bug present, the string !! Should not get here unexpectedly prints, even though execution should have been aborted due to the Get-Item call triggering a non-terminating error.

A statement-terminating error, by contrast, is not affected by the bug; e.g., if you use Get-Item -NoSuchParam -Verbose instead, execution is aborted as expected.

Given that Windows PowerShell is no longer being actively developed, this bug may never get fixed - though perhaps if enough users show interest in the open bug report, it will (note that the report only mentions Move-Item, but it seems that all cmdlets are affected).


Workarounds:

  • Instead of -Verbose, use the $VerbosePreference variable.
& { 
 $ErrorActionPreference = 'Stop'
 $VerbosePreference = 'Continue' 
 Get-Item \no\such\path
 '!! Should not get here'
}
  • Instead of $ErrorActionPreference = 'Stop', use -ErrorAction Stop on every cmdlet call:
& { 
 Get-Item \no\such\path -Verbose -ErrorAction Stop
 '!! Should not get here'
}
Related