如何编写接受管道输入的PowerShell脚本?

时间:2009-05-19 22:32:48

标签: powershell

我正在尝试编写一个可以获取管道输入的PowerShell脚本(并且预计会这样做),但尝试类似

的内容
ForEach-Object {
   # do something
}
使用命令行中的脚本时

实际上不起作用,如下所示:

1..20 | .\test.ps1

有办法吗?

注意:我了解功能和过滤器。这不是我要找的。

4 个答案:

答案 0 :(得分:109)

在v2中,您还可以接受管道输入(通过propertyName或byValue),添加参数别名等:

function Get-File{
    param(  
    [Parameter(
        Position=0, 
        Mandatory=$true, 
        ValueFromPipeline=$true,
        ValueFromPipelineByPropertyName=$true)
    ]
    [Alias('FullName')]
    [String[]]$FilePath
    ) 

    process {
       foreach($path in $FilePath)
       {
           Write-Host "file path is: $path"
       }
    }
}


# test ValueFromPipelineByPropertyName 
dir | Get-File

# test ValueFromPipeline (byValue) 

"D:\scripts\s1.txt","D:\scripts\s2.txt" | Get-File

 - or -

dir *.txt | foreach {$_.fullname} | Get-File

答案 1 :(得分:38)

这有效,可能有其他方法可以做到:

foreach ($i in $input) {
    $i
}

17:12:42 PS> 1..20 | \ CMD-input.ps1
1
2
3
- 剪辑 -
18个
19个
20个

搜索“powershell $输入变量”,您将找到更多信息和示例 一对夫妇在这里:
PowerShell Functions and Filters PowerShell Pro!
(请参阅“使用PowerShell特殊变量”$ input“”)部分 “脚本,函数和脚本块都可以访问$ input变量,该变量为传入管道中的元素提供枚举器。”

$input gotchas « Dmitry’s PowerBlog PowerShell and beyond
“...基本上是枚举器中的$ input,可以访问你拥有的管道。”

对于PS命令行,而不是 DOS命令行 Windows命令处理器。

答案 2 :(得分:23)

你可以写一个过滤器,这是一个像这样的函数的特殊情况:

filter SquareIt([int]$num) { $_ * $_ }

或者您可以创建类似的功能:

function SquareIt([int]$num) {
  Begin {
    # Executes once before first item in pipeline is processed
  }

  Process {
    # Executes once for each pipeline object
    $_ * $_
  }

  End {
    # Executes once after last pipeline object is processed
  }
}

以上工作作为交互式功能定义,或者如果在脚本中可以点缀到您的全局会话(或其他脚本)中。但是你的例子表明你想要一个脚本,所以这里它是一个可以直接使用的脚本(不需要打点):

  --- Contents of test.ps1 ---
  param([int]$num)

  Begin {
    # Executes once before first item in pipeline is processed
  }

  Process {
    # Executes once for each pipeline object
    $_ * $_
  }

  End {
    # Executes once after last pipeline object is processed
  }

使用PowerShell V2,这会改变一些“高级功能”,它使用与编译的cmdlet相同的参数绑定功能来实现功能。有关差异的示例,请参阅此blog post。另请注意,在此高级函数的情况下,您不使用$ _来访问管道对象。使用高级函数,管道对象绑定到参数,就像使用cmdlet一样。

答案 3 :(得分:7)

以下是使用管道输入的脚本/函数的最简单示例。每个行为与管道到“echo”cmdlet的行为相同。

As Scripts:

#Echo-Pipe.ps1
  Begin {
    # Executes once before first item in pipeline is processed
  }

  Process {
    # Executes once for each pipeline object
    echo $_
  }

  End {
    # Executes once after last pipeline object is processed
  }
#Echo-Pipe2.ps1
foreach ($i in $input) {
    $i
}

作为功能:

Function Echo-Pipe {
  Begin {
    # Executes once before first item in pipeline is processed
  }

  Process {
    # Executes once for each pipeline object
    echo $_
  }

  End {
    # Executes once after last pipeline object is processed
  }
}

Function Echo-Pipe2 {
    foreach ($i in $input) {
        $i
    }
}

E.g。

PS > . theFileThatContainsTheFunctions.ps1 # This includes the functions into your session
PS > echo "hello world" | Echo-Pipe
hello world
PS > cat aFileWithThreeTestLines.txt | Echo-Pipe2
The first test line
The second test line
The third test line