15

今天我第一次尝试使用 PowerShell (v3.0),并对它的一些错误处理概念的奇怪实现方式感到非常沮丧。

我编写了以下代码(使用远程注册表 PowerShell 模块)

try
{
    New-RegKey -ComputerName $PCName -Key $Key -Name $Value
    Write-Host -fore Green ($Key + ": created")
}
catch
{
    Write-Host -fore Red "Unable to create RegKey: " $Key
    Write-Host -fore Red $_
}

(这只是一个片段)

显然 PowerShell 的默认行为是不捕获非终止错误。所以我在脚本的顶部添加了以下行,正如不同人推荐的那样:

$ErrorActionPreference = "Stop"

在 PowerShell ISE 中执行此操作确实捕获了所有错误。但是,从终端执行以下命令仍然无法捕获我的错误。

来自 ISE:

PS C:\windows\system32> C:\Data\Scripts\PowerShell\Error.ps1
Errorhandling:  Stop
SOFTWARE\MySoftware does not exist. Attempting to create
Unable to create RegKey:  SOFTWARE\MySoftware
Key 'SOFTWARE\MySoftware' doesn't exist.

从命令行:

PS C:\Data\Scripts\PowerShell> .\Error.ps1
Errorhandling:  Stop
SOFTWARE\MySoftware does not exist. Attempting to create
New-RegKey : Key 'SOFTWARE\MySoftware' doesn't exist.
At C:\Data\Scripts\PowerShell\Error.ps1:17 char:13
+             New-RegKey -ComputerName $PCName -Key $Key -Name $Value
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,New-RegKey

SOFTWARE\MySoftware: created

我不知道为什么首选项变量的行为会根据调用它们的位置而有所不同,尤其是因为 ISE 似乎执行完全相同的命令?

根据其他反馈,我更改了以下行:

New-RegKey -ComputerName $PCName -Key $Key -Name $Value

至:

New-RegKey -ComputerName $PCName -Key $Key -Name $Value -ErrorAction Stop

使用这种方法,我能够从命令行和 ISE 捕获错误,但我不想在我调用的每个 Cmdlet 上指定错误行为,特别是因为捕获错误对于正常运行至关重要编码。(另外,这种方法确实有效的事实只会让我更加困惑)

为整个脚本和/或模块的范围定义错误处理行为的正确方法是什么?

另外,这是我的 $PSVersionTable:

PS C:\Data\Scripts\PowerShell> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      3.0
WSManStackVersion              3.0
SerializationVersion           1.1.0.1
CLRVersion                     4.0.30319.18408
BuildVersion                   6.2.9200.16481
PSCompatibleVersions           {1.0, 2.0, 3.0}
PSRemotingProtocolVersion      2.2
4

1 回答 1

12

由于您运行的是 V3,因此您还可以选择使用 $PSDefaultParameterValues:

$PSDefaultParameterValues += @{'New-RegKey:ErrorAction' = 'Stop'}

通常这会在全局范围内改变它。如果您想将其隔离到本地或脚本范围,您可以先在本地范围内初始化一个新的:

$PSDefaultParameterValues = @{}
$PSDefaultParameterValues += @{'New-RegKey:ErrorAction' = 'Stop'}

如果要继承父范围中已有的内容,然后将其添加到本地范围:

 $PSDefaultParameterValues = $PSDefaultParameterValues.clone()
 $PSDefaultParameterValues += @{'New-RegKey:ErrorAction' = 'Stop'}

要为所有 cmdlet(而不仅仅是 New-RegKey)设置默认 ErrorAction,请在上面的代码中指定'*:ErrorAction'而不是。'New-RegKey:ErrorAction'

于 2014-01-21T14:16:38.980 回答