Solved

I want to learn about exception handling in power shell I am reading and looking over the script now and really dont know what i am doing !

Posted on 2015-02-21
3
176 Views
Last Modified: 2015-03-07
I want this script to just list the found ips and then if it does not find them return a "*"
right now when I run it I get

I am not sure this is even an "exception"


Open in new window


nd
 
Test-Connection : Testing connection to computer '192.168.5x.39' failed: A non-recoverable error occurred during a database lookup
At C:\Users\Bks\Desktop\ipscan.ps1:8 char:47
+     $startip..$endip | foreach{test-connection <<<<  -ComputerName $startsubnet$_ -count 1} | select -expandproperty ipv4address | select -expandproperty ipaddresstostring | foreach{[System.Net.Dns]::GetHostByAddr
ess("$_")}
    + CategoryInfo          : ResourceUnavailable: (192.168.5x.39:String) [Test-Connection], PingException
    + FullyQualifiedErrorId : TestConnectionException,Microsoft.PowerShell.Commands.TestConnectionCommand
 
T$startrange = read-host "Enter a start IP"
$endrange = read-host "Enter an end IP"
$startsubnet = "$($startrange.Split(".")[0]).$($startrange.Split(".")[1]).$($startrange.Split(".")[2])."
$endsubnet = "$($endrange.Split(".")[0]).$($endrange.Split(".")[1]).$($endrange.Split(".")[2])."
if ($startsubnet -eq $endsubnet) {
    $startip = $($startrange.Split(".")[3])
    $endip = $($endrange.Split(".")[3])
    $startip..$endip | foreach{test-connection -ComputerName $startsubnet$_ -count 1} | select -expandproperty ipv4address | select -expandproperty ipaddresstostring | foreach{[System.Net.Dns]::GetHostByAddress("$_")}
} else {
    write-host "Start subnet was not the same as the end subnet"
}
0
Comment
Question by:NAMEWITHELD12
3 Comments
 
LVL 65

Accepted Solution

by:
RobSampson earned 250 total points
Comment Utility
Hi there, I'm just learning the finer details of Powershell myself, so hopefully I can explain what I have found with the exercise.

First, here is the code I have come up with:
$startrange = read-host "Enter a start IP"
$endrange = read-host "Enter an end IP"
$startsubnet = "$($startrange.Split(".")[0]).$($startrange.Split(".")[1]).$($startrange.Split(".")[2])."
$endsubnet = "$($endrange.Split(".")[0]).$($endrange.Split(".")[1]).$($endrange.Split(".")[2])."
if ($startsubnet -eq $endsubnet) {
    $startip = $($startrange.Split(".")[3])
    $endip = $($endrange.Split(".")[3])
    $startip..$endip | foreach{
        $lastoctet = $_
        $iptest = test-connection -ComputerName $startsubnet$lastoctet -count 1
        try {
            $iptest | select -expandproperty ipv4address -erroraction Stop | select -expandproperty ipaddresstostring | foreach{[System.Net.Dns]::GetHostByAddress("$_")}
        }
        catch {
            #Write-Host "Test-Connection failed for $startsubnet$lastoctet"
            $Prop = [Ordered]@{
                'Hostname'="<UNKNOWN>"
                'Aliases'="{}"
                'AddressList'="{$startsubnet$lastoctet}"
            }
            New-Object PsObject -Property $Prop
        }
    }
} else {
    write-host "Start subnet was not the same as the end subnet"
}

Open in new window


So we've had to break the code down a bit more from the ForEach loop to be able to branch into error handling scenarios.  We use Test-Connection to return the properties of a tested IP.  From trying an invalid IP, we can gather that the ipv4address property does not exist, so the "select -expandproperty ipv4address" fails.  To be able to catch this error, we run that section in a Try block, with the -ErrorAction Stop parameter for the cmdlet we expect to fail.

We do that so that instead of writing the error text, we can output some custom string or object.  In the Catch block, we create a new ordered hash table with the same properties that is otherwise output by a successful connection.  The "New-Object PsObject -Property $Prop" line instructs Powershell to create a new object from that hash table and pass it along the pipeline, which eventually gets output.

Finally, because Powershell identifies the custom object as having all the same properties as the inbuilt, returned object from GetHostByAddress, it automatically puts those together in the output.

Hopefully that helps.  I still have a lot more to learn, but I really like the way you can work along the pipeline with the right commands.

Regards,

Rob.
0
 
LVL 39

Assisted Solution

by:footech
footech earned 250 total points
Comment Utility
I'm slightly confused by one thing, you say you want the script to list the found ips and then if it does not find them return a "*", but I'm not quite sure what you mean by "found IPs".  Do you mean IPs that you could ping, or IPs that you could resolve to a name?  When testing the conditions, you could treat errors found as different or same.

Rob's on the right path, but the errors can come from two different places:
 1) from the Test-Connection cmdlet
 2) from the [System.Net.Dns]::GetHostByAddress static method

Try/Catch only catches terminating errors, and the error generated by Test-Connection is normally non-terminating, but we can change that by setting the -ErrorAction parameter to Stop.  If we want treat the errors differently, then we either need to make sure only one can occur in a particular Try block, or you can have multiple Catch blocks for a single Try block, each of which is set to handle a particular exception type.

Following along with Rob's suggestion of outputting a custom object with the same properties as that produced when no error is encountered (which is a good one in many cases), you get something like the below.  
Note:  the "{}" seen when outputting certain properties is indicative of an array, so if you're trying to mirror the normal object you may want to take that into account rather than just creating a string with the curly brackets even though it may look the same in some views.  It may be pedantry to correct that, but it may matter during further processing.

$startrange = read-host "Enter a start IP"
$endrange = read-host "Enter an end IP"
$startsubnet = "$($startrange.Split(".")[0]).$($startrange.Split(".")[1]).$($startrange.Split(".")[2])."
$endsubnet = "$($endrange.Split(".")[0]).$($endrange.Split(".")[1]).$($endrange.Split(".")[2])."
if ($startsubnet -eq $endsubnet) {
    $startip = $($startrange.Split(".")[3])
    $endip = $($endrange.Split(".")[3])
    $startip..$endip | foreach{
        $lastoctet = $_
        try {
            Test-Connection -ComputerName $startsubnet$lastoctet -Count 1 -ErrorAction Stop |
             Select -ExpandProperty Address |
             foreach { [System.Net.Dns]::GetHostByAddress($_) }
        }
        catch [System.Net.NetworkInformation.PingException] {
            #Write-Host "Test-Connection failed for $startsubnet$lastoctet"
            $Prop = [Ordered]@{
                    'Hostname' = "*"
                    'Aliases' = @()
                    'AddressList' = @("$startsubnet$lastoctet")
                    }
            New-Object PsObject -Property $Prop
        }
        catch [System.Management.Automation.MethodInvocationException] {
            $Prop = [Ordered]@{
                    'Hostname' = "<UNKNOWN>"
                    'Aliases' = @()
                    'AddressList' = @("$startsubnet$lastoctet")
                    }
            New-Object PsObject -Property $Prop
        }
    }
} else {
    Write-Host "Start subnet was not the same as the end subnet"
}

Open in new window

0
 
LVL 1

Author Closing Comment

by:NAMEWITHELD12
Comment Utility
thanks and sorry for the delay
0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

Are you one of those front-line IT Service Desk staff fielding calls, replying to emails, all-the-while working to resolve end-user technological nightmares? I am! That's why I have put together this brief overview of tools and techniques I use in o…
"Migrate" an SMTP relay receive connector to a new server using info from an old server.
In this video, we discuss why the need for additional vertical screen space has become more important in recent years, namely, due to the transition in the marketplace of 4x3 computer screens to 16x9 and 16x10 screens (so-called widescreen format). …
With the advent of Windows 10, Microsoft is pushing a Get Windows 10 icon into the notification area (system tray) of qualifying computers. There are many reasons for wanting to remove this icon. This two-part Experts Exchange video Micro Tutorial s…

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now