Page 1 of 1

Function accepting Parameter and Pipeline input

Posted: Mon Mar 29, 2010 5:12 am
by tconley@semprautilities.com
I have been working on a function and I want it to be able to function correctly either getting input from the pipeline or from parameters being passed to it. I have gotten it work for Pipeline input but I am having trouble getting it to accept parameters as well.

Code: Select all

function get-netinfo ([string]$ipaddress=$null, [int]$NetClass=$null, [string]$SubNetMask=$null, $inputObject=$null) {
    Begin{
        $output= @()
        Write-Host "Begin:"
        if ($ipaddress -ne $null){
            $T ="" |Select-Object IPAddress, network, subnetmask, NetClass;
            $t.ipaddress    = $ipaddress
            $t.netclass        = $NetClass
            $t.subnetmask    = $SubNetMask
            $inputObject += $t
        }
        
    }
    
    Process{
            if (($inputObject -ne $null)){
            $f = "Processing:" + ($_.ipaddress) + " '" + $_.netclass +"' '" + $_.subnetmask + "'"
            Write-Host $f
    
            $T ="" |Select-Object IPAddress, network, subnetmask, NetClass;
            $Ntemp=""
            $Mtemp=""
            $nctemp=$_.netclass
            
            
            ForEach ($ele in $_.ipaddress.split(".")){$Ntemp += [convert]::tostring($ele, 2).padleft(8, "0")}
            
            if ($_.subnetmask -ne $null ) {
                ForEach ($ele in $_.subnetmask.split(".")){
                $Mtemp += [convert]::tostring($ele, 2).padleft(8, "0")
                $NCtemp = $Mtemp.indexof("0")
                }
            }
            Else {
                $Mtemp= (("").padright($nctemp,"1")).padright(32,"0")
                
            }
            
            $Ntemp = ($Ntemp.substring(0,$nctemp)).padright(32,"0")
            
            $t.ipaddress = $_.ipaddress
            
            $o1 = [convert]::toint32($Ntemp.substring(00,8),2)
            $o2 = [convert]::toint32($Ntemp.substring(08,8),2)
            $o3 = [convert]::toint32($Ntemp.substring(16,8),2)
            $o4 = [convert]::toint32($Ntemp.substring(24,8),2)
        
            $t.network         = "$o1.$o2.$o3.$o4"
        
            $o1 = [convert]::toint32($Mtemp.substring(00,8),2)
            $o2 = [convert]::toint32($Mtemp.substring(08,8),2)
            $o3 = [convert]::toint32($Mtemp.substring(16,8),2)
            $o4 = [convert]::toint32($Mtemp.substring(24,8),2)
        
            $t.subnetmask     = "$o1.$o2.$o3.$o4"
            $t.netclass = $nctemp
            
            $output += $t
            }
    }
        
        
    End{
        return $output
    }
    
}
Here is an example of how i passed it pipeline data and the output

Code: Select all

$to=@()

$t = "" |Select-Object ipaddress, netclass, subnetmask;
$t.ipaddress = "10.136.10.192"
$t.netclass = 24

$to += $t

$t = "" |Select-Object ipaddress, netclass, subnetmask;
$t.ipaddress = "10.136.106.50"
$t.subnetmask = "255.255.252.0"

$to += $t


$to | get-netinfo -ipaddress 11.128.9.15 -NetClass 8 | ft -autosize

Output:
Begin:
Processing:10.136.10.192 '24' ''
Processing:10.136.106.50 '' '255.255.252.0'

IPAddress     network      subnetmask    NetClass
---------     -------      ----------    --------
10.136.10.192 10.136.10.0  255.255.255.0       24
10.136.106.50 10.136.104.0 255.255.252.0       22
Example of paramenter input test

Code: Select all

get-netinfo -ipaddress 10.194.7.255 -netclass 22 | ft -autosize

Output:
Begin:
Processing: '' ''
You cannot call a method on a null-valued expression.
At :line:26 char:38
+             ForEach ($ele in $_.ipaddress.split <<<< (".")){$Ntemp += [convert]::tostring($ele, 2).padleft(8, "0")}
any ideas. I tried to add the parameters to the input object and it takes it but it doesn't itterate trough it.

Function accepting Parameter and Pipeline input

Posted: Mon Mar 29, 2010 6:25 am
by tconley@semprautilities.com
Actually you can use $_ inside of the process section of a function. I am just trying to make this handle data where it comes from parameter or pipeline.Reference information:http://huddledmasses.org/writing-better ... -pipeline/

Function accepting Parameter and Pipeline input

Posted: Mon Mar 29, 2010 9:04 am
by jvierra
Here is an example of doing it the V2 way.

Code: Select all

	
function Show-ProcessName{
  [CmdletBinding()]
  Param(
      [Parameter(
       Mandatory=$true,
       ValueFromPipeline=$true
      )]
      [string] $ProcessName
  )
  Process
  {
    write-host ("Process name is:$ProcessName")
  }
}
	
Show-ProcessName "DummyProc"
Show-ProcessName -ProcessName Dummy
Get-Process | Show-ProcessName

Functions built to work like CmdLets are more flexible and reliable.
jvierra2010-03-29 16:12:50

Function accepting Parameter and Pipeline input

Posted: Mon Mar 29, 2010 10:08 am
by jvierra
Your post from 'huddlledmasses' is older from V1 PowerShell. It shuold work in both however it may not be what you ae looking for.

I am not really sure what you are asking. If you check the $input or $_ then you know it is pipeling input or not and adjust accordingly.

What is not working?

You seem to be writng a pipeline function but it is not outputoing to teh pipeline but is saving weverything to the end. Just write all object to teh pipeline. Let PowerShell handle ther rest for you .

Here is one way of handling some of your dilemma.

Code: Select all

	
    Process{
            # if in pipeline then copy all args
            if ($_){
                $ipaddress = $_.IpAddress
                $NetClass = $_.NetClass
                $SubNetMask = $_.SubNetMask
            }
            $f = "Processing:" + ($ipaddress) + " '" + $netclass +"' '" + $SubNetMask + "'"
            Write-Host $f
    


What you are doing in te begin block seems to indicate an incompletre understanding of how PowerShell processes in a pipeline. None of this is necessary in a pipeline. Just create and write objects in the process block.

I also fail to see how the code is ever changubg the input. It moves it around but the output is identical to teh input.