bdcoder
bdcoder

Reputation: 3781

PowerShell Write-Output not working in try/catch block?

Below is my Powershell environment (via the Get-Host command):

Name             : Windows PowerShell ISE Host
Version          : 5.1.15063.608
InstanceId       : 46c51405-fc6d-4e36-a2ae-09dbd4069710
UI               : System.Management.Automation.Internal.Host.InternalHostUserInterface
CurrentCulture   : en-US
CurrentUICulture : en-US
PrivateData      : Microsoft.PowerShell.Host.ISE.ISEOptions
DebuggerEnabled  : True
IsRunspacePushed : False
Runspace         : System.Management.Automation.Runspaces.LocalRunspace

I have a script that makes a REST request to a resource -- everything works fine.

While testing, I changed the URL to be invalid to see if error messages are written to the output file -- this is where I am confused. It appears that the only way to write exceptions to the log is by using Write-Host. When I use Write-Output the exception messages are NEVER written to the log file. Below is the code I am using:

function rest_request( $method, $uri )
{

   # Code here create @req dictionary

   try {

      $json = Invoke-RestMethod @req 

   } catch {

      # If using Write-Output - Nothing is written to output file???
      # MUST use Write-Host for error info to be included in output file - WHY?

      Write-Host "* REST Request Error:"

      Write-Host $error[0] | Format-List -force

      $json = $null

   }

   return $json

}

function do_something()
{

    Write-Output "Start..."

    # other functions called here but removed for clarity.
    # The other functions contain Write-Output statements
    # which are showing in the log file.

    # Issue REST request with invalid URL to cause exception ...

    $json = rest_request "Get" "https://nowhere.com/rest/api" 

    Write-Output "Done."

}

do_something | Out-File "D:\temp\log_file.txt" -Append

According to this blog post: using Write-Host should be avoided, and yet, it seems that Write-Host is the only way I can get error messages in the output file.

My question is: How do you write a function that makes a REST request and returns the result if successful, but if an error occurs, write the error message to an output file and return $null?

As I am fairly green when it comes to PowerShell, any advice would be appreciated.

Upvotes: 2

Views: 3253

Answers (2)

bdcoder
bdcoder

Reputation: 3781

Ok - I gave up completely on redirection and instead wrote a function that writes the parameter to the log file, as follows:

function log_write
{ 

   param
   (
      [Parameter(ValueFromPipeline=$true)] $piped
   )

   $piped | Out-File $log_file -Append

}

Note: $log_file is set at initialization as I needed a new log file name for each day of the week.

Then, I replaced ALL Write-Output / Write-Host with log_write, i.e.:

log_write "* REST Request Error:"

$s = $error[0] | Format-List -force

log_write $s

Works like a charm and exceptions messages are written to the log file without any of the previous issues.

Upvotes: 1

sodawillow
sodawillow

Reputation: 13176

As far as I know Write-Host only writes to the host, nothing else.

In your example, do_something does not return anything, so it's no wonder you don't get anything in the log file.

Here is how you could do it, but many different approaches exist:

function Send-RESTRequest {

    Param($method, $uri, $logFile)

    # Code here create @req dictionary

    try {

        # make sure exception will be caught
        $json = Invoke-RestMethod @req -ErrorAction Stop

    } catch {

        # send exception details to log file
        $_ | Out-File $logFile -Append

        $json = $null
    }

    return $json

}

function Do-Something {
    # Issue REST request with invalid URL to cause exception ...

    $json = Send-RESTRequest -method "Get" -uri "https://nowhere.com/rest/api" -logFile "D:\temp\log_file.txt"
}

Do-Something

Upvotes: 0

Related Questions