如何在Powershell cmdlet中将CSV文件的内容作为管道输入处理

时间:2018-11-14 01:08:38

标签: powershell pipeline cmdlet

我想使用CSV文件来提供powershell cmdlet的参数

Role, email, fname, lname
Admin, a@b.com, John, Smith

我要按如下方式处理cmdlet:

import-csv myFile| mycmdlet | export-csv myresults

我也希望能够像这样调用cmdlet

mycmdlet -role x -email j@b.com -fname John -lname Smith

并以类似以下对象的形式查看结果:

lname: "Smith"
fname: "John"
email: "j@b.com"
role: "X"
ResultData: "something else"

我不想这样做:

import-csv X.txt | foreach-object { mycmdlet -email $_.email } 

在Powershell中,我想这样做:

function global:test-Pipeline{
param(  
[Parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)][String[]]$role, 
[Parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)][String[]]$email, 
[Parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)][String[]]$fname, 
[Parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)][String[]]$lname ) 

$result = new-object psobject

process {
   foreach($address in $email)
   {
       Do something with each role, email, fname lname
       Add output to $result
   }
}

End {
    return $result
}

}

我敢肯定这是有可能的,我该怎么做?无需在cmdlet中处理CSV就能做到吗?

1 个答案:

答案 0 :(得分:3)

是的,您几乎正确。您的参数不应使用ValueFromPipeline,而应使用ValueFromPipelineByPropertyName。它们应该是[String],而不是[String[]]。原因是您将在每个“传递”中获得与单个输入对象相对应的一组参数。

您在这里也不需要End{}块,应该全部在Process{}中完成。

function Test-Pipeline{
    param(  
        [Parameter(ValueFromPipelineByPropertyName=$true)][String]$role, 
        [Parameter(ValueFromPipelineByPropertyName=$true)][String]$email, 
        [Parameter(ValueFromPipelineByPropertyName=$true)][String]$fname, 
        [Parameter(ValueFromPipelineByPropertyName=$true)][String]$lname 
    ) 


    Process {
        New-Object PSObject -Property @{
            role = "~$role~"
            email = "mailto:$email"
            fname = [cultureinfo]::CurrentCulture.TextInfo.ToTitleCase($fname)
            lname = [cultureinfo]::CurrentCulture.TextInfo.ToTitleCase($lname)
        }    
    }
}

用法:

Import-Csv myData.csv | Test-Pipeline | Export-Csv tranformedData.csv -NoTypeInformation

Import-Csv myData.csv | Test-Pipeline -role "Override Role" | ConvertTo-Json

发生了什么事?

Import-Csv为CSV中的每一行提供一个对象,并且每个对象为CSV中的每一列都有一个属性。

当您通过管道将其传递到另一个命令(包括函数)时,每个单个对象都一次发送一次。

您可以接受一个对象,并在命令中处理其属性。

您使用ValueFromPipelineByPropertyName在这里拥有的内容将查看输入对象,如果存在,并且包含一个与参数名称(或其任何别名)匹配的属性,则该值该属性的参数将绑定到参数(除非您在调用时指定;否则它将覆盖输入值)。

由于再次需要对象,因此在Process块中创建了一个新对象,该对象将通过管道传递到下一个命令。