Senior Systems Engineer
Senior Systems Engineer

Reputation: 1139

Powershell to perform Test-NetConnection exception handling?

The below script to check the list of website connectivity is not working when one of the domain controllers is not contactable, and when the destination IP address is not responding?

How can this script be adjusted to always move on or On Error Resume Next, and then put the column "Exception Error".

Try
{
    $Array = @()
    $Servers = Get-ADDomainController -filter * | Select-Object -ExpandProperty Name
    $PortNumber = '443'
    $Array = Invoke-Command -cn $Servers {
        param ($PortNumber)
       
        $Destinations = "168.62.20.37", "www.pingdom.com","168.168.21.21","cloudmasters.com"
       
        $Object = New-Object PSCustomObject
        $Object | Add-Member -MemberType NoteProperty -Name "Servername" -Value "$env:computername - $((Resolve-DnsName -Name $env:computername -Type A).IPAddress)"
        $Object | Add-Member -MemberType NoteProperty -Name "Port" -Value $PortNumber
       
        Foreach ($Item in $Destinations)
        {
            $Result = Test-NetConnection -Port $PortNumber -cn $Item
            $Delay = $Result.'PingReplyDetails'.Roundtriptime | % { ("$_" + " ms") }
            $Object | Add-Member -Type NoteProperty -Name "Destination" -Value $Item -Force
            $Object | Add-Member -Type NoteProperty -Name "Ping Time" -Value $Delay -Force
            $Object | Add-Member -Type NoteProperty -Name "Ping" -Value $Result.PingSucceeded -Force
            $Object | Add-Member -Type NoteProperty -Name "TCP" -Value $Result.TcpTestSucceeded -Force
            $Object
        }
       
       
    } -ArgumentList $PortNumber -ErrorAction stop | Select-Object * -ExcludeProperty runspaceid, pscomputername, PSShowComputerName
}
Catch [System.Exception]{
    Write-host "Error" -backgroundcolor red -foregroundcolor yellow
    $_.Exception.Message
}


$Array | Out-GridView -Title "Results"

The script is a bit old since there is a lot of Add-Member Object in use. It is working, but not sure what's the suggested best practice to optimize for speed.

Upvotes: 0

Views: 2738

Answers (3)

Theo
Theo

Reputation: 61068

The try..catch should be inside the loop. Also, you could create a PsCustomObject for each item in the loop and fill in the details in the try and catch

Something like:

$Servers    = Get-ADDomainController -Filter * | Select-Object -ExpandProperty Name
$PortNumber = 443

$Array = Invoke-Command -ComputerName $Servers -ScriptBlock {
    param ($PortNumber)

    $Servername   = "$env:COMPUTERNAME - $((Resolve-DnsName -Name $env:COMPUTERNAME -Type A).IPAddress)"
    $Destinations = "168.62.20.37", "www.pingdom.com","168.168.21.21","cloudmasters.com"

    foreach ($Item in $Destinations) {
        # prepare an object to output
        $Object = [PSCustomObject]@{
            'Servername'      = $Servername
            'Port'            = $PortNumber
            'Destination'     = $Item
            'Ping Time'       = $null
            'Ping'            = $false
            'TCP'             = $false
            'Exception Error' = $null
        } 
        try {
            # capture warnings in variable $warnings and supress output using '3> $null'
            $Result = Test-NetConnection -Port $PortNumber -ComputerName $Item -ErrorAction Stop -WarningVariable warnings 3> $null

            $Object.'Ping Time'       = $Result.'PingReplyDetails'.Roundtriptime
            $Object.'Ping'            = $Result.PingSucceeded
            $Object.'TCP'             = $Result.TcpTestSucceeded
            $Object.'Exception Error' = $warnings -join ', '
        }
        catch {
            $Object.'Exception Error' = $_.Exception.Message
        }
        # output the object
        $Object
    }
} -ArgumentList $PortNumber | Sort-Object Servername

$Array | Select-Object * -ExcludeProperty RunspaceId, PSComputerName, PSShowComputerName | Out-GridView -Title "Results"

Upvotes: 1

Daniel Björk
Daniel Björk

Reputation: 2507

Move your Try-Catch statement into the foreach loop:

    $Array = @()
    $Servers = Get-ADDomainController -filter * | Select-Object -ExpandProperty Name
    $PortNumber = '443'
    $Array = Invoke-Command -cn $Servers {
        param ($PortNumber)
       
        $Destinations = "168.62.20.37", "www.pingdom.com","168.168.21.21","cloudmasters.com"
       
        $Object = New-Object PSCustomObject
        $Object | Add-Member -MemberType NoteProperty -Name "Servername" -Value "$env:computername - $((Resolve-DnsName -Name $env:computername -Type A).IPAddress)"
        $Object | Add-Member -MemberType NoteProperty -Name "Port" -Value $PortNumber
       
        Foreach ($Item in $Destinations)
        {
            Try
            {
                $Result = Test-NetConnection -Port $PortNumber -cn $Item
                $Delay = $Result.'PingReplyDetails'.Roundtriptime | % { ("$_" + " ms") }
                $Object | Add-Member -Type NoteProperty -Name "Destination" -Value $Item -Force
                $Object | Add-Member -Type NoteProperty -Name "Ping Time" -Value $Delay -Force
                $Object | Add-Member -Type NoteProperty -Name "Ping" -Value $Result.PingSucceeded -Force
                $Object | Add-Member -Type NoteProperty -Name "TCP" -Value $Result.TcpTestSucceeded -Force
                $Object
            }
            Catch [System.Exception]{
                Write-host "Error" -backgroundcolor red -foregroundcolor yellow
                $_.Exception.Message
            }
        }
       
       
    } -ArgumentList $PortNumber -ErrorAction stop | Select-Object * -ExcludeProperty runspaceid, pscomputername, PSShowComputerName




$Array | Out-GridView -Title "Results"

Upvotes: 1

Kluk
Kluk

Reputation: 135

I think you want something like this:

$Object += New-Object PSObject -Property @{
    Destination = [String]$Item;
    PingTime = [Int]$Delay;
    Ping = [Bool]$Result.PingSucceeded;
    TCP = [Bool]$Result.TcpTestSucceeded;
}

Upvotes: 1

Related Questions