使用带有函数的管道获得不同的结果

时间:2012-03-01 03:52:06

标签: function powershell pipeline

我发现通过PowerShell管道将对象传递给函数会将它们转换为string个对象。如果我将对象作为参数传递,它会保留其类型。为了证明:

我有以下PowerShell函数,它显示对象的类型和值:

function TestFunction {
    param (
        [Parameter(
            Position=0,
            Mandatory=$true,
            ValueFromPipeline=$true
        )] $InputObject
    )

    Echo $InputObject.GetType().Name
    Echo $InputObject
}

我运行此脚本来测试函数:

[string[]] $Array = "Value 1", "Value 2"

# Result outside of function.
Echo $Array.GetType().Name
Echo $Array
Echo ""

# Calling function with parameter.
TestFunction $Array
Echo ""

# Calling function with pipeline.
$Array | TestFunction

这会产生输出:

String[]
Value 1
Value 2

String[]
Value 1
Value 2

String
Value 2

编辑:如何使用管道将整个数组传递给函数?

3 个答案:

答案 0 :(得分:7)

要处理通过管道收到的多个项目,您需要在函数中使用一个过程块:

function Test-Function {
    param (
        [Parameter(ValueFromPipeline=$true)] $Test
    )

    process {
        $Test.GetType().FullName
        $Test
    }
}

[string[]] $Array = "Value 1", "Value 2"
$Array | Test-Function

更多信息:

答案 1 :(得分:3)

除了拥有流程块之外,您还需要处理数组中的每个项目。当数组作为参数传递时,需要它,而不是通过管道传递。考虑一下:

function Test-Function 
{
    param (
        [Parameter(
            Position=0,
            Mandatory=$true,
            ValueFromPipeline=$true
        )] $InputObject
    )

    process
    {
        $InputObject.GetType().Name
    }
}

$Array = "Value 1","Value 2"
Test-Function $array

结果将是String [],这可能不是你想要的。无论参数如何传递,以下命令都将打印数组中每个项的类型:

function Test-Function 
{
    param (
        [Parameter(
            Position=0,
            Mandatory=$true,
            ValueFromPipeline=$true
        )] $InputObject
    )

    process
    {
        foreach($i in $InputObject)
        {
            $i.GetType().Name
        }
    }
}

答案 2 :(得分:0)

您是否尝试将不是字符串的内容传递给该函数?

尝试: 1, 2 | TestFunction

编辑:

试试这个。我做的唯一更改是在$ InputObject

周围添加一个进程
function TestFunction {
    param (
        [Parameter(
            Position=0,
            Mandatory=$true,
            ValueFromPipeline=$true
        )] $InputObject
    )

    process
    {
    Echo $InputObject.GetType().Name
    Echo $InputObject
    }
}