【问题标题】:Powershell error handling using invoke-command calling .bat file使用调用命令调用 .bat 文件的 Powershell 错误处理
【发布时间】:2014-08-25 14:20:06
【问题描述】:

我正在尝试使用 TRY-CATCH 块来捕获我用来调用另一台服务器上的远程 .bat 文件的调用命令的错误。

如果 .bat 文件失败(它正在本地 SQL 服务器上执行 SP 以运行备份),我希望 Powershell 知道 .bat 文件有错误并进入我的 CATCH 块。

但是,如果 .bat 文件失败,它不会捕获错误。如果对 .bat 文件的调用失败(因为我故意将其重命名为不存在的东西),它仍然不会进入我的 CATCH 块。

我错过了什么?

$scriptblock = {\\RemoteServerA\run.bat}
   try
   {
      Invoke-command –ComputerName $TargetComp -ScriptBlock $scriptblock -Credential $cred
   }
   catch
   {
      send-mailMessage -to "me@mail.ca" -subject "Remote .bat file failed" -from "you@mail.ca" -body ".bat file failed" -SmtpServer "smtp.me.ca" -credential $cred
   }

我什至尝试使用if...else 块,通过这种方式,它更好一点。如果对 .bat 文件的调用失败,它将失败,因为我将它重命名为不存在的东西。但是,如果 .bat 文件的内容失败(即 SP 失败),它不会识别该失败,但似乎看到对 .bat 文件的调用是成功的,而不是失败。

这是一组更完整的代码,因为我的目标是在远程服务器上成功完成第一个批处理文件后在远程服务器上执行第二个批处理文件。

Invoke-command –ComputerName $TargetComp –ScriptBlock $scriptblock -Credential $cred

if ($? -eq "True")
   {Invoke-command –ComputerName $TargetComp –ScriptBlock $scriptblock2 –credential $cred
   $output2 = $?

   if ($output2 -eq "True")
      {send-mailMessage -to "me@mail.ca" -subject "Backup Successful" -from "me@mail.ca" -body "Yippee" -SmtpServer "smtp.me" -credential $cred
      Write-Host "Backup Successful"
      }
   else {send-mailMessage -to "me@mail.ca" -subject "BackupDB failed" -from "me@mail.ca" -body "BackupDB failed" -SmtpServer "smtp.me" -credential $cred
      Write-Host "Backup Failed" + $output2
      }
   }
else {send-mailMessage -to "me@mail.ca" -subject "DatabaseCheckDB failed" -from "me@mail.ca" -body "DatabaseCheckDB failed" -SmtpServer "smtp.me" -credential $cred}

【问题讨论】:

  • 我自己没有尝试过,但据我记忆,Invoke-Command 处理错误的方式不同。我认为您需要使用 Invoke-Command 的 -AsJob 参数,然后使用 Get-Job 和 Receive-Job cmdlet 来处理远程作业的结果。
  • 是否有替代方法可以使用 invoke-command 在远程系统上调用 .bat 文件并尝试以这种方式构建我的逻辑?
  • 你不应该检查 $LASTEXITCODE 而不是 $? ?见这里:stackoverflow.com/questions/10666035/…

标签: windows powershell


【解决方案1】:

其他选择是这样处理它:
调用的脚本进入 Try、Catch 和 finally。

$scriptblock = {
    Try {
        $strErrorMessage = $null
        $strTrace = $null

        $strTrace += "Start work"
        #Do Work
        $strTrace += "Work ended with LASTEXITCODE: '$LASTEXITCODE '"

    }
    Catch {
        $strErrorMessage = "Work Failed. Error: $($($error[0].ToString()) $($error[0].InvocationInfo.PositionMessage))"
    }
    Finally {
        $objReturnData = "" | Select-Object -Property strErrorMessage, strTrace
        $objReturnData.strErrorMessage = $strErrorMessage
        $objReturnData.strTrace = $strTrace
    }
    Return $objReturnData
}


并像这样调用它:

$objReturnData = Invoke-command –ComputerName $TargetComp -ScriptBlock $scriptblock -Credential $cred


然后返回结果。

$objReturnData.strTrace
$objReturnData.strErrorMessage 


现在您可以使用 If / Else 查看作业是否失败。

【讨论】:

    【解决方案2】:

    感谢大家的快速帮助,我想我想太多了。

    我的远程服务器上基本上有 2 个 .bat 文件,每个文件调用一个存储过程。

    现在,我将尝试另一种方法,直接调用 SP,而不是调用 .bat 文件。成功完成第一个 SP 后,调用第二个。如果没有,则失败并发送电子邮件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-20
      • 1970-01-01
      相关资源
      最近更新 更多