PowerShell错误处理与调试全解析
立即解锁
发布时间: 2025-08-14 00:55:05 阅读量: 27 订阅数: 25 AIGC 


精通PowerShell脚本编写:自动化与简化任务
### PowerShell 错误处理与调试全解析
#### 1. 错误处理
在调用 .NET 方法时,会出现一些特定的错误情况。例如,静态方法 `IPAddress.Parse` 会因为使用无效而引发异常。以下代码展示了函数在出现错误后继续执行的情况:
```powershell
function caller {
[IPAddress]::Parse('this is not an IP')
second
}
function second {
'second'
}
caller
```
##### 1.1 throw 与 ErrorAction
`throw` 关键字会引发终止错误,但当 `ErrorAction` 设置为 `SilentlyContinue` 时,`throw` 引发的错误会受到影响。以下是一个示例函数:
```powershell
function Invoke-Something {
[CmdletBinding()]
param ( )
throw 'Error'
Write-Host 'No error'
}
```
当以默认的 `Continue` 错误操作运行该函数时,会抛出错误,第二条命令不会执行:
```plaintext
PS> Invoke-Something
Exception:
Line |
5 | throw 'Error'
| ~~~~~~~~~~~~~
| Error
```
若将 `ErrorAction` 设置为 `SilentlyContinue` 或 `Ignore`,`throw` 会被忽略:
```plaintext
PS> Invoke-Something -ErrorAction SilentlyContinue
No error
```
若在父作用域中设置 `$ErrorActionPreference` 变量为 `SilentlyContinue`,也会出现相同的问题。
为了避免这种情况,可以将 `throw` 语句放在 `try` 块中,这样无论 `ErrorAction` 设置如何,都会触发 `catch` 块:
```powershell
function Invoke-Something {
[CmdletBinding()]
param ( )
try {
throw 'Error'
Write-Host 'No error'
} catch {
Write-Host 'An error occurred'
}
}
```
运行结果:
```plaintext
PS> Invoke-Something -ErrorAction SilentlyContinue
An error occurred
```
对于使用 `CmdletBinding` 属性的脚本,可以使用 `ThrowTerminatingError` 方法,它不受 `ErrorAction` 参数或 `ErrorActionPreference` 变量的影响:
```powershell
function Invoke-Something {
[CmdletBinding()]
param ( )
try {
throw 'Error'
Write-Host 'No error'
} catch {
$PSCmdlet.ThrowTerminatingError($_)
}
}
```
运行结果:
```plaintext
PS> Invoke-Something -ErrorAction SilentlyContinue
Exception: Error
```
为了建立一致的行为,有以下建议:
- 优先在函数、脚本和脚本块中使用 `CmdletBinding`。
- 使用 `throw` 时,仅在 `try` 块内使用。
- 使用 `ThrowTerminatingError` 方法来停止脚本执行。
- 创建非终止错误时,优先使用 `WriteError` 方法,因为它能正确设置 `$?` 的值。
- 调用可能引发错误的脚本时,应使用 `try` 块来预期和处理错误。
##### 1.2 子作用域中的终止错误
当调用一个在函数作用域内引发终止错误的函数时,若 `ErrorActionPreference` 为 `Continue`、`SilentlyContinue` 或 `Ignore`,终止错误不会导致脚本结束。例如:
```powershell
function Invoke-Something {
[CmdletBinding()]
param ( )
try {
throw 'Error'
} catch {
$PSCmdlet.ThrowTerminatingError($_)
}
}
& {
$ErrorActionPreference = 'Continue'
Invoke-Something
'After Invoke-Something'
}
```
运行结果:
```plaintext
Exception:
Line |
3 | Invoke-Something
| ~~~~~~~~~~~~~~~~
| Error
After Invoke
```
0
0
复制全文
相关推荐









