簡短描述
描述如何使用方法對 PowerShell 中的物件執行動作。
完整描述
PowerShell 會使用 物件來代表數據存放區中的項目或計算機的狀態。 例如,FileInfo 物件代表文件系統磁碟驅動器中的檔案,而 ProcessInfo 物件則代表電腦上的進程。
物件具有屬性,可儲存對象的相關數據,以及可讓您變更物件的方法。
「方法」是一組指示,可指定您可以在 對象上執行的動作。 例如,FileInfo 物件包含複製 CopyTo 物件所代表檔案的 FileInfo 方法。
若要取得任何物件的方法,請使用 Get-Member Cmdlet。 使用其 MemberType 屬性值為 “Method”。 下列命令會取得進程物件的方法。
Get-Process | Get-Member -MemberType Method
TypeName: System.Diagnostics.Process
Name MemberType Definition
---- ---------- ----------
BeginErrorReadLine Method System.Void BeginErrorReadLine()
BeginOutputReadLine Method System.Void BeginOutputReadLine()
...
Kill Method System.Void Kill()
Refresh Method System.Void Refresh()
Start Method bool Start()
ToString Method string ToString()
WaitForExit Method bool WaitForExit(int milliseconds), ...
WaitForInputIdle Method bool WaitForInputIdle(int millisecon...
若要執行或「叫用」物件的方法,請輸入點 (.)、方法名稱,以及一組括弧 “()”。 如果方法有自變數,請將自變數值放在括弧內。 即使沒有自變數,每個方法呼叫都需要括弧。 如果方法採用多個自變數,則應該以逗號分隔。
例如,下列命令會叫用程式的 Kill 方法,以結束電腦上的記事本程式。
$notepad = Get-Process notepad
$notepad.Kill()
結合上述語句可以縮短此範例。
(Get-Process Notepad).Kill()
Get-Process 命令會以括弧括住,以確保它在叫用 Kill 方法之前執行。 接著會在傳回的 Kill 物件上叫用 Process 方法。
另一個非常有用的方法是字串 Replace 方法。
Replace 方法會取代字串內的文字。 在下列範例中,點 (.) 可以緊接在字串的結尾引號後面。
'this is rocket science'.Replace('rocket', 'rock')
this is rock science
如先前範例所示,您可以使用命令、變數中的物件,或產生物件的任何專案來叫用方法(例如引號中的字串)。
從 PowerShell 4.0 開始,支援使用動態方法名稱的方法調用。
瞭解方法
若要尋找物件方法的定義,請移至物件類型的幫助主題,並尋找其方法頁面。 例如,下列頁面說明 System.Diagnostics.Process 進程物件的方法。
若要判斷方法的自變數,請檢閱方法定義,就像PowerShell Cmdlet的語法圖表一樣。
方法定義可能會有一或多個方法簽章,就像 PowerShell Cmdlet 的參數集一樣。 簽章會顯示所有有效的命令格式,以叫用 方法。
例如,CopyTo 類別的 FileInfo 方法包含下列兩個方法簽章:
CopyTo(String destFileName)
CopyTo(String destFileName, Boolean overwrite)
第一個方法簽章會採用目的地檔名(和路徑)。 下列範例使用第一個 CopyTo 方法,將 Final.txt 檔案複製到 C:\Bin 目錄。
(Get-ChildItem c:\final.txt).CopyTo("c:\bin\final.txt")
備註
不同於PowerShell 自變數 模式,物件方法會在 表示式 模式中執行,這是PowerShell所建置的 .NET 架構傳遞。 在 表示式 模式中,不允許 裸字 自變數(未加上批註的字串)。 當使用路徑做為參數時,您可以看見這個差異,而不是路徑做為自變數。 您可以在 about_Parsing 中深入瞭解剖析模式
第二個方法簽章會採用目的地檔名和布爾值,以判斷目的地檔案是否應該覆寫,如果目的地檔案已經存在。
下列範例使用第二個 CopyTo 方法,將 Final.txt 檔案複製到 C:\Bin 目錄,並覆寫現有的檔案。
(Get-ChildItem c:\final.txt).CopyTo("c:\bin\final.txt", $true)
成員訪問枚舉
從 PowerShell 3.0 開始,當您使用成員存取運算子 (.) 來存取清單集合上不存在的方法時,PowerShell 會自動列舉集合中的專案,並在每個專案上叫用 方法。 如需詳細資訊,請參閱 about_Member-Access_Enumeration。
範例
下列範例會執行 物件集合中個別進程物件的 Kill 方法。
第一個命令會啟動記事本程式的三個實例。
Get-Process 取得記事本程式的所有三個實例,並將其儲存在 $p 變數中。
Notepad; Notepad; Notepad
$p = Get-Process Notepad
$p.Count
3
下一個命令會在 變數中的所有三個進程上執行 $p 方法。 即使進程集合沒有 Kill 方法,此命令仍可運作。
$p.Kill()
Get-Process Notepad
Get-Process 命令會確認 Kill 方法已運作。
Get-Process : Cannot find a process with the name "notepad". Verify the proc
ess name and call the cmdlet again.
At line:1 char:12
+ Get-Process <<<< notepad
+ CategoryInfo : ObjectNotFound: (notepad:String) [Get-Process]
, ProcessCommandException
+ FullyQualifiedErrorId : NoProcessFoundForGivenName,Microsoft.PowerShel
l.Commands.GetProcessCommand
這個範例的功能相當於使用 Foreach-Object Cmdlet 在集合中的每個物件上執行 方法。
$p | ForEach-Object {$_.Kill()}
ForEach 和 Where 方法
從 PowerShell 4.0 開始,支援使用方法語法的集合篩選。 這允許在處理集合 ForEach 和 Where時使用兩個新方法。
您可以在 about_arrays 深入瞭解這些方法
當有多個多載存在時呼叫特定方法
呼叫 .NET 方法時,請考慮下列案例。 如果方法採用 物件,但透過介面的多載採用更特定的類型,PowerShell 會選擇接受物件的方法,除非您明確將它轉換成該介面。
Add-Type -TypeDefinition @'
// Interface
public interface IFoo {
string Bar(int p);
}
// Type that implements the interface
public class Foo : IFoo {
// Direct member method named 'Bar'
public string Bar(object p) { return $"object: {p}"; }
// *Explicit* implementation of IFoo's 'Bar' method().
string IFoo.Bar(int p) {
return $"int: {p}";
}
}
'@
在此範例中,選擇 object 方法的較不特定 多載。
[Foo]::new().Bar(1)
object: 1
在此範例中,我們會將 方法轉換成介面 IFoo,以選取 Bar 方法更特定的多載。
([IFoo] [Foo]::new()).Bar(1)
int: 1
使用採用檔案系統路徑的 .NET 方法
PowerShell 支援每個程序的多個 Runspace。 每個運行空間都有自己的 目前目錄。 這與目前行程的工作目錄不同:[System.Environment]::CurrentDirectory。
.NET 方法會使用進程工作目錄。 PowerShell Cmdlet 會使用 Runspace 位置。 此外,.NET 方法只能使用原生文件系統路徑,而不是PowerShell Path物件。 若要搭配 .NET 方法使用 PowerShell 路徑,您必須先解析文件系統原生路徑的路徑,再將它傳遞至 .NET 方法。