How to write an extended PowerShell function that can work with both channels in objects and objects, get from the parameter value?

I am writing a function Chunk-Objectthat can split an array of objects into auxiliary arrays. For example, if I pass it an array @(1, 2, 3, 4, 5)and point the 2elements to a piece, then it will return 3 arrays @(1, 2), @(3, 4)and @(5). In addition, the user can provide an optional parameter scriptblockif they want to process each element before cutting them into submatrices. Now my code is:

function Chunk-Object()
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory = $true,
                   ValueFromPipeline = $true,
                   ValueFromPipelineByPropertyName = $true)] [object[]] $InputObject,
        [Parameter()] [scriptblock] $Process,
        [Parameter()] [int] $ElementsPerChunk
    )

    Begin {
        $cache = @();
        $index = 0;
    }

    Process {
        foreach($o in $InputObject) {
            $current_element = $o;
            if($Process) {
                $current_element = & $Process $current_element;
            }
            if($cache.Length -eq $ElementsPerChunk) {
                ,$cache;
                $cache = @($current_element);
                $index = 1;
            }
            else {
                $cache += $current_element;
                $index++;
            }
        }
    }

    End {
        if($cache) {
            ,$cache;
        }
    }
}


(Chunk-Object -InputObject (echo 1 2 3 4 5 6 7) -Process {$_ + 100} -ElementsPerChunk 3)
Write-Host "------------------------------------------------"
(echo 1 2 3 4 5 6 7 | Chunk-Object -Process {$_ + 100} -ElementsPerChunk 3)

Result:

PS C:\Users\a> C:\Untitled5.ps1
100
100
100
100
100
100
100
------------------------------------------------
101
102
103
104
105
106
107

PS C:\Users\a> 

As you can see, it works with the pipeline in objects, but it does not work with the values ​​obtained from the parameter. How to change the code so that it works in both cases?

+4
4

, Chunk-Object, , , -InputObject , $InputObject.

, :

echo 1 2 3 4 5 6 7 | Chunk-Object -Process {$_ + 100} -ElementsPerChunk 3

, $_ , $InputObject ( - [object[]]. foreach , $InputObject process. $current_element = $o $current_element = $InputObject, .

, -InputObject:

Chunk-Object -InputObject (echo 1 2 3 4 5 6 7) -Process {$_ + 100} -ElementsPerChunk 3

, , , , -Process, $_, foreach > loop $o, $_ . 100, $current_element {$_ + 100}, 100, $_ NULL. , $_ $o, :

Chunk-Object -InputObject (echo 1 2 3 4 5 6 7) -Process {$o + 100} -ElementsPerChunk 3

$_ , foreach , foreach($o in $InputObject) { $InputObject | %{. , , Chunk-Object , $_ , strong > process , , .


UPDATE:

,

$current_element = & $Process $current_element;

$current_element $Process. , , , , . MyFunction 'foo', foo $_ ; , & {$_ + 100} 'foo' $_ 'foo'. scriptblock {$args[0] + 100}, :

Chunk-Object -InputObject (echo 1 2 3 4 5 6 7) -Process {$args[0] + 100} -ElementsPerChunk 3

, scriptblock , foreach, Foreach-Object ($InputObject | %{), , .

+4

. , .

: (echo 1 2 3 4 5 6 7) "1 2 3 4 5 6 7",

: : @(1, 2, 3, 4, 5, 6, 7)

: foreach. ,

. foreach-object

Process {
    $InputObject | Foreach-Object {
        ...
    }
}

foreach($foo in $bar) , . $list | Foreach-Object { ... } ,

. , ; , , , .

:

function Chunk-Object()
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory = $true,
                   ValueFromPipeline = $true,
                   ValueFromPipelineByPropertyName = $true)] [object[]] $InputObject,
        [Parameter()] [scriptblock] $Process,
        [Parameter()] [int] $ElementsPerChunk
    )

    Begin {
        $cache = @();
        $index = 0;
    }

    Process {
        $InputObject | ForEach-Object {
            $current_element = $_;
            if($Process) {
                $current_element = & $Process $current_element;
            }
            if($cache.Length -eq $ElementsPerChunk) {
                ,$cache;
                $cache = @($current_element);
                $index = 1;
            }
            else {
                $cache += $current_element;
                $index++;
            }
        }
    }

    End {
        if($cache) {
            ,$cache;
        }
    }
}


Set-PSDebug -Off
Write-Host "Input Object is array"
Chunk-Object -InputObject @(1, 2, 3, 4, 5, 6, 7) -Process {$_ + 100} -ElementsPerChunk 3
Write-Host "------------------------------------------------"
Write-Host "Input Object is on pipeline"
@(1, 2, 3, 4, 5, 6, 7) | Chunk-Object -Process {$_ + 100} -ElementsPerChunk 3
Write-Host "------------------------------------------------"
Write-Host "Input object is string"
(echo "1 2 3 4 5 6 7")  | Chunk-Object -Process {$_ + 100} -ElementsPerChunk 3
Write-Host "------------------------------------------------"
Write-Host "Input object is split string"
(echo "1 2 3 4 5 6 7") -split ' ' | Chunk-Object -Process {$_ + 100} -ElementsPerChunk 3
Write-Host "------------------------------------------------"
Write-Host "Input object is int[] converted from split string"
([int[]]("1 2 3 4 5 6 7" -split ' '))  | Chunk-Object -Process {$_ + 100} -ElementsPerChunk 3
Write-Host "------------------------------------------------"
Write-Host "Input object is split and converted"
(echo "1 2 3 4 5 6 7") -split ' ' | Chunk-Object -Process {[int]$_ + 100} -ElementsPerChunk 3
+2

PowerShell , , , .

:

function Test {
    [CmdletBinding()]
    param (
        [Parameter(ValueFromPipeline = $true)]
        [Object[]] $InputObject
    )

    process {
        $InputObject.Count;
    }
}

# This example shows how the single array is passed
# in, containing 4 items.
Test -InputObject (1,2,3,4);

# Result: 4

# This example shows how PowerShell unwraps the
# array and treats each object individually.
1,2,3,4 | Test;

# Result: 1,1,1,1

, -, , .

function Test {
    [CmdletBinding()]
    param (
        [Parameter(ValueFromPipeline = $true)]
        [Object[]] $InputObject
        , [ScriptBlock] $Process
    )

    process {
        if ($InputObject.Count -gt 1) {
            foreach ($Object in $InputObject) {
                Invoke-Command -ScriptBlock $Process -ArgumentList $Object;
            }
        }
        else {
            Invoke-Command -ScriptBlock $Process -ArgumentList $InputObject;
        }
    }
}

Test -InputObject (1,2,3,4) -Process { $args[0] + 100 };

Write-Host -Object '-----------------';

1,2,3,4 | Test -Process { $args[0] + 100; };

, $_ $args[0], , process { ... } ScriptBlock. . .

function Test {
    [CmdletBinding()]
    param (
        [Parameter(ValueFromPipeline = $true)]
        [Object[]] $InputObject
        , [ScriptBlock] $Process
    )

    process {
        if ($InputObject.Count -gt 1) {
            foreach ($Object in $InputObject) {
                $Object | & $Process;
            }
        }
        else {
            $_ | & $Process;
        }
    }
}

Test -InputObject (1,2,3,4) -Process { process { $_ + 100; }; };

Write-Host -Object '-----------------';

1,2,3,4 | Test -Process { process { $_ + 100; }; };
+1

$Inputobject , $Input. , , , :

Function Get-DriveC {
[cmdletbinding()]

Param(
[Parameter(ValueFromPipeline)]
[ValidateNotNullorEmpty()]
[string[]]$Computername = $env:computername)

Begin {
    Write-Verbose "Starting Get-DriveC"
    #define a hashtable of parameters to splat
    $param=@{Computername=$null;class="win32_logicaldisk";errorAction="Stop";
    filter="deviceid='c:'"}
}
Process {
foreach ($computer in $computername) {
  Try {
   Write-Verbose "Querying $computer"
   $param.Computername=$computer
   Get-CimInstance @param
  }
  Catch {
    Write-Warning "Oops. $($_.exception.message)"
  }
} #foreach
} #process

End {
    Write-Verbose "Ending Get-DriveC"
 }

} #end function

.

InputObject , . , , , , .

0

All Articles