Function accepting Parameter and Pipeline input

Ask your 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.
This topic is 14 years old and has exceeded the time allowed for comments. Please begin a new topic or use the search feature to find a similar but newer topic.
Locked
User avatar
tconley@semprautilities.com
Posts: 18
Last visit: Thu May 27, 2021 11:28 am

Function accepting Parameter and Pipeline input

Post 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.
User avatar
tconley@semprautilities.com
Posts: 18
Last visit: Thu May 27, 2021 11:28 am

Function accepting Parameter and Pipeline input

Post 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/
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Function accepting Parameter and Pipeline input

Post 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
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Function accepting Parameter and Pipeline input

Post 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.
This topic is 14 years old and has exceeded the time allowed for comments. Please begin a new topic or use the search feature to find a similar but newer topic.
Locked