0
votes

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
2
On which line do you get the error message? What did you try to debug your code?Clijsters
Do you have quotes around the message after Write-Host? i.e. Write-Host "Request to $CommonName took $AverageResponseTime ms in average" -ForegroundColor Green JohnLBevan
in the last line that I just added to the original question, I missed that sorry.Luis Valencia
ps. FYI it's generally recommended that you avoid Write-Host for most scenarios; see this post for more: stackoverflow.com/questions/38523369/…JohnLBevan
Yeah, so $results is empty. It should be a list-like object where you add your items to.Clijsters

2 Answers

2
votes

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.

1
votes

@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