我正在尝试找出在 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 进行异常处理是最佳实践
答案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,但这不是这里的主题。