【问题标题】:PowerShell Write-Output not working in try/catch block?PowerShell 写输出在 try/catch 块中不起作用?
【发布时间】:2017-09-17 14:03:02
【问题描述】:

下面是我的 Powershell 环境(通过 Get-Host 命令):

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

我有一个向资源发出 REST 请求的脚本——一切正常。

在测试时,我将 URL 更改为无效,以查看是否将错误消息写入输出文件——这是我感到困惑的地方。似乎将异常写入日志的唯一方法是使用 Write-Host。当我使用 Write-Output 时,异常消息永远不会写入日志文件。以下是我正在使用的代码:

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

根据这篇博文:using Write-Host should be avoided,但似乎 Write-Host 是我在输出文件中获取错误消息的唯一方法。

我的问题是:如何编写一个函数来发出 REST 请求并在成功时返回结果,但如果发生错误,将错误消息写入输出文件并返回 $null?

由于我对 PowerShell 相当陌生,因此我们将不胜感激。

【问题讨论】:

  • "# 如果使用 Write-Output - 没有任何内容写入输出文件??? # 必须使用 Write-Host 以将错误信息包含在输出文件中 - 为什么? “ - 这显然是不正确的,我输入了上次你问同样问题时演示的代码。你说你当时使用*>> 重定向所有输出流,写主机是流6,将被重定向;在这个版本中,您使用的是| out-file,它只捕获管道输出,它不会。并且管道输出不会输出文件,因为您在 $json 中捕获它,然后对 $json 不执行任何操作。
  • 是的 - 但我删除然后重新发布问题以更好地说明正在发生的事情 - 写入输出从未写入日志文件 - 所以我重新编写代码并编写了 log_write功能——一切正常;感谢您抽出时间回复;总是通过阅读回复来学习一些东西! ;)

标签: powershell


【解决方案1】:

好的,我完全放弃了重定向,而是写了一个函数,将参数写入日志文件,如下:

function log_write
{ 

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

   $piped | Out-File $log_file -Append

}

注意:$log_file 是在初始化时设置的,因为我需要为一周中的每一天设置一个新的日志文件名。

然后,我用 log_write 替换了 ALL Write-Output / Write-Host,即:

log_write "* REST Request Error:"

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

log_write $s

像魅力一样工作,异常消息被写入日志文件,没有任何以前的问题。

【讨论】:

  • 感谢您提供此解决方法。这个烦人的错误显示,PS 是在哪里创建的......
【解决方案2】:

据我所知Write-Host 只写给主机,没有别的。

在您的示例中,do_something 没有返回任何内容,因此您在日志文件中没有得到任何内容也就不足为奇了。

您可以这样做,但存在许多不同的方法:

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

【讨论】:

  • 我从示例中删除了很多代码,“do_something”实际上调用了其他几个使用 Write-Output 的函数;因此我需要将所有输出发送到日志文件。但同样,(目前)唯一有效的方法是我使用 Write-Host。如果我尝试使用: $_ | Out-File $logFile - 根据您在 catch/try 块中的建议附加,我得到: Out-File :该进程无法访问文件 'D:\temp\log_file.txt',因为它正在被另一个进程使用。毫无疑问,因为在调用 do_something 时 Out-File 已经打开了文件。我已经更新了我的原始帖子以显示这一点。
  • 据我所知,Write-Host 只写入主机,没有别的。 - 它写入流 6,它与 PS v5 中的写入信息相同,以上。可以重定向。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多