Showing posts with label ip. Show all posts
Showing posts with label ip. Show all posts

Friday, September 7, 2007

Two PowerShell filters to aid with IP addresses


There are two major differences between functions and filters in PowerShell:

  1. The keyword, function vs filter.
  2. The available current variable inside the function/filter.

Both procedures can be used in pipelines.
When a function is used, the special variable $input is available to process through the input collection. For filters, the special variable $_ contains the current pipeline object.

Filter, as its name suggests will pass on only certain objects down the pipeline.
To demonstrate it, here are two filters to help where IP address are involved.

 

I have a text file were each line contains an IP address.

###### ip.txt #####

10.0.0.138
1.1.1.1111
192.168.2.1
10.0.0.101
10.0.0.102
10.0.0.103

###### EOF #######

 

I want to get the content of this file and operate ONLY on live hosts.
The first filter will validate the IP address and stream down the pipe only valid ones.
The second filter will ping each valid host passed and test its availability,.
The third, ForEach cmdlet,  will run some code on the filtered IPs.

 

filter Validate-IPAddress {
    trap{write-host "$_ <$input>" -f red -b black; continue;}   
    [System.Net.IPAddress]::Parse($_).IPAddressToString;   
}

 

filter Ping-Host{
    begin{
        # instantiate once for all piped objects
        $ping = new-object System.Net.NetworkInformation.Ping;
    }
    process{   
        # ping test
        $stat=$ping.Send($_).status;
        if($stat -ne "Success"){write-warning "$_ is not available <$stat>";}
        else {$_;}
    }   
}

 

# cat = Get-Content
# -f = foreground
# -b = background

cat ip.txt | Validate-IPAddress | Ping-Host | foreach {    
    write-host "$_ is ALIVE, run some code" -f green -b black
}

 

# colored output , just for demonstrating

10.0.0.138 is ALIVE, run some code
An invalid IP address was specified. <1.1.1.1111>
WARNING: 192.168.2.1 is not available <TimedOut>
10.0.0.101 is ALIVE, run some code
WARNING: 10.0.0.102 is not available <TimedOut>
10.0.0.103 is ALIVE, run some code

################################################

 

Here's the filters final version. You can see that only validated IPs and live hosts are processed.

 

filter Validate-IPAddress {
    trap{continue;}   
    [System.Net.IPAddress]::Parse($_).IPAddressToString;
}

filter Ping-Host{
    begin{ $ping = new-object System.Net.NetworkInformation.Ping; }
    process{ if($ping.Send($_).status -eq "Success") {$_;} }   
}

 

cat ip.txt | Validate-IPAddress | Ping-Host | foreach {
    write-host "$_ is ALIVE, run some code" -f green -b black
}

 

# output

10.0.0.138 is ALIVE, run some code
10.0.0.101 is ALIVE, run some code
10.0.0.103 is ALIVE, run some code

Monday, August 27, 2007

Validating IP addresses

The common way to validate IP addresses is with Regular expressions. This method helps determine whether a string is a valid IP address. It uses the Parse method of the system.net.ipaddress NET class.

The function returns a boolean value with respect to the tests result.

 

function Validate-IPAddress{
    param([string]$ip=$(throw "Missing IP address argument"))
    trap{$false; continue;}
    [bool][system.net.ipaddress]::Parse($ip);
}

 

 

# Some usage examples

>> Validate-IPAddress "192.168.1.27"
True

Validate-IPAddress "192.168.1.274"
False

 

# common if/else testing
>> $ip="192.168.1.27";
>> if(Validate-IPAddress $ip){
>> "$ip is Valid";
>> } else {
>> write-warning "$ip is NOT Valid";
>> }

192.168.1.27 is Valid

 

# test for false value
# -not logical operator can be replaced with "!"

>> $ip="192.168.1.274";
>> if(-not (Validate-IPAddress $ip)){
>> write-warning "$ip is NOT Valid";
>> }

WARNING: 192.168.1.274 is NOT Valid

Tuesday, August 7, 2007

IP decimal to binary conversion and back

 

Just playing around with IP numbers. here are two PowerShell one-liners for the job.

 

$ip = "192.168.0.1";

# convert to binary form
$sbin=[string]::join(".",($ip.split(".") | % {[System.Convert]::ToString($_,2).PadLeft(8,"0")}))   
$sbin


11000000.10101000.00000000.00000001

# convert the result back to decimal
[string]::join(".",($sbin.split(".") | % {[System.Convert]::ToByte($_,2)}))
192.168.0.1

This one-liners can be converted to functions in order to use them in the pipeline thus converting bulk ip numbers easily and PowerShelly ;)