2017-09-17 21 views
1

下面是我PowerShell的环境(通过get-host命令):PowerShell写入输出在try/catch块中不起作用?

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更改为无效,以查看是否将错误消息写入输出文件 - 这是我感到困惑的地方。看来写日志的唯一方法是使用写主机。当我使用写入输出时,异常消息从不写入日志文件。下面是我使用的代码:

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,然而,似乎写主机是我可以在输出文件中得到错误信息的唯一途径。

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

因为我对PowerShell相当绿色,任何意见将不胜感激。

+0

“*#如果使用写输出 - 没有写入输出文件???#必须使用写主机将错误信息包含在输出文件中 - 为什么?*” - 这显然不是真的,我把你之前提出过的问题展示出来的代码。你说过你使用'* >>'重定向所有输出流,而写主机是流6并且将被重定向;在这个版本中你正在使用'| out-file“,它只捕获流水线输出,不会。并且流水线输出不会出现,因为您在'$ json'中捕获它,然后对'$ json'执行任何操作。 – TessellatingHeckler

+0

正确 - 但我删除了,然后转发问题以更好地说明发生了什么 - 写输出从未被写入日志文件 - 所以我重写了代码并编写了一个log_write函数 - 一切正常现在应该;感谢你花时间发布回复;总是通过阅读答复来学习一些东西! ;) – bdcoder

回答

0

好了 - 我完全放弃对重定向,而是写了写参数到日志文件中的函数,如下所示:

function log_write 
{ 

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

    $piped | Out-File $log_file -Append 

} 

注:因为我需要一个新的日志文件名称为一周的每一天$ LOG_FILE设置为初始化。

然后,我更换了所有写输出/写主机与log_write,即:

log_write "* REST Request Error:" 

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

log_write $s 

就像一个魅力和异常信息写入日志文件中没有任何以前的问题。

0

据我所知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 
+0

我从我的例子中消除了很多代码,“do_something”实际上调用了其他几个使用Write-Output的函数;因此我需要将所有输出发送到日志文件。但是,再次,目前唯一可行的方法是使用写主机。如果我尝试使用:$ _ | Out-File $ logFile - 根据您在catch/try块中的建议添加,我得到:Out-File:进程无法访问文件'D:\ temp \ log_file.txt',因为它正在被另一个进程使用。毫无疑问,因为当调用do_something时Out-File已经打开文件。我已更新我的原始帖子以显示此内容。 – bdcoder

+0

*据我所知,写主机只写入主机,没有别的。* - 它写入流6,这是相同的写入信息在PS V5及以上。它可以被重定向。 – TessellatingHeckler

相关问题