![](/img/trans.png)
[英]Installing windows updates remotely, using PowerShell. (some PowerCLI)
[英]Powershell. Difference between piping commands and using Foreach-Object
對不起,如果這個問題已經得到回答,我可以找到類似的問題,但不是我需要問的確切問題。
我們舉兩個例子:
1. Get-Process -name msedge,putty | Stop-Process
2. Get-Process -name msedge,putty | Foreach-Object {Stop-Process $_}
兩者都在做同樣的操作。 每種方法使用的方法是什么? 在第一個示例只是為了代碼可讀性/美學而省略Foreach-Object
構造的意義上,它們是否相同?
第一個示例要求 Cmdlet 支持通過管道綁定相關參數。 在您的情況下, Stop-Process
會將 Process 對象從管道綁定到它的-InputObject
參數。
您可以使用get-help stop-process -Parameter *
並查看哪些參數具有“接受管道輸入?” 設置為真。
如果 Cmdlet 不支持相關參數值的綁定,您可以將ForEach-Object
包裹在它周圍,就像您在第二個示例中所做的那樣。 通過這種方式,您可以使用自動變量$_
將當前管道對象(或您從中派生的信息)“手動”綁定到相應的參數。
如果 Cmdlet 支持綁定管道中的參數值,您應該使用什么方法? 不幸的是,這取決於。 可以編寫行為不同的 Cmdlet,具體取決於參數值的綁定方式。 讓我來說明這一點:
function Test-BindingFoo {
[CmdletBinding()]
param (
[Parameter(ValueFromPipeline)]
[string[]]
$InputParameter
)
begin {
Write-Host "[BEGIN]"
}
process {
foreach ($value in $InputParameter) {
Write-Host "The current value is: $value"
}
}
end {
Write-Host "[END]"
}
}
如果您使用管道綁定執行此 Cmdlet,則該函數的 Begin 塊只執行一次:
❯ "foo1", "foo2" | Test-BindingFoo
[BEGIN]
The current value is: foo1
The current value is: foo2
[END]
如果您使用ForEach-Object
,則每次對象通過管道時都會執行 Begin 塊:
❯ "foo1", "foo2" | ForEach-Object { Test-BindingFoo $_ }
[BEGIN]
The current value is: foo1
[END]
[BEGIN]
The current value is: foo2
[END]
在實施良好的 Cmdlet 中,這里的差異應該無關緊要。 但是我發現當以我們在此處討論的方式傳入參數時,了解 Cmdlet 內部發生的情況很有用。
您也可以這樣做,並在進程對象(操作語句)上使用 kill 方法:
Get-Process msedge,putty | Foreach-Object kill
# or
Get-Process msedge,putty | Foreach-Object -membername kill
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.