解釋 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

更新於: 2020年5月4日

5K+ 次瀏覽

啟動您的 職業生涯

透過完成課程獲得認證

開始學習
廣告