Function accepting Parameter and Pipeline input

Ask your Windows PowerShell-related questions, including questions on cmdlet development!
Forum rules
Do not post any licensing information in this forum.

Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
Locked
User avatar
tconley@semprautilities.com
Posts: 13
Joined: Fri Dec 11, 2009 9:09 am

Function accepting Parameter and Pipeline input

Post by tconley@semprautilities.com » Mon Mar 29, 2010 5:12 am

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.

User avatar
tconley@semprautilities.com
Posts: 13
Joined: Fri Dec 11, 2009 9:09 am

Function accepting Parameter and Pipeline input

Post by tconley@semprautilities.com » Mon Mar 29, 2010 6:25 am

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/

User avatar
jvierra
Posts: 13798
Joined: Tue May 22, 2007 9:57 am
Contact:

Function accepting Parameter and Pipeline input

Post by jvierra » Mon Mar 29, 2010 9:04 am

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

User avatar
jvierra
Posts: 13798
Joined: Tue May 22, 2007 9:57 am
Contact:

Function accepting Parameter and Pipeline input

Post by jvierra » Mon Mar 29, 2010 10:08 am

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.

Locked