解釋 PowerShell 高階函式中的 ValueFromPipeline。
考慮以下示例,我們建立了一個高階函式來獲取特定程序的資訊,例如**程序名稱**、**程序 ID (PID)**、**啟動時間**、**響應狀態**等。
function Get-ProcessInformation{ [cmdletbinding()] param( [Parameter(Mandatory=$True)] [string[]]$name ) Begin{ Write-Verbose "Program started" } Process{ Write-Verbose "Extracting Process Inforamtion" Get-Process $name | Select Name, ID, StartTime, Responding | ft - AutoSize } End{ Write-Verbose "Function ends here" } }
以上是高階函式示例。當我們執行上述命令時,它將為我們提供有關所選表的程序資訊。
輸出
PS C:\WINDOWS\system32> Get-ProcessInformation -name Chrome Name Id StartTime Responding ---- -- --------- ---------- chrome 1284 24-04-2020 21:29:25 True chrome 1316 24-04-2020 21:29:37 True chrome 2004 25-04-2020 17:12:40 True chrome 2676 26-04-2020 10:59:37 True chrome 3096 24-04-2020 23:39:00 True chrome 4660 25-04-2020 22:43:34 True chrome 6040 24-04-2020 21:29:31 True chrome 6548 26-04-2020 10:59:30 True chrome 6592 26-04-2020 10:59:39 True chrome 6644 25-04-2020 16:41:59 True chrome 6780 26-04-2020 09:53:33 True chrome 7392 25-04-2020 11:47:22 True chrome 10540 26-04-2020 10:56:49 True chrome 11288 24-04-2020 21:33:05 True chrome 12088 26-04-2020 10:59:48 True chrome 12100 24-04-2020 21:29:38 True chrome 13112 26-04-2020 10:59:48 True chrome 13460 26-04-2020 10:59:45 True
現在我們將上述建立的函式作為管道輸出傳遞,並檢查它是否有效?
PS C:\WINDOWS\system32> "Chrome" | Get-ProcessInformation cmdlet Get-ProcessInformation at command pipeline position 1 Supply values for the following parameters: name: Get-ProcessInformation : Cannot bind argument to parameter 'name' because it is an empty string. At line:1 char:12 + "Chrome" | Get-ProcessInformation + ~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidData: (:) [Get-ProcessInformation], Param eterBindingValidationException + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAl lowed,Get-ProcessInformation
這不起作用,因為此函式不相容作為管道輸入使用。它沒有將**“chrome”**作為其輸入,並且由於**Mandatory**引數而要求提供 Name 變數的值。我們只需要新增**ValueFromPipeline()**引數即可。由於我們已經在函式中使用了**Mandatory**引數,因此只需新增另一個管道引數,如下所示。
function Get-ProcessInformation{ [cmdletbinding()] param( [Parameter(Mandatory=$True,ValuefromPipeline=$True)] [string[]]$name ) Begin{ Write-Verbose "Program started" } Process{ Write-Verbose "Extracting Process Inforamtion" Get-Process $name | Select Name, ID, StartTime, Responding | ft - AutoSize } End{ Write-Verbose "Function ends here" } }
現在,讓我們檢查它是否有效。
PS C:\WINDOWS\system32> "Chrome" | Get-ProcessInformation Name Id StartTime Responding ---- -- --------- ---------- chrome 1284 24-04-2020 21:29:25 True chrome 1316 24-04-2020 21:29:37 True chrome 2004 25-04-2020 17:12:40 True chrome 2676 26-04-2020 10:59:37 True chrome 3096 24-04-2020 23:39:00 True chrome 4660 25-04-2020 22:43:34 True chrome 6040 24-04-2020 21:29:31 True chrome 6548 26-04-2020 10:59:30 True chrome 6592 26-04-2020 10:59:39 True chrome 6644 25-04-2020 16:41:59 True chrome 6780 26-04-2020 09:53:33 True chrome 7392 25-04-2020 11:47:22 True chrome 10540 26-04-2020 10:56:49 True chrome 11288 24-04-2020 21:33:05 True chrome 12088 26-04-2020 10:59:48 True
是的,它有效。現在如果我們提供兩個現有程序名稱作為輸入,它將無法提供所需的結果,因為我們在引數部分宣告的字串不是陣列,而是一個單個字串變數。我們現在將其宣告為字串陣列。
function Get-ProcessInformation{ [cmdletbinding()] param( [Parameter(Mandatory=$True,ValuefromPipeline=$True)] [string[]]$name ) Begin{ Write-Verbose "Program started" } Process{ Write-Verbose "Extracting Process Inforamtion" Get-Process $name | Select Name, ID, StartTime, Responding | ft - AutoSize } End{ Write-Verbose "Function ends here" } }
現在檢查輸出。
PS C:\WINDOWS\system32> "Chrome","SkypeApp" | Get-ProcessInformation Name Id StartTime Responding ---- -- --------- ---------- chrome 1284 24-04-2020 21:29:25 True chrome 1316 24-04-2020 21:29:37 True chrome 2004 25-04-2020 17:12:40 True chrome 2676 26-04-2020 10:59:37 True chrome 3096 24-04-2020 23:39:00 True chrome 4660 25-04-2020 22:43:34 True chrome 6040 24-04-2020 21:29:31 True chrome 6548 26-04-2020 10:59:30 True chrome 6592 26-04-2020 10:59:39 True chrome 6644 25-04-2020 16:41:59 True chrome 6780 26-04-2020 09:53:33 True Name Id StartTime Responding ---- -- --------- ---------- SkypeApp 2552 21-04-2020 18:31:02 True
在這裡,我們得到了預期的輸出,但對於每個新程序,我們都得到了標題,而我們不需要這些。我們需要組合輸出,因此我們將在這裡使用**foreach**迴圈,並需要使用**PSCustomObject**來收集資料。
function Get-ProcessInformation{ [cmdletbinding()] param( [Parameter(Mandatory=$True,ValuefromPipeline=$True)] [string]$name ) Begin{ Write-Verbose "Program started" $out = @() } Process{ Write-Verbose "Extracting Process Inforamtion" $procs = Get-Process $name foreach($proc in $procs){ $out += [PSCustomObject]@{ "Process_Name" = $proc.Name "PID" = $proc.Id "Start_Time" = $proc.StartTime "Responding?" = $proc.Responding } } } End{ $out Write-Verbose "Function ends here" } }
當您檢查上面的輸出時,輸出已組合,並且符合預期。
PS C:\WINDOWS\system32> "Chrome","SkypeApp" | Get-ProcessInformation Process_Name PID Start_Time Responding? ------------ --- ---------- ----------- chrome 1284 24-04-2020 21:29:25 True chrome 1316 24-04-2020 21:29:37 True chrome 2004 25-04-2020 17:12:40 True chrome 2676 26-04-2020 10:59:37 True chrome 3096 24-04-2020 23:39:00 True chrome 4660 25-04-2020 22:43:34 True chrome 6040 24-04-2020 21:29:31 True chrome 6548 26-04-2020 10:59:30 True chrome 6592 26-04-2020 10:59:39 True chrome 6644 25-04-2020 16:41:59 True chrome 6780 26-04-2020 09:53:33 True chrome 7392 25-04-2020 11:47:22 True chrome 10540 26-04-2020 10:56:49 True chrome 11288 24-04-2020 21:33:05 True chrome 12088 26-04-2020 10:59:48 True chrome 12100 24-04-2020 21:29:38 True SkypeApp 2552 21-04-2020 18:31:02 True
廣告