powershell - 循环管道参数 - 有什么意义?

标签 powershell loops for-loop pipeline

tutorial made by Microsoft中有一个类似于以下的代码片段(编辑了原始内容以减少干扰):

function Test {
    param (
        [Parameter(ValueFromPipeline)]
        [string[]]$Params
    )

    process {
        foreach ($Param in $Params) {
            Write-Output $Param
        }
    }
}

但是,在前面的所有示例中,process block 本身已用作循环体。据我了解,以下简化代码应该是等效的:

function Test {
    param (
        [Parameter(ValueFromPipeline)]
        [string[]]$Params
    )

    process {
        Write-Output $Params
    }
}

确实,无论我用什么管道传递给它,结果都是一样的。然而,它出现在第一方教程中的事实让我相信使用循环可能有一些实际原因。

使用一种模式与另一种模式有什么区别吗?如果是,那是什么?如果不是,哪一个是首选?


以防万一我的简化失败了,这是原始示例:

function Test-MrErrorHandling {

    [CmdletBinding()]
    param (
        [Parameter(Mandatory,
                   ValueFromPipeline,
                   ValueFromPipelineByPropertyName)]
        [string[]]$ComputerName
    )

    PROCESS {
        foreach ($Computer in $ComputerName) {
            Test-WSMan -ComputerName $Computer
        }
    }
}

最佳答案

要点

你传递给下一个的内容有很大的不同cmdletpipeline (在您的情况下Test-WSMan):

function Test1 {
    param (
        [Parameter(ValueFromPipeline)]
        [string[]]$Params
    )
     process {
        foreach ($Param in $Params) {
            Write-Output ('Param: {0}, ToString: {1}, Count: {2}' -f $Param, "$Param", $Param.Count)
        }
    }
}

1,2,@(3,4) |Test1
Param: 1, ToString: 1, Count: 1
Param: 2, ToString: 2, Count: 1
Param: 3, ToString: 3, Count: 1
Param: 4, ToString: 4, Count: 1

function Test2 {
    param (
        [Parameter(ValueFromPipeline)]
        [string[]]$Params
    )

    process {
        Write-Output ('Param: {0}, ToString: {1}, Count: {2}' -f $Params, "$Params", $Params.Count)
    }
}

1,2,@(3,4) |Test2
Param: System.String[], ToString: 1, Count: 1
Param: System.String[], ToString: 2, Count: 1
Param: System.String[], ToString: 3 4, Count: 2

换句话说,在第二个示例中,您实际上将字符串数组 ( [String[]] ) 传递给 Test-WSMan 。如 Test-WSMan 实际上需要一个字符串( [[-ComputerName] <String>] ),PowerShell 会方便地 Type Cast字符串数组 ( String[] ) 转换为单个字符串类型 ( String )。
请注意,在某些情况下,如果您例如,这可能会像第二个示例中那样出错。 (意外)在管道中强制使用数组( @(3,4) )。在这种情况下,数组中的多个项目将被连接并传递到下一个 cmdlet。

使用单一参数名称

一般来说,(强烈)推荐Use Singular Parameter Names这通常也意味着您期望一个 String对于每个管道项目(例如当时的 $ComputerName):

Avoid using plural names for parameters whose value is a single element. This includes parameters that take arrays or lists because the user might supply an array or list with only one element.

Plural parameter names should be used only in those cases where the value of the parameter is always a multiple-element value. In these cases, the cmdlet should verify that multiple elements are supplied, and the cmdlet should display a warning to the user if multiple elements are not supplied.

这对于你的第二个例子来说意味着:

function Test2 {
    param (
        [Parameter(ValueFromPipeline)]
        [string]$Param
    )

    process {
        Write-Output $Param
    }
}

您自己的(而不是调用的 Test-WSMan )cmdlet 将产生错误:

1,2,@(3,4) |Test2

Test2: The input object cannot be bound to any parameters for the
command either because the command does not take pipeline input or
the input and its properties do not match any of the parameters
that take pipeline input.

关于powershell - 循环管道参数 - 有什么意义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72711942/

相关文章:

Javascript循环对象数组

powershell - 在SharePoint 2013中使用Powershell将列表项复制到另一个子网站列表

powershell - 在 Windows 10 Powershell 中通过 F7 使命令历史弹出窗口工作

python,生成器迭代一个或多个项目

使用 for 循环创建链表

r - 在 R 中循环获取 ChangePoint 数据

amazon-web-services - 如何使用 Get-SSMParameterList CmdLet 处理具有特定前缀的参数

powershell - 相当于Unix命令 “Uniq -c”的Powershell

java - 计算不均匀二维数组中的列总和

javascript - 将来自 JavaScript 对象中不同属性的数组项组合起来