PowerShell 异常处理完全指南

结构化异常捕获

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
try {
# 可能失败的操作
Get-Content -Path '不存在的文件.txt' -ErrorAction Stop
Invoke-RestMethod -Uri 'http://无效域名'
}
catch [System.IO.FileNotFoundException] {
Write-Warning "文件未找到: $($_.Exception.ItemName)"
}
catch [System.Net.WebException] {
Write-Warning "网络错误: $($_.Exception.Status)"
}
catch {
Write-Error "未捕获的异常: $_"
}
finally {
# 清理资源
Remove-Variable -Name '*temp*' -ErrorAction SilentlyContinue
}

错误处理模式

  1. 终止错误:使用-ErrorAction Stop强制转换
  2. 非终止错误:通过$Error自动变量追踪
  3. 类型过滤:catch块支持.NET异常类型匹配
  4. 错误记录:$Error[0]获取最近异常详细信息

最佳实践

  • 在函数内使用throw生成可预测异常
  • 避免空catch块吞噬异常
  • 使用-ErrorVariable参数捕获错误对象
  • 通过$ErrorView控制错误显示格式

PowerShell远程调试核心技术

远程会话调试配置

1
2
3
4
5
6
7
8
9
10
$session = New-PSSession -ComputerName Server01
Enter-PSSession -Session $session

# 设置远程断点
$bpParams = @{
ScriptName = 'RemoteScript.ps1'
Line = 42
Action = { Write-Host "远程变量值: $using:localVar" }
}
Set-PSBreakpoint @bpParams

异常捕获增强

1
2
3
4
5
6
7
8
9
10
function Invoke-RemoteCommand {
param([scriptblock]$ScriptBlock)

try {
Invoke-Command -Session $session -ScriptBlock $ScriptBlock -ErrorAction Stop
}
catch [System.Management.Automation.RemoteException] {
Write-Warning "远程执行异常: $($_.Exception.SerializedRemoteException.Message)"
}
}

调试信息传输

1
2
3
4
5
6
7
8
9
10
# 创建调试信息通道
$debugStream = Register-ObjectEvent -InputObject $session -EventName DebugDataAdded -Action {
param($source, $eventArgs)
$debugRecord = $eventArgs.DebugRecord
[PSCustomObject]@{
时间戳 = Get-Date
调试级别 = $debugRecord.Level
详细信息 = $debugRecord.Message
}
}

典型应用场景

  1. 生产环境实时诊断
  2. 集群脚本批量调试
  3. 受限会话权限分析
  4. 跨域脚本问题追踪

安全注意事项

  • 使用受限端点配置
  • 加密调试信道通信
  • 清理临时调试会话
  • 审计调试日志留存

PowerShell错误处理核心机制

基础错误捕获结构

1
2
3
4
5
6
7
8
9
10
11
12
try {
Get-Content 'nonexistent.txt' -ErrorAction Stop
}
catch [System.IO.FileNotFoundException] {
Write-Host "文件未找到: $($_.Exception.Message)"
}
catch {
Write-Host "未知错误: $($_.Exception.GetType().FullName)"
}
finally {
# 清理资源代码
}

错误变量解析

1
2
3
4
# 自动变量应用示例
$Error[0] | Format-List * -Force
$Error.Clear()
$ErrorActionPreference = 'Continue'

自定义错误抛出

1
2
3
4
5
6
function Validate-Range {
param([int]$Value)
if ($Value -notin 1..100) {
throw [System.ArgumentOutOfRangeException]::new('Value')
}
}

最佳实践

  1. 优先使用强类型异常捕获
  2. 合理设置ErrorActionPreference
  3. 保持finally块简洁
  4. 记录完整错误堆栈信息