如何在Powershell cmdlet中将CSV文件的内容作为管道输入处理 [英] How can I process the content of a CSV file as Pipeline input in Powershell cmdlet

查看:87
本文介绍了如何在Powershell cmdlet中将CSV文件的内容作为管道输入处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to use a CSV file to feed the parameters of powershell cmdlet

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

我要按如下方式处理cmdlet:

I want to process a cmdlet as follows:

import-csv myFile| mycmdlet | export-csv myresults

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

I also want to be able to call the cmdlet like this

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

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

and see a result as an object like:

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

我不想这样做:

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

在Powershell中,我想这样做:

In the powershell I wanted to do something line this:

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就能做到吗?

I'm sure this must be possible, how do i do it? Can it be done without having to process the CSV in the cmdlet?

推荐答案

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

Yes, you almost have it right. Your parameters should not use ValueFromPipeline but should use ValueFromPipelineByPropertyName. They should be [String] but not [String[]]. The reason is that you are going to get a single set of parameters, corresponding to a single input object, in each "pass".

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

You also don't need the End{} block here it should all be done in 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中的每一列都有一个属性.


What's going on?

Import-Csv gives you one object for every row in the CSV, and each object has a property for each column in the CSV.

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

When you pipe that into another command, including your function each individual object gets sent through one at a time.

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

You could accept the one object, and process its properties in the command.

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

What you have here, using ValueFromPipelineByPropertyName, looks at the input object, if there is one, and if it contains a property that matches the name of the parameter (or any of its aliases), then the value of that property will be bound to the parameter (unless you specified on calling; that would override the input value).

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

Since you want objects again as a result, you create a new object in the Process block, which will be passed out through the pipeline to the next command.

这篇关于如何在Powershell cmdlet中将CSV文件的内容作为管道输入处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆