Go Premium for a chance to win a PS4. Enter to Win

x
?
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
Medium Priority
?
206 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 1000 total points
ID: 40624073
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 41

Assisted Solution

by:footech
footech earned 1000 total points
ID: 40624992
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
ID: 40651253
thanks and sorry for the delay
0

Featured Post

 The Evil-ution of Network Security Threats

What are the hacks that forever changed the security industry? To answer that question, we created an exciting new eBook that takes you on a trip through hacking history. It explores the top hacks from the 80s to 2010s, why they mattered, and how the security industry responded.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

It’s been over a month into 2017, and there is already a sophisticated Gmail phishing email making it rounds. New techniques and tactics, have given hackers a way to authentically impersonate your contacts.How it Works The attack works by targeti…
Recently we ran in to an issue while running some SQL jobs where we were trying to process the cubes.  We got an error saying failure stating 'NT SERVICE\SQLSERVERAGENT does not have access to Analysis Services. So this is a way to automate that wit…
Windows 8 came with a dramatically different user interface known as Metro. Notably missing from that interface was a Start button and Start Menu. Microsoft responded to negative user feedback of the Metro interface, bringing back the Start button a…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

824 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