【问题标题】:Powershell - simply checking if a function completed successfully or not (times out)Powershell - 只需检查功能是否成功完成(超时)
【发布时间】:2013-10-11 11:11:24
【问题描述】:

我基本上有这个简单的 powershell 脚本,它执行一个 ssrs 报告 url 并将其保存到网络。

它通常运行良好,但有时会超时,当它超时时,它仍然说它成功了。我尝试了一些没有运气的事情。

我的脚本的简化版本如下所示:

-----------------------------
function RunReport($url,$outputfile) {
# // create a request
[Net.HttpWebRequest] $req = [Net.WebRequest]::create($url)
$req.Method = "GET"
$req.Timeout = 600000 # = 10 minutes

# // Set credentials
$req.UseDefaultCredentials = $true

#echo  "Getting Response"
[Net.HttpWebResponse] $result = $req.GetResponse()
[IO.Stream] $stream = $result.GetResponseStream()

#[IO.StreamReader] $reader = New-Object IO.StreamReader($stream)
[System.IO.FileStream]$writeStream = New-Object System.IO.FileStream($outputfile, [System.IO.FileMode]::Create);

# // write to file
[byte[]]$buffer = new-object byte[] 4096
[int]$total = [int]$count = 0
do
{
 $count = $stream.Read($buffer, 0, $buffer.Length)
 $writeStream.Write($buffer, 0, $count)
} while ($count -gt 0)
$writeStream.Close()
#$stream.flush()
$stream.Close()
}


$url=...
$outputfile=...

IF(RunReport "$url" "$outputfile")
{Write-Host "Success"}
ELSE
{Write-Host "Failed"}
-------------------------------

我尝试过这样的事情,但没有运气:

RunReport "$url" "$outputfile"
If($?)
    {Write-Host "Success"}
ELSE
    {Write-Host "Failed"}

RunReport "$url" "$outputfile"
If($? -eq true)
    {Write-Host "Success"}
ELSE
    {Write-Host "Failed"}

我正在处理的超时错误是:

使用“0”参数调用“GetResponse”的异常:“操作已超时” 在 C:\data\powershell\script.ps1:9 char:49 + [Net.HttpWebResponse] $result = $req.GetResponse

您不能在空值表达式上调用方法。 在 C:\data\powershell\script.ps1:10 char:48 + [IO.Stream] $stream = $result.GetResponseStream

您不能在空值表达式上调用方法。 在 C:\data\powershell\script.ps1:18 char:38 + $count = $stream.Read

您不能在空值表达式上调用方法。 在 C:\data\powershell\script.ps1:23 char:14 + $stream. 关闭

任何帮助将不胜感激。我认为这应该很容易,只是没有正确的语法?谢谢

【问题讨论】:

  • 你用的是什么版本的powershell?您是否考虑过将 Invoke-WebRequest 作为 PS 版本 3 的一部分?

标签: powershell reporting-services


【解决方案1】:

也许您可以像这样使用 try/catch 来处理该部分:

try {
 [Net.HttpWebResponse] $result = $req.GetResponse() 
}

catch {
 return 1
}

你可以在你怀疑代码没有做它应该做的事情的其他地方应用相同的技术:

try { 
[System.IO.FileStream]$writeStream = New-Object System.IO.FileStream($outputfile, [System.IO.FileMode]::Create);
}

catch {
 return 1
}

一旦您检测到问题发生在哪里,您就可以像这样查看异常

catch { write-warning $_ ; exit 1 }

【讨论】:

  • 谢谢,但我试着把它放进去,但没有运气。它运行了整个过程,没有创建文件,但仍然给出了输出“成功”。
  • 这段代码解决了你提到的“超时”问题。但是,您现在提到的问题稍后会发生。您也可以使用 try/catch 来创建文件。
  • 这让我找到了我必须工作的东西。通过按照建议使用 Try/Catch,例如在 catch 返回 11 时。然后,当我调用该函数时,我这样做了:$var = RunReport "$url" "$outputfile" If($var -ne 11) {Success code} Else {fail code}Thanks link
【解决方案2】:

“无法在空值表达式上调用方法”错误均源于 .GetResponse 方法因超时而失败,导致 $result 变量未分配。最简单的更改是将脚本的其余部分(在“$result = $req.GetResponse()”之后)放入“if ($result) {}”块中。然后,您可以使用“then {}”块进行错误处理。

更高级的方法是使用 try {} 和 catch {} 块,捕捉实际的超时异常并正确处理。

【讨论】:

  • 我是 powershell 的新手,尝试了下面的 try/catch 解决方案,但没有成功。你能提供我可以尝试的示例代码吗?非常感谢!
【解决方案3】:

你有两个问题:

  1. 超时(以及由此产生的级联错误)

  2. 您的 RunReport 函数不会返回任何内容。

对于#2,你不能测试不存在的东西。所以让你的函数向调用者返回某种成功/失败指示符。

对于 #1,当您调用 GetResponse() 时,您需要将其包装在 try/catch 块中,捕获异常,然后退出函数并将适当的状态返回给调用者。

您可能还想查看 this SO post 关于使用 SOAP 方法调用 SSRS 的信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-21
    • 1970-01-01
    • 1970-01-01
    • 2019-12-04
    • 2012-03-04
    • 1970-01-01
    相关资源
    最近更新 更多