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

Joe*_*oey 75 powershell

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

ForEach-Object {
   # do something
}
Run Code Online (Sandbox Code Playgroud)

在使用命令行中的脚本时实际上不起作用,如下所示:

1..20 | .\test.ps1
Run Code Online (Sandbox Code Playgroud)

有办法吗?

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

Sha*_*evy 112

在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
Run Code Online (Sandbox Code Playgroud)

  • 实际上,您可以将param()块放在脚本的顶部,而无需声明脚本本地的函数. (7认同)
  • 没有大问题,将函数体保存在脚本文件中并传递给脚本:dir |\GET-File.ps1 (6认同)

Bra*_*tch 40

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

foreach ($i in $input) {
    $i
}
Run Code Online (Sandbox Code Playgroud)

17:12:42 PS> 1..20 | .\ cmd-input.ps1
1
2
3
- snip -
18
19
20

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

$ input陷阱«德米特里的PowerBlog PowerShell及其他
"......基本上是一个枚举器中的$ input,可以访问你拥有的管道."

对于PS命令行,不是DOS命令行 Windows Command Processor.

  • EBGreen,`ntvdm`,它是Windows NT的DOS VM,在64位系统上不再存在.`cmd.exe`是*不是*DOS; 它是Windows命令处理器,除了黑色的灰色文本外,与DOS完全没有任何共同之处. (12认同)

Kei*_*ill 23

您可以编写一个过滤器,这是一个函数的特殊情况,如下所示:

filter SquareIt([int]$num) { $_ * $_ }
Run Code Online (Sandbox Code Playgroud)

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

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
  }
}
Run Code Online (Sandbox Code Playgroud)

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

  --- 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
  }
Run Code Online (Sandbox Code Playgroud)

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

  • 过程块就是你想要的.它具有不占用管道的优点. (4认同)

sam*_*est 8

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

作为脚本:

#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
  }
Run Code Online (Sandbox Code Playgroud) #Echo-Pipe2.ps1
foreach ($i in $input) {
    $i
}
Run Code Online (Sandbox Code Playgroud)

作为功​​能:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

例如

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
Run Code Online (Sandbox Code Playgroud)