Powershell - 错误处理 (Try/Catch) 最佳实践

Powershell - 错误处理 (Try/Catch) 最佳实践

我正在尝试找出在 Powershell 脚本中使用 Try/Catch 错误处理的“最正确”方法。我有一个问题,对于以下脚本:对于每个文件,我正在执行 Copy-Item、Move-Item,然后对文件执行一个函数。我会对这三个命令中的每一个都执行一次 try catch 吗?这似乎不对,因为如果任何一个失败,我都不想继续。或者我应该只使用一个 Try/Catch 并在每个 cmdlet 后添加 -ErrorVariable 参数,然后在 Catch 中使用一些查询逻辑来确定这三个命令中的哪一个出错了?如果是这样,我如何找出创建了哪个 ErrorVariable(CopyErr、MoveErr)?

选项一:

($hash = @(Get-ChildItem C:\DIR -Recurse -Include *.txt) | Where {$_.length -gt 0}) | ForEach-Object {
    Try {
        Copy-Item $_ -Destination C:\DIR2\ -Force -ErrorAction Stop -ErrorVariable CopyErr
        Move-Item $_ -Destination C:\ARCHIVE\$($_.BaseName).$(Get-Date -f "yyyy-MM-dd_hhmmss").txt -Force -ErrorAction Stop -ErrorVariable MoveErr
        Start-Process SomeExternalProcess.exe -PassThru
    }
    Catch {
        "logic to determine which cmd failed"
    }

选项二:

 ($hash = @(Get-ChildItem C:\DIR -Recurse -Include *.txt) | Where {$_.length -gt 0}) | ForEach-Object {
    Try {
        Copy-Item $_ -Destination C:\DIR2\ -Force -ErrorAction Stop
    }
    Catch {
        "Copy Error"
    }
     Try {
        Move-Item $_ -Destination C:\ARCHIVE\$($_.BaseName).$(Get-Date -f "yyyy-MM-dd_hhmmss").txt -Force -ErrorAction Stop
    }
    Catch {
        "Move Error"
    }
     Try {
        Start-Process SomeExternalProcess.exe -PassThru
    }
    Catch {
        "Process Error"
    }
}

答案1

您实际上没有遇到代码问题。您询问的是意见。征求意见会给您带来广泛的回应。

如果你已有的方法对你有用,那么就保留它。然而,这里真正重要的是你真正想要捕获哪种错误。

终止 / 非终止 / 两者兼而有之?… 以及在哪个阶段…

MS 没有针对 PowerShell 的官方最佳实践,但有很多针对某些项目提出了看法。

所以,这是一个广泛的话题,因此,给出一个简单的基于代码的回应确实是一个挑战。

顺便说一句……Try/Catch - 错误处理通常不是 PowerShell 特有的东西。它几乎在每种主要编程语言中都存在多年。因此,参考其他语言中的指南也是明智的。

看看这些:

例外情况的最佳实践

https://docs.microsoft.com/en-us/dotnet/standard/exceptions/best-practices-for-exceptions

C# 异常处理最佳实践

https://stackify.com/csharp-exception-handling-best-practices

Windows PowerShell

https://docs.microsoft.com/en-us/powershell/developer/windows-powershell

PowerShell 标准库:构建可在 Windows PowerShell 和 PowerShell Core 上运行的单一模块 https://blogs.msdn.microsoft.com/powershell/2018/08/06/powershell-standard-library-build-single-module-that-works-across-windows-powershell-and-powershell-core

PowerShell实践和风格

https://github.com/PoshCode/PowerShellPracticeAndStyle

PowerShell 脚本最佳实践

https://martin77s.wordpress.com/2014/06/17/powershell-scripting-best-practices

Powershell - 推荐的编码风格

https://lazywinadmin.com/2011/06/powershell-recommended-coding-style.html

PowerShell 的推荐编码风格是什么?

https://stackoverflow.com/questions/2025989/what-is-the-recommended-coding-style-for-powershell

也可以看看:

为什么使用 try catch 进行异常处理是最佳实践

https://stackoverflow.com/questions/14973642/how-using-try-catch-for-exception-handling-is-best-practice

答案2

抱歉,我回答了一个已接受的答案。

以下是对我有用的方法,移动 25k 个文件夹:

Move-Item -Path '001DAB77' -Destination '..\..\Archive\001DAB77'
$errorCheckFine = $?
( (Get-Date -Format G) + '> ' + $errorCheckFine + ':001DAB77') | Add-Content '..\..\Archive\move.log'

和下一个文件夹

Move-Item -Path '001DAB78' -Destination '..\..\Archive\001DAB78'
$errorCheckFine = $?
( (Get-Date -Format G) + '> ' + $errorCheckFine + ':001DAB78') | Add-Content '..\..\Archive\move.log'

move.log文件中的输出:

2024-01-30 08:46:06> 真实:001DAB78

是的,有更好的方法来获取所有 24k 文件夹,使用 Import-Csv 和 foreach,但这不是这里的主题。

相关内容