【问题标题】:PowerShell: Pipe contents of csv file in to custom functionPowerShell:将 csv 文件的内容通过管道传输到自定义函数
【发布时间】:2015-03-17 20:37:05
【问题描述】:

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

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 如下所示:

计算机名称服务名称状态 本地主机 Svc1 正在运行 本地主机 Svc2 已停止 Comp1 Svc1 正在运行 Comp1 Svc2 正在运行 Comp1 Svc3 正在运行 Comp2 Svc1 正在运行 Comp2 Svc3 正在运行

【问题讨论】:

  • 这看起来和你上一个问题几乎一样。如果您觉得没有正确处理,您应该返回并编辑您之前的内容
  • 我真的很想知道你为什么坚持这样做?管道将一次处理这些项目。你需要Group-Object 才能在整个实体上发挥它的魔力。

标签: powershell csv import


【解决方案1】:

这是否更符合您在上一个问题中寻找的内容?

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。一旦我们弄清楚哪个问题更好,我可以合并这两个并删除其中一个,因为这看起来确实像重复。

【讨论】:

    【解决方案2】:

    感谢 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>

    【讨论】:

      猜你喜欢
      • 2019-01-24
      • 1970-01-01
      • 2021-10-15
      • 1970-01-01
      • 1970-01-01
      • 2014-07-08
      • 1970-01-01
      • 1970-01-01
      • 2019-12-05
      相关资源
      最近更新 更多