0

I basically have this simple powershell script that executes an ssrs report url and saves it to the network.

It usually runs fine, but sometimes it times out and when it does, it still says it succeeded. I've tried a handful of things with no luck.

A simplified version of my script looks like this:

-----------------------------
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"}
-------------------------------

I've tried stuff like this with no luck:

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

and

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

The timeout error I'm dealing with is:

Exception calling "GetResponse" with "0" argument(s): "The operation has timed out" At C:\data\powershell\script.ps1:9 char:49 + [Net.HttpWebResponse] $result = $req.GetResponse <<<< () + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : DotNetMethodException

You cannot call a method on a null-valued expression. At C:\data\powershell\script.ps1:10 char:48 + [IO.Stream] $stream = $result.GetResponseStream <<<< () + CategoryInfo : InvalidOperation: (GetResponseStream:String) [], RuntimeException + FullyQualifiedErrorId : InvokeMethodOnNull

You cannot call a method on a null-valued expression. At C:\data\powershell\script.ps1:18 char:38 + $count = $stream.Read <<<< ($buffer, 0, $buffer.Length) + CategoryInfo : InvalidOperation: (Read:String) [], RuntimeException + FullyQualifiedErrorId : InvokeMethodOnNull

You cannot call a method on a null-valued expression. At C:\data\powershell\script.ps1:23 char:14 + $stream.Close <<<< () + CategoryInfo : InvalidOperation: (Close:String) [], RuntimeException + FullyQualifiedErrorId : InvokeMethodOnNull

Any help would be greatly appreciated. I assume this should be fairly easy, just don't have the correct syntax ? Thanks

Jay
  • 455
  • 3
  • 17
  • 34
  • What version of powershell are you using? Have you considered using Invoke-WebRequest as part of PS version 3? – Colyn1337 Oct 04 '13 at 14:04

3 Answers3

1

Maybe you can use try/catch to deal with that part like this:

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

catch {
 return 1
}

You can apply the same technique in other places where you suspect code is not doing what it is supposed to do like:

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

catch {
 return 1
}

Once you detect where the issue is happening, you could then look into exception like

catch { write-warning $_ ; exit 1 }
Adil Hindistan
  • 6,351
  • 4
  • 25
  • 28
  • Thanks but I tried putting this in with no luck. It ran through the process, DID NOT create the files, but still gave the output "success". – Jay Oct 04 '13 at 15:24
  • This code is addressing the problem about 'timeout' you mentioned. However, the issue you are referring now is happening later on. You might use try/catch around file creation as well. – Adil Hindistan Oct 04 '13 at 16:32
  • This led me to something I got to work. By using the Try/Catch as suggested, and on catch returning 11 for example. Then when I call the function I did this: `$var = RunReport "$url" "$outputfile" If($var -ne 11) {Success code} Else {fail code}` thanks [link](http://www.manning-sandbox.com/thread.jspa;jsessionid=RhxMA3gbFwd3mWwe?messageID=57987) – Jay Oct 04 '13 at 17:21
0

The 'cannot call a method on a null-valued expression' errors are all stemming from the fact that the .GetResponse method is failing with a timeout, leaving the $result variable unassigned. The simplest change would be to put the rest of the script (after "$result = $req.GetResponse()") into an "if ($result) {}" block. You can then use a "then {}" block to do your error handling.

A more advanced method would be to use try {} and catch {} blocks, to catch the actual timeout exception and handle it properly.

jbsmith
  • 1,616
  • 13
  • 10
  • I'm very new at powershell, and tried the try/catch solution below with no luck. Can you provide sample code that I can try please? Much appreciated!! – Jay Oct 04 '13 at 15:26
0

You have two problems:

  1. The timeouts (and the cascading errors from that)

  2. Your RunReport function doesn't ever return anything.

For #2, you can't test something that doesn't exist. So make your function return some kind of success/fail indicator to the caller.

For #1, when you call GetResponse() you need to wrap it in a try/catch block, catch the exception, and exit the function with the appropriate status returned to the caller.

You might want to look at this SO post about calling SSRS using SOAP methods as well.

Community
  • 1
  • 1
alroc
  • 27,574
  • 6
  • 51
  • 97