2

I have a powershell script that measures download time on some pages, however I get the error above, I am unsure what I am doing wrong

error is

Cannot bind argument to parameter 'InputObject' because it is null.

function ResponseTime($CommonName,$URL, $environment) 
{ 
    $Times = 5
    $i = 0 
    $TotalResponseTime = 0 
      Write-HOst $URL
    While ($i -lt $Times) { 
        $Request = New-Object System.Net.WebClient 
        $Request.UseDefaultCredentials = $true 
        $Start = Get-Date 
        Write-HOst $URL
        $PageRequest = $Request.DownloadString($URL) 
        $TimeTaken = ((Get-Date) - $Start).TotalMilliseconds 
        $Request.Dispose() 
        $i ++ 
        $TotalResponseTime += $TimeTaken 
    } 

    $AverageResponseTime = $TotalResponseTime / $i 
    Write-Host Request to $CommonName took $AverageResponseTime ms in average -ForegroundColor Green 

    $details = @{            
        Date             = get-date              
        AverageResponseTime     = $AverageResponseTime              
        ResponseTime      = $Destination 
        Environment = $environment
    }                           
    $results += New-Object PSObject -Property $details
    $random = Get-Random -minimum 1 -maximum 30
    Start-Sleep -s $random
} 

#PRODUCTION
ResponseTime -commonname 'app homepage' -URL 'https://url1' -environment 'PRODUCTION'
ResponseTime -commonname 'department homepage' -URL 'https://url2' -environment 'PRODUCTION'

$results | export-csv -Path c:\so.csv -NoTypeInformation
8
  • 1
    On which line do you get the error message? What did you try to debug your code? Commented Oct 6, 2017 at 11:53
  • Do you have quotes around the message after Write-Host? i.e. Write-Host "Request to $CommonName took $AverageResponseTime ms in average" -ForegroundColor Green Commented Oct 6, 2017 at 11:55
  • in the last line that I just added to the original question, I missed that sorry. Commented Oct 6, 2017 at 11:55
  • ps. FYI it's generally recommended that you avoid Write-Host for most scenarios; see this post for more: stackoverflow.com/questions/38523369/… Commented Oct 6, 2017 at 11:56
  • Yeah, so $results is empty. It should be a list-like object where you add your items to. Commented Oct 6, 2017 at 11:57

2 Answers 2

2

Reviewing your last edit, it seems that $results simply returns $null (As your error says)

The only line setting $results is $results += New-Object PSObject -Property $details

It is not in the scope of your Export-CSV call and - even if it would, $results could be empty, if this line is not called.

You should IMHO set it to e.g. an ArrayList like follows:

$results = New-Object -TypeName System.Collections.ArrayList

And add items to it via

$times = ResponseTime -commonname '' #etc
$results.Add($times) | Out-Null

This gives you an ArrayList - even if there are no items in it - which can easily be transformed to CSV and other formats.

Sign up to request clarification or add additional context in comments.

Comments

1

@Clijsters has given the correct answer; i.e. the issue being the scope of your $results variable.

This answer just provides a bit of a code review to help you with other bits going forwards...

function Get-ResponseTime { 
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [string]$CommonName
        ,
        [Parameter(Mandatory = $true)]
        [string]$URL
        , 
        [Parameter(Mandatory = $true)]
        [string]$Environment
        , 
        [Parameter(Mandatory = $false)]
        [int]$Times = 5
    )    
    [System.Int64]$TotalResponseTime = 0 
    [System.Diagnostics.Stopwatch]$stopwatch = New-Object 'System.Diagnostics.Stopwatch'
    Write-Verbose "Processing URL: $URL"
    1..$times | foreach-object {
        [System.Net.WebClient]$Request = New-Object 'System.Net.WebClient' 
        $Request.UseDefaultCredentials = $true 
        Write-Verboset "Call $_ to URL: $URL"
        $stopwatch.Restart()
        $PageRequest = $Request.DownloadString($URL) 
        $stopwatch.Stop()
        $TimeTaken = $stopwatch.Elapsed.TotalMilliseconds 
        $Request.Dispose() 
        $TotalResponseTime += $TimeTaken 
    } 

    $AverageResponseTime = $TotalResponseTime / $Times 
    Write-Verbose "Request to $CommonName took $AverageResponseTime ms on average" 

    $details = @{            
        Date             = get-date              
        AverageResponseTime     = $AverageResponseTime              
        #ResponseTime      = $Destination #this is not declared anywhere / don't know what this field's for
        Environment = $environment
    }                           
    Write-Output (New-Object 'PSObject' -Property $details)
    #do you really want a delay here?  Doesn't make much sense... may make sense to include a delay in the above loop; i.e. to stagger your tests?
    #$random = Get-Random -minimum 1 -maximum 30
    #Start-Sleep -s $random
} 

#PRODUCTION
[PSObject[]]$results = @(
    (Get-ResponseTime -commonname 'app homepage' -URL 'https://url1' -environment 'PRODUCTION' -Verbose)
    ,(Get-ResponseTime -commonname 'department homepage' -URL 'https://url2' -environment 'PRODUCTION' -Verbose)
)
$results | Export-Csv -LiteralPath 'c:\so.csv' -NoTypeInformation

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.