无法从Get-PSDrive中捕获DriveNotFoundException

时间:2016-02-24 18:56:23

标签: powershell

我无法抓住以下示例中DriveNotFoundException生成的Get-PSDrive

try {
    # Assumes no Q:\ drive connected.
    $foo = Get-PSDrive -name 'Q' -ErrorAction Stop
}
catch [System.Management.Automation.DriveNotFoundException] {
    Write-Output "Drive not found."
}
catch {
    Write-Output "Something else went wrong."
}

这应该打印以下内容:

PS C:\temp> .\foo.ps1
Drive not found.
PS C:\temp>

相反,我得到:

PS C:\temp> .\foo.ps1
Something else went wrong.
PS C:\temp>

我正在使用Powershell 2.0,如果这是相关的。

4 个答案:

答案 0 :(得分:5)

问题是因为-ErrorAction Stop正在更改try / catch块所看到的Exception类型。

您可以通过捕获ActionPreferenceStopException类型来证明这一点。因此,让我们运行一些故障排除代码,看看发生了什么:

try {
    # Assumes no Q:\ drive connected.
    $foo = Get-PSDrive -name 'Q' -ErrorAction Stop
}
catch [System.Management.Automation.DriveNotFoundException] {
    Write-Output "Drive not found."
}
catch [System.Management.Automation.ActionPreferenceStopException] {
    Write-Output "Stop Exception."
    write-host "Caught an exception:" -ForegroundColor Red
    write-host "Exception Type: $($_.Exception.GetType().FullName)" -ForegroundColor Red
    write-host "Exception Message: $($_.Exception.Message)" -ForegroundColor Red
}
catch
{
    write-host "Caught an exception:" -ForegroundColor Red
    write-host "Exception Type: $($_.Exception.GetType().FullName)" -ForegroundColor Red
    write-host "Exception Message: $($_.Exception.Message)" -ForegroundColor Red
}

返回以下输出:

Stop Exception.
Caught an exception:
Exception Type: System.Management.Automation.DriveNotFoundException
Exception Message: Cannot find drive. A drive with the name 'Q' does not exist.

所以你看到try / catch抓住了[System.Management.Automation.ActionPreferenceStopException]异常,即使异常类型 [System.Management.Automation.DriveNotFoundException] 里面< / em> catch块。

因此,我们可以使用@ haliphax解决方案的略微修改版本来处理它,这是检查ActionPreferenceStopException catch块内的错误类型:

try {
    # Assumes no Q:\ drive connected.
    $foo = Get-PSDrive -name 'Q' -ErrorAction Stop
}
catch [System.Management.Automation.ActionPreferenceStopException] {
    if ($Error[0].Exception.GetType().Name -eq 'DriveNotFoundException') {
        Write-Output "Drive not found."
    }
    else {
        Write-Output "Something else went wrong."
    }
}
catch {
    Write-Output "Something else went wrong."
}

答案 1 :(得分:3)

补充HAL9256's great answer

注意:以下内容部分是推测性的。如果我错了,请告诉我。

  • 观察到的行为是PowerShell v1和v2 中可能是错误,其中 内部类型异常[System.Management.Automation.ActionPreferenceStopException] catch语句中try / catch

  • [System.Management.Automation.ActionPreferenceStopException]阻止了掩饰原始异常的匹配逻辑。

  • 我怀疑$Error[0].Exception纯粹是一个永远不会暴露的内部异常的原因是catch及其别名在$_.Exception块内,{{ 1}},反映原始异常,即使在PowerShell v1和v2中 - $Errors集合也不包含[System.Management.Automation.ActionPreferenceStopException]的痕迹。

  • 虽然错误已在v3 + 中修复,但v3 + 仍然,但现在 匹配[System.Management.Automation.ActionPreferenceStopException] in typed { {1}}处理程序,大概是为了不破坏向后兼容性。

  • 鉴于其通用性质,它在抓取catch 方面有很大的好处(它只是告诉您 cmdlet遇到了非终止错误)。

    • 捕获它的唯一可能原因是,如果您想知道手头的异常是本地终止还是仅因[System.Management.Automation.ActionPreferenceStopException]-ErrorAction Stop而被视为终止。

因此,对于必须同时运行v2-的代码,我解决了以下问题

$ErrorActionPreference = 'Stop'

答案 2 :(得分:2)

我意识到这是由于一些奇怪的行为(根据上面关于PowerShell的更高版本的评论),但这确实设法处理特定的错误:

try {
    $foo = Get-PSDrive -name 'Q' -ErrorAction Stop
}
catch {
    if ($Error[0].Exception.GetType().Name -eq 'DriveNotFoundException') {
        Write-Output 'No such drive.'
    }
    else {
        Write-Output 'Something else went wrong.'
    }
}

答案 3 :(得分:1)

这只是我使用的代码最终版本的简短帖子,基于@ {HAL9256在his answer中提供的解释:

Get-PSDrive

这已经在PowerShell 2.0和Twitter上进行了测试。 4.0并适用于两者。我想在PowerShell 2.0环境中catch语句中会出现一些其他异常,触发<PersonName Infant="false" NameNumber="2.1" NameReference="C04" PassengerType="CNN"> <GivenName>SALMAN</GivenName> <Surname>KHAN</Surname> </PersonName> 块,但在我的用例中,它是一个小风险可接受的风险,并将在稍后的脚本中触发不同的异常。