我一直在尝试在 powershell 中编写一个脚本,如果文件未通过 WinSCP 正确传输,则该脚本会重命名该文件。脚本看起来像这样:
# Variables
$error = 0
$currentFile = "test"
# Functions
function upload-files {
param(
$WinScpSession,
$LocalDirectory,
$FileType,
$RemoteDirectory
)
get-childitem $LocalDirectory -filter $FileType |
foreach-object {
# $_ gets the current item of the foreach loop.
write-output "Sending $_..."
$currentFile = "$($LocalDirectory)$($_)"
upload-file -WinScpSession $session -LocalDirectory "$($LocalDirectory)$($_)" -RemoteDirectory "$RemoteDirectory"
}
}
try
{
# Upload files
upload-files -WinScpSession $Session -LocalDirectory [PathToLocalDirectory] -FileType [FileType] -RemoteDirectory [PathToRemoteDirectoy]
}
catch
{
Write-Host "Error: $($_.Exception.Message)"
write-output $currentFile
$errorMoveLocation = copy-item -path "$currentFile" -destination "$currentFile.err" -passthru
Write-Host "Error File has been saved as $errorMoveLocation"
$error = 1
}
为了便于阅读,我删除了路径以及一些与该问题无关的 WinSCP 行。
当在upload-file函数之后添加一些破坏脚本的代码时,它将转到catch语句,我期望$currentFile变量是$($LocalDirectory)$($_),因为它被捕获了再次设置变量后。然而,变量的实际值是其启动时的原始“测试”值。我尝试将 $currentFile 的范围更改为两个脚本,但全局相同的问题仍然发生。我对 powershell 还比较陌生,这超出了我的专业知识。任何帮助将不胜感激,谢谢!
upload-files
(大概还有
upload-file
函数)仅发出非终止错误,而
try
/
catch
仅捕获终止错误。
upload-files
报告termination 错误,您有两个选择:
在调用它之前,(临时)将 $ErrorActionPreference
首选项变量设置为
'Stop'
,这会将非终止错误提升为终止错误。
高级(类似 cmdlet)函数,这使其支持 -ErrorAction
公共参数,允许您在每次调用的基础上传递
-ErrorAction Stop
以实现效果一样。
param(...)
属性装饰函数的
[CmdletBinding()]
块足以使其成为高级函数,使用单独参数
[Parameter()]
属性也是如此。
实施(a):
$oldErrorActionPref = $ErrorActionPreference
try
{
# Treat all errors as terminating
$ErrorActionPreference = 'Stop'
upload-files -WinScpSession $Session -LocalDirectory [PathToLocalDirectory] -FileType [FileType] -RemoteDirectory [PathToRemoteDirectoy]
}
catch
{
Write-Host "Error: $($_.Exception.Message)"
# ...
}
finally {
$ErrorActionPreference = $oldErrorActionPref
}
实施(b):
# ...
function upload-files {
[CmdletBinding()] # NOTE: This makes your function an *advanced* one.
param(
$WinScpSession,
$LocalDirectory,
$FileType,
$RemoteDirectory
)
# ...
}
try
{
# Pass -ErrorAction Stop to treat all errors as terminating
upload-files -ErrorAction Stop -WinScpSession $Session -LocalDirectory [PathToLocalDirectory] -FileType [FileType] -RemoteDirectory [PathToRemoteDirectoy]
}
catch
{
Write-Host "Error: $($_.Exception.Message)"
# ...
}