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