ForEach 与 Try/Catch 错误处理

Oat*_*oat 0 powershell try-catch

到目前为止,这是我的代码:

$Folders = Get-ChildItem -Path U:\Powershell\Move-Files\Clients |
           ?{$_.PsIsContainer} |
           Select -ExpandProperty FullName

Get-ChildItem -Path U:\Powershell\Move-Files\Individual | ?{
    !($_.PsIsContainer)
} | %{
    #Part of the file to match
    $File = ($_.name.substring(0,$_.basename.length-11))
    $File = ($File -split '_')[1] + ", " + ($File -split '_')[0]
    # Find matching Directory
    $Path = $Folders | ?{$_ -match $File}

    Move-Item -Path $_.FullName -Destination $Path -ErrorAction Silently Continue

    Write-Host "Moved $_.FullName to $Path"
}
Run Code Online (Sandbox Code Playgroud)

基本上,我有很多命名的文件First_Last (MMM yyyy).pdf,这会获取每个文件并以 的格式创建一个变量Last, First以便它可以进行部分匹配并将文件移动到目标文件夹(格式为Last, First ##-####)。这一切都很好,只是我在实现try/catch错误处理时遇到了麻烦。

我替换了以以下开头的行Move-Item

try {
  Move-Item -Path $_.FullName -Destination $Path -ErrorAction SilentlyContinue
  "Moved $_.FullName to $Path successfully" | Add-Content U:\Powershell\Move-Files\log.txt
} catch {
  "Error moving $_.FullName" | add-content U:\Powershell\Move-Files\log.txt
}
Run Code Online (Sandbox Code Playgroud)

几乎完美地工作,除了catch没有正确报告哪些文件没有被移动。该try部分在日志中读取得很好。但是catch只会在日志中读取以下内容:

错误移动 无法处理参数,因为参数“目标”的值为空。将参数“destination”的值更改为非空值..FullName

不知道如何修复它。

Ans*_*ers 5

块中的当前对象 ( $_)catch是错误/异常,而不是引发异常的操作的当前对象。如果要在错误消息中输出路径,则需要将其放入变量中:

try {
  $file = $_.FullName
  Move-Item -Path $file -Destination $Path -ErrorAction SilentlyContinue
  "Moved $file to $Path successfully" | Add-Content 'U:\Powershell\Move-Files\log.txt'
} catch {
  "Error moving $file" | Add-Content 'U:\Powershell\Move-Files\log.txt'
}
Run Code Online (Sandbox Code Playgroud)

附带说明:PowerShell 只对字符串进行简单的变量扩展。"$_.FullName"将扩展为$_后跟字符串 的字符串表示形式".FullName"。如果要扩展当前对象的属性,则需要一个子表达式:

"Error moving $($_.FullName)"
Run Code Online (Sandbox Code Playgroud)

字符串连接:

"Error moving " + $_.FullName
Run Code Online (Sandbox Code Playgroud)

或格式运算符:

"Error moving {0}" -f $_.FullName
Run Code Online (Sandbox Code Playgroud)