Powershell 使用一元运算符的管道多重时间

Powershell 使用一元运算符的管道多重时间,powershell,pipeline,Powershell,Pipeline,我有以下功能: Function Refine{ [CmdletBinding()] param ( [parameter(ValueFromPipeline = $true)] $data ) begin {} process { For ($i=0; $i -le $data.count; $i++){ if ($data[$i]

我有以下功能:

Function Refine{
    [CmdletBinding()]
        param (
            [parameter(ValueFromPipeline = $true)]
          $data
        )
        begin {}
        process {
            For ($i=0; $i -le $data.count; $i++){
            if ($data[$i] -match 'nmap scan report' -and $data[$i+1] -match 'host is up' )  {
                $dat += $data[$i] + "`n"
                $counter=($i+4)
                while ($data[$counter] -match '^[0-9]') {
                    $dat += $data[$counter] + "`n"
                    $counter++
                }        
                }
            }
            
         }
        end { 
            if ($dat){#See that its not empty
            return  $dat.Split([Environment]::NewLine)
            }
        }
    }

$file1 = gc c:\test.txt

,gc ($file1) | Refine
我必须使用一元运算符进行管道,因为我希望将整个对象一次管道化到细化函数

输出如下所示,例如: 1.1.1.1的Nmap扫描报告 113/tcp闭合标识 443/tcp开放ssl/http Fortinet ssl VPN 2.2.2.2的Nmap扫描报告 21/tcp过滤ftp 22/tcp过滤ssh

现在,我想使用另一个函数,该函数采用此函数并从文本创建对象:

  Function BuildArray{
      [CmdletBinding()]
      Param(
          [Parameter(ValueFromPipeline = $true)]
          $data
      )
      Begin {}
      Process {
        $NMAPS=@()
        $nmap=@()
        $ports=@()
        For ($i=0; $i -lt $data.count; $i++){
            If ($data[$i] -match 'nmap scan report')  {
            $ip = ($data[$i] |  Select-String -Pattern "\d{1,3}(\.\d{1,3}){3}" -AllMatches).Matches.Value
            $k=$i
            If ($data[($i+1)] -notmatch 'nmap scan report' -and $i -le $data.count){
                DO{
                $ports+=$data[$i+1]
                $i++
                }
               While ($data[$i+1] -notmatch 'nmap scan report' -and $i -le $data.count)
               $nmap = @{IP = "$ip"; ports=@($ports)}
               $NMAPS+=$nmap
               $nmap=@()
               $ports=@()
               $i = $k
               }
              }
            }
      }
      End {
        $NMAPS
      }
  }
我这里的问题又是——我希望管道中的数据作为一个整体传递给BuildArray函数。但是我不能使用一元运算符,因为我得到一个错误,说我只能在管道开始时使用它

 ,(gc $file1 ) | ,(refine) | BuildArray #No good

如何将管道中的第二个对象作为一个整体一次性传递给第三个对象?

恕我直言,您对管道的一般概念理解不正确。cmdlet应该,这意味着每个cmdlet都应该以a.s.a.p.的形式处理每个项目,并将其流式传输到下一个cmdlet,以最终将其从内存中释放。
PowerShell对象()针对流式处理进行了优化,因为它包含其属性的所有类型信息。这使得这些PowerShell对象较重,不适合将其存储在(大型)集合中。
特定于您自己的函数,它使您(特别针对管道中的每个特定对象开发的
开始
过程
结束
块结构)毫无意义。如果在将其传递给
BuildArray
函数之前收集数组中的所有对象,则最好使用块(或保留所有类似于
End
块的输入块),其中将管道中提供的所有对象保存在单个数组中:

Function BuildArray {
    [CmdletBinding()]
    Param(
        [Parameter(ValueFromPipeline = $true)]$data
    )
    Process { Write-Host 'Process:' $Input }
}

1,2,3 | BuildArray

Process: 1
Process: 2
Process: 3

此外:

  • (或字符串)原样 价格昂贵。
    • 如果您确实使用了它,您应该正确初始化
      $dat='
      值,否则您可能会从它的一个父函数继承的意外副本开始

Write Output(gc$file1)-NoEnumerate
作为初始表达式,然后在函数中使用
Write Output$Output-NoEnumerate
而不是
return
,(,(gc$file1)|优化)| BuildArray?因此,您希望将第一个和第二个合并为一个对象,并作为一个整体传递给BuildArray?我实际上希望首先使用获取内容从文件中读取内容,然后将其传递给一个函数,该函数将文本更改为我喜欢的方式(优化),并将其传递给一个函数,该函数接收文本并从该信息中构建自定义对象谢谢,很明显,我是个笨蛋,非常感谢你提供的信息
Function BuildArray {
    [CmdletBinding()]
    Param(
        [Parameter(ValueFromPipeline = $true)]$data
    )
    End { Write-Host 'End:' $Input } # or just: Write-Host $Input
}

1,2,3 | BuildArray

End: 1 2 3