为什么 -Verbose 使 Copy-Item 忽略 ErrorActionPreference?

Joh*_*ero 5 powershell

将 -Verbose 添加到 Copy-Item 命令似乎会使该命令忽略 $ErrorActionPreference 的值。这是一个错误还是我不明白的东西?

我认为这个脚本应该在显示“为什么显示这个......”之前停止。

$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."
Run Code Online (Sandbox Code Playgroud)

这是我得到的输出:


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
Run Code Online (Sandbox Code Playgroud)

mkl*_*nt0 3

这是Windows PowerShell中的一个已知错误,现已在PowerShell [Core]中修复,自(至少) v7.0.3,这是撰写本文时的 LTS 版本(我不确定该修复是在哪个特定版本中)介绍)。

这是重现该问题的最小示例:

& { 
  $ErrorActionPreference = 'Stop'
  Get-Item \no\such\path -Verbose
  '!! Should not get here' 
}
Run Code Online (Sandbox Code Playgroud)

由于存在错误,字符串!! Should not get here会意外打印,即使由于调用触发Get-Item终止而应中止执行错误而应中止执行。

相比之下,语句终止错误不受该错误的影响;例如,如果您使用Get-Item -NoSuchParam -Verbose改为使用,执行将按预期中止。

鉴于Windows PowerShell不再被积极开发,此错误可能永远不会得到修复 - 尽管如果有足够多的用户对公开的错误报告表现出兴趣,它可能会得到修复(请注意,该报告仅提到Move-Item,但似乎所有 cmdlet 都会受到影响) 。


解决方法

  • -Verbose使用变量代替$VerbosePreference
& { 
 $ErrorActionPreference = 'Stop'
 $VerbosePreference = 'Continue' 
 Get-Item \no\such\path
 '!! Should not get here'
}
Run Code Online (Sandbox Code Playgroud)
  • 而不是,在每个 cmdlet 调用上$ErrorActionPreference = 'Stop'使用:-ErrorAction Stop
& { 
 Get-Item \no\such\path -Verbose -ErrorAction Stop
 '!! Should not get here'
}
Run Code Online (Sandbox Code Playgroud)