PowerShell管道如何工作 – 第1部分?
PowerShell透過管道結構變得更容易。使用管道結構,我們可以將左側命令輸出或字串的輸入傳遞到命令右側作為輸入。例如,
Get-Service | Out-File c:\services.txt
在上面的示例中,我們將**Get-Service**的輸出作為物件傳遞給**Out-File**命令,它是管道的右側,作為輸入。在詳細瞭解管道如何工作之前,我們需要了解我們編寫的每個命令都會產生輸出,並且該輸出已由PowerShell使用管道進行格式化。
例如,**Get-Process**命令,如果我們不格式化此命令,則實際的預設命令為:
Get-Process | Out-Default | Out-Host
**Out-Default**和**Out-Host**是不可見的,但實際上在後臺執行。**Out-Default**設定預設格式,而**Out-Host**命令將輸出列印到控制檯。
在管道結構中,命令的右側從輸出的左側獲取輸入。因此,我們需要了解,我們究竟可以將什麼傳遞給管道,我們不能傳遞隨機的東西,例如程序的名稱或PID作為管道,如下所示。
"PowerShell" | Get-Process
"1002" | Get-Process
上面的命令將生成錯誤,指出上面的命令不將提供的輸入作為管道輸入。
Get-Process: The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.
而對於Get-Service,我們可以傳遞名稱。
PS C:\> "Winrm","Spooler" | Get-Service Status Name DisplayName ------ ---- ----------- Running Winrm Windows Remote Management (WS-Managem… Running Spooler Print Spooler
以下是解釋。要檢查我們究竟可以將什麼作為輸入傳遞到命令的右側,我們需要使用**Get-Command**以及屬性名稱ParameterSet。您還可以使用**Get-Help**命令。
(Get-Command Get-Service).ParameterSets.Parameters
執行上述命令後,請注意這兩個屬性**ValueFromPipeLine**和**ValueFromPipelineByPropertyName**,並檢查**True**值。讓我們過濾掉這些屬性。
在本文中,我們介紹了**ValueFromPipleLine**屬性。**valueFromPipelineByPropertyName**引數將在下一篇文章(第2部分)中介紹。
(Get-Command Get-Service).ParameterSets.parameters | where{$_.ValueFromPipeline -eq 'True'} | Select Name,ParameterType輸出
Name ParameterType ---- ------------- Name System.String[] InputObject System.ServiceProcess.ServiceController[]
從上面的輸出中,我們可以將**Name**作為輸入物件,其型別為**String[]**。這意味著我們可以傳遞多個服務名稱,這與前面示例中討論的相同。
PS C:\> "Winrm","Spooler" | Get-Service Status Name DisplayName ------ ---- ----------- Running Winrm Windows Remote Management (WS-Managem… Running Spooler Print Spooler
第二個是InputObject,其型別為ServiceController[]。當您使用命令的Get-Member時,您可以在第一行看到此型別,並且將獲得TypeName。
PS C:\> Get-Service | Get-Member TypeName: System.Service.ServiceController
讓我們以Stop-Service命令為例,以便更好地理解它,
(Get-Command Stop-Service).ParameterSets.parameters | where{$_.ValueFromPipeline -eq 'True'} | Select Name,ParameterType
Name ParameterType
---- -------------
InputObject System.Diagnostics.Process[]因此,**Stop-Process**命令僅接受Process陣列作為輸入,並且如果您檢查**Get-Process**,其成員型別也是**System.Diagnostics.process**。這意味著我們可以使用管道將整個Get-Process作為輸入傳遞給**Stop-Process**。
PS C:\> Get-Process | gm TypeName: System.Diagnostics.Process Get-Process | Stop-Process
這意味著如果我們傳遞程序的名稱或程序ID,則它不應該工作。
PS C:\> "2916" | Stop-Process InvalidArgument: (2916:String) [Stop-Process], ParameterBindingException PS C:\> "Notepad" | Stop-Process InvalidArgument: (Notepad:String) [Stop-Process], ParameterBindingException
在上面的示例中,傳遞程序ID或程序名稱不起作用,因為管道不接受該輸入。
資料結構
網路
關係資料庫管理系統
作業系統
Java
iOS
HTML
CSS
Android
Python
C語言程式設計
C++
C#
MongoDB
MySQL
Javascript
PHP