PowerShell:将csv文件的内容管道传入自定义函数

时间:2015-03-17 20:37:06

标签: powershell csv import

我有一个自定义POWERSHELL函数,它需要接受来自csv文件的数据数组(最好是生成此CSV的另一个cmdlet),读取内容然后根据比较生成一些所需的输出。比较部分按需要工作,但只有当我在函数内部硬编码import-csv ComputerServicesList行时。为了灵活性,我需要函数ot接受这个作为参数。以下是我目前的功能。关于在这一点上尝试什么,我没有想法。

function myTest3 {
    [cmdletBinding()]
    param (
        [Parameter(Mandatory=$True,
                   ValueFromPipeline=$True,
                   ValueFromPipelineByPropertyName=$True,
                   HelpMessage="Input a CSV vile with at least the follwoing cols: ComputerName, ServiceName, State")]    
        [array]$InputData 
    )

    #$data = $InputData
    $report= @()
    $counter = 0
    foreach ($line in $InputData) {
        $tempreport = New-Object PSObject
        $tempreport | Add-Member -type NoteProperty -name ComputerName -value $line.computerName
        $tempreport | Add-Member -type NoteProperty -name ExitCode -value $line.ExitCode
        $tempreport | Add-Member -type NoteProperty -name Name -value $line.ServiceName
        $tempreport | Add-Member -type NoteProperty -name ProcessId -value $line.ProcessId
        $tempreport | Add-Member -type NoteProperty -name StartMode -value $line.StartMode
        $tempreport | Add-Member -type NoteProperty -name State -value $line.State
        $tempreport | Add-Member -type NoteProperty -name Status -value $line.status
        $counter = $counter + 1
        write-host "Records  Looped: $counter"
        #Append
        $report += $tempreport
    } 
    write-output $report | ft

    # I WANT TO GET RID OF THIS LINE
    $data = import-csv .\ComputerServicesList.csv
    #perform Computer Count
    $uniqueComputerCount = ($data | Sort-Object ComputerName -Unique).Count
    write-host "Uniq computers counted: $uniqueComputerCount"        
    $RunningServices = $data | where-object {$_.State -eq "Running"} | Select ComputerName, ServiceName

    # List services that are shared.
    $SvcsCollapsed = $RunningServices | Group-Object ServiceName | where {$_.count -eq $uniqueComputerCount} | select Name 
    write-output $SvcsCollapsed      

}
import-csv .\ComputerServicesList.csv |  myTest3 | ft

我的输入CSV如下所示:     

    ComputerName    ServiceName    State
    Localhost       Svc1           Running
    Localhost       Svc2           Stopped
    Comp1           Svc1           Running
    Comp1           Svc2           Running
    Comp1           Svc3           Running
    Comp2           Svc1           Running
    Comp2           Svc3           Running
    

2 个答案:

答案 0 :(得分:0)

这是否与您之前提出的问题更符合要求?

function myTest{
    [cmdletBinding()]
        param (
           [Parameter(Mandatory=$True,
                       ValueFromPipeline=$True,
                       ValueFromPipelineByPropertyName=$True,
                       HelpMessage="Input CSV file listing ComputerNames, Servicename, State")]
            $InputObject  
        )
    End{
        $uniqueComputerCount = ($input | Sort-Object ComputerName -Unique).Count
        Write-host "Unique Computers: $uniqueComputerCount"
        $input | Group-Object ServiceName | Where-Object{$_.Count -eq $uniqueComputerCount} | Select -ExpandProperty Name
    }

}

然后呼叫将是:

Import-Csv c:\temp\data.log | myTest

$input包含整个管道实体,以便可以按照每个单独的行一次处理它。认为您需要PowerShell 3.0才能按预期工作。有关此主题的更多阅读,请查看this blog

逻辑的解释来自我的回答here。一旦我们找出哪个问题更好,我就可以合并两个并删除其中一个,因为这看起来像是重复的。

答案 1 :(得分:0)

谢谢Matt,你让我在这里找到了将你的一些代码放在END {}部分的建议。到目前为止,这是我在PS中不理解的缺失链接。该代码也适用于我的其他自定义cmdlet,它创建列表,无需创建CSV,绝对是加号;-)

感兴趣的人的工作代码:     


    function myTest3 {
        [cmdletBinding()]
        param (
            [Parameter(Mandatory=$True,
                       ValueFromPipeline=$True,
                       ValueFromPipelineByPropertyName=$True,
                       HelpMessage="Input a CSV/Array with at least the following cols: ComputerName, ServiceName, State")]
[array]$InputData )
BEGIN{ # Setup code if($PSCmdlet.ParameterSetName -eq "nopipeline"){ Write-Host "No pipeline input" } } PROCESS{ $data += $InputData } END { #perform Computer Count $uniqueComputerCount = ($data | Sort-Object ComputerName -Unique).Count write-host "Uniq computers counted: $uniqueComputerCount"
$RunningServices = $data | where-object {$_.State -eq "Running"} | Select ComputerName, ServiceName

# List services that are shared. $SvcsCollapsed = $RunningServices | Group-Object ServiceName | where {$_.count -eq $uniqueComputerCount} | select -ExpandProperty Name write-output $SvcsCollapsed } } #import-csv .\ComputerServicesList.csv | myTest3 | ft </code></pre>