0

I'm trying to use a TRY-CATCH block to capture the error of an invoke-command I'm using to call a remote .bat file on another server.

If the .bat file fails (it's executing a SP on the local SQL server to run a backup), I would like Powershell to know the .bat file had an error and go into my CATCH block.

However, if the .bat file fails, it doesn't catch the error. If the call to the .bat file fails (because I purpose renamed it to something that doesn't exist), it still does not go into my CATCH block.

What am I missing?

$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
   }

I even tried it using an if...else block, and by this way it was a bit better. It would fail if the call to the .bat file failed because I renamed it to something that doesn't exist. However if the contents of the .bat file failed (i.e. the SP failed), it would not recognize that failure, but seem like it sees the call to the .bat file was successful, and not fail.

This was a more complete set of code, since my goal is to execute a 2nd batch file on the remote server upon successful completion of the first batch file on the remote server.

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}
Mofi
  • 46,139
  • 17
  • 80
  • 143
dnaman
  • 33
  • 2
  • 6
  • I haven't tried it myself, but from what I remember, Invoke-Command handles errors differently. I think you need to use the -AsJob parameter of Invoke-Command then use the Get-Job and Receive-Job cmdlets to handle the results of the remote Job. – CitizenRon Aug 25 '14 at 14:42
  • Would there be an alternative method to using invoke-command to call a .bat file on a remote system and try to build in my logic that way? – dnaman Aug 25 '14 at 15:14
  • Shouldn't you check $LASTEXITCODE instead of $? ? See here: http://stackoverflow.com/questions/10666035/powershell-difference-between-and-lastexitcode – David Brabant Aug 25 '14 at 15:24

2 Answers2

1

Other option is to handel it like this:
The invoked script into Try, Catch and 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
}


And invoke it like this:

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


Then return the result.

$objReturnData.strTrace
$objReturnData.strErrorMessage 


Now you can use If / Else to look if the job failed.

Patrick
  • 2,128
  • 16
  • 24
0

Thanks for the quick help everyone, I think I was overthinking what I was trying to.

Essentially there are 2 .bat files on my remote server, each calling a single stored procedure.

Now, instead of calling the .bat files, I am going to try a different approach and just call the SP directly. Upon successful completion of the first SP, call the 2nd. If not, then fail and send an email.

dnaman
  • 33
  • 2
  • 6