简体   繁体   中英

Powershell error handling using invoke-command calling .bat file

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 (ie 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}

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM